diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5c9446aa6..111061ef8 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -243,7 +243,7 @@ IF(SALOME_BUILD_GUI)
LIST(APPEND _${PROJECT_NAME}_exposed_targets
AdvancedGUI BasicGUI BlocksGUI BooleanGUI BuildGUI DisplayGUI DlgRef EntityGUI GEOMBase
GEOMFiltersSelection GEOM GEOMToolsGUI GenerationGUI GroupGUI Material MeasureGUI GEOMObject
- OperationGUI PrimitiveGUI RepairGUI TransformationGUI ImportExportGUI
+ OperationGUI PrimitiveGUI RepairGUI TransformationGUI ImportExportGUI DependencyTree
)
ENDIF(SALOME_BUILD_GUI)
diff --git a/SalomeGEOMConfig.cmake.in b/SalomeGEOMConfig.cmake.in
index 9e0392028..c72af1a38 100644
--- a/SalomeGEOMConfig.cmake.in
+++ b/SalomeGEOMConfig.cmake.in
@@ -162,6 +162,7 @@ SET(GEOM_GEOMBase GEOMBase)
SET(GEOM_GEOMFiltersSelection GEOMFiltersSelection)
SET(GEOM_GEOM GEOM)
SET(GEOM_GEOMToolsGUI GEOMToolsGUI)
+SET(GEOM_DependencyTree DependencyTree)
SET(GEOM_GenerationGUI GenerationGUI)
SET(GEOM_GroupGUI GroupGUI)
SET(GEOM_Material Material)
diff --git a/adm_local/cmake_files/FindGEOM.cmake b/adm_local/cmake_files/FindGEOM.cmake
index 1f882bc78..69722aa4e 100644
--- a/adm_local/cmake_files/FindGEOM.cmake
+++ b/adm_local/cmake_files/FindGEOM.cmake
@@ -54,6 +54,7 @@ FIND_LIBRARY(GEOM_GEOMBase GEOMBase ${GEOM_ROOT_DIR}/lib/salome)
FIND_LIBRARY(GEOM_GEOMFiltersSelection GEOMFiltersSelection ${GEOM_ROOT_DIR}/lib/salome)
FIND_LIBRARY(GEOM_GEOM GEOM ${GEOM_ROOT_DIR}/lib/salome)
FIND_LIBRARY(GEOM_GEOMToolsGUI GEOMToolsGUI ${GEOM_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(GEOM_DependencyTree DependencyTree ${GEOM_ROOT_DIR}/lib/salome)
FIND_LIBRARY(GEOM_GenerationGUI GenerationGUI ${GEOM_ROOT_DIR}/lib/salome)
FIND_LIBRARY(GEOM_GroupGUI GroupGUI ${GEOM_ROOT_DIR}/lib/salome)
FIND_LIBRARY(GEOM_Material Material ${GEOM_ROOT_DIR}/lib/salome)
diff --git a/doc/salome/gui/GEOM/images/dialog.png b/doc/salome/gui/GEOM/images/dialog.png
old mode 100755
new mode 100644
index c46b6b571..8d7e48a96
Binary files a/doc/salome/gui/GEOM/images/dialog.png and b/doc/salome/gui/GEOM/images/dialog.png differ
diff --git a/doc/salome/gui/GEOM/images/ob_popup_menu.png b/doc/salome/gui/GEOM/images/ob_popup_menu.png
index 1d9f0e321..3aafa729e 100644
Binary files a/doc/salome/gui/GEOM/images/ob_popup_menu.png and b/doc/salome/gui/GEOM/images/ob_popup_menu.png differ
diff --git a/doc/salome/gui/GEOM/images/pref15.png b/doc/salome/gui/GEOM/images/pref15.png
old mode 100755
new mode 100644
index c4b2cac4d..0fec2802a
Binary files a/doc/salome/gui/GEOM/images/pref15.png and b/doc/salome/gui/GEOM/images/pref15.png differ
diff --git a/doc/salome/gui/GEOM/images/pref_dep_tree.png b/doc/salome/gui/GEOM/images/pref_dep_tree.png
new file mode 100644
index 000000000..c02134335
Binary files /dev/null and b/doc/salome/gui/GEOM/images/pref_dep_tree.png differ
diff --git a/doc/salome/gui/GEOM/images/reduce_study_dialog.png b/doc/salome/gui/GEOM/images/reduce_study_dialog.png
new file mode 100644
index 000000000..8f53d7aaf
Binary files /dev/null and b/doc/salome/gui/GEOM/images/reduce_study_dialog.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_bidir_link.png b/doc/salome/gui/GEOM/images/tree_bidir_link.png
new file mode 100644
index 000000000..1697ada69
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_bidir_link.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_button_update.png b/doc/salome/gui/GEOM/images/tree_button_update.png
new file mode 100644
index 000000000..190454b19
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_button_update.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_cycldep_link.png b/doc/salome/gui/GEOM/images/tree_cycldep_link.png
new file mode 100644
index 000000000..ea00164a1
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_cycldep_link.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_default_node.png b/doc/salome/gui/GEOM/images/tree_default_node.png
new file mode 100644
index 000000000..2a369dd3a
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_default_node.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_disp_ascendants.png b/doc/salome/gui/GEOM/images/tree_disp_ascendants.png
new file mode 100644
index 000000000..9f7debc30
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_disp_ascendants.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_disp_descendants.png b/doc/salome/gui/GEOM/images/tree_disp_descendants.png
new file mode 100644
index 000000000..aaed30738
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_disp_descendants.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_example.png b/doc/salome/gui/GEOM/images/tree_example.png
new file mode 100644
index 000000000..e41c1b1f8
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_example.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_hierarchy_type.png b/doc/salome/gui/GEOM/images/tree_hierarchy_type.png
new file mode 100644
index 000000000..4e708fd6a
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_hierarchy_type.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_highlighted_node.png b/doc/salome/gui/GEOM/images/tree_highlighted_node.png
new file mode 100644
index 000000000..6a6743020
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_highlighted_node.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_main_node.png b/doc/salome/gui/GEOM/images/tree_main_node.png
new file mode 100644
index 000000000..fc4009b66
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_main_node.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_move_nodes.png b/doc/salome/gui/GEOM/images/tree_move_nodes.png
new file mode 100644
index 000000000..d358c1f7c
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_move_nodes.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_popup_menu1.png b/doc/salome/gui/GEOM/images/tree_popup_menu1.png
new file mode 100644
index 000000000..bfc90aca7
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_popup_menu1.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_popup_menu2.png b/doc/salome/gui/GEOM/images/tree_popup_menu2.png
new file mode 100644
index 000000000..f33e4f3cc
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_popup_menu2.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_selected_node.png b/doc/salome/gui/GEOM/images/tree_selected_node.png
new file mode 100644
index 000000000..5f44ee521
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_selected_node.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_selfdep_link.png b/doc/salome/gui/GEOM/images/tree_selfdep_link.png
new file mode 100644
index 000000000..21121230b
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_selfdep_link.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_tool_bar.png b/doc/salome/gui/GEOM/images/tree_tool_bar.png
new file mode 100644
index 000000000..eab734638
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_tool_bar.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_unidir_link.png b/doc/salome/gui/GEOM/images/tree_unidir_link.png
new file mode 100644
index 000000000..6afe3f35b
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_unidir_link.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_unpublished_node.png b/doc/salome/gui/GEOM/images/tree_unpublished_node.png
new file mode 100644
index 000000000..95f9b1629
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_unpublished_node.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_view_dump.png b/doc/salome/gui/GEOM/images/tree_view_dump.png
new file mode 100644
index 000000000..b02616f29
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_view_dump.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_view_fitall.png b/doc/salome/gui/GEOM/images/tree_view_fitall.png
new file mode 100644
index 000000000..87e001dd8
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_view_fitall.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_view_fitarea.png b/doc/salome/gui/GEOM/images/tree_view_fitarea.png
new file mode 100644
index 000000000..e83d023a3
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_view_fitarea.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_view_fitselect.png b/doc/salome/gui/GEOM/images/tree_view_fitselect.png
new file mode 100755
index 000000000..e52598d7b
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_view_fitselect.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_view_glpan.png b/doc/salome/gui/GEOM/images/tree_view_glpan.png
new file mode 100644
index 000000000..28ab547ea
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_view_glpan.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_view_pan.png b/doc/salome/gui/GEOM/images/tree_view_pan.png
new file mode 100644
index 000000000..ec56cacc7
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_view_pan.png differ
diff --git a/doc/salome/gui/GEOM/images/tree_view_zoom.png b/doc/salome/gui/GEOM/images/tree_view_zoom.png
new file mode 100644
index 000000000..386c966d1
Binary files /dev/null and b/doc/salome/gui/GEOM/images/tree_view_zoom.png differ
diff --git a/doc/salome/gui/GEOM/input/arranging_study_objects_page.doc b/doc/salome/gui/GEOM/input/arranging_study_objects_page.doc
index 8821198e3..88aea81d4 100644
--- a/doc/salome/gui/GEOM/input/arranging_study_objects_page.doc
+++ b/doc/salome/gui/GEOM/input/arranging_study_objects_page.doc
@@ -20,6 +20,7 @@ parent object is highlighted with bold font.
and then displays only the children of the selected object(s).
+\anchor publish_hidden_objects
Unpublish - hides the selected geometric object from the Object Browser
and erases it from all viewers. To publish unpublished geometric objects select in the
context menu of the Geometry root object Publish... item.
@@ -34,6 +35,12 @@ and then displays only the children of the selected object(s).
unpublished objects are sorted by name in ascending order. It is possible
to change the order (ascending / descending) by clicking the corresponding title bar of the objects list.
+
+
\ref dependency_tree_page "Show dependency tree" - shows dependency tree of selected objects
+in new 2D View Window.
+
+
\ref reduce_study_page "Reduce study" - allows to reduce study
+by automatic removing objects according to user's options.
Folders
diff --git a/doc/salome/gui/GEOM/input/dependency_tree.doc b/doc/salome/gui/GEOM/input/dependency_tree.doc
new file mode 100644
index 000000000..e44dba400
--- /dev/null
+++ b/doc/salome/gui/GEOM/input/dependency_tree.doc
@@ -0,0 +1,211 @@
+/*!
+
+\page dependency_tree_page Dependency Tree
+
+
+
+In order to better understand the relations between the %GEOM
+objects in a study the user has a possibility to display the
+ascendants and descendant of the object(s) in a family tree.
+
+User can build the dependency tree by selecting desirable object
+in Object Browser or OCC Viewer and calling "Show dependency tree"
+popup item. It will open a new or clear the existing "Dependency
+Tree" view window (only one view is supported) and display a
+dependency tree for the selected object or objects (multiple
+selection is supported). Also user can rebuild the tree if to select
+some object(s) right in the "Dependency Tree" view and call
+"Rebuild the tree" popup menu item.
+
+\image html tree_example.png
+
+User can change all necessary parameters of Dependency Tree Viewer
+in \ref pref_dependency_tree "Preferences".
+
+
+\anchor dependency_tree_nodes_anchor
Nodes
+
+Tree nodes in the Dependency Viewer are named according to the study
+names of the corresponding objects.
+
+Non-published objects are shown in the tree as "unpublished" and
+colored in special color.
+
+All nodes have the fixed size, so the long names are cut and shown
+with ellipsis; full name of the object can be seen in the tooltip
+if to keep the cursor over the node.
+
+"Dependency Tree" view supports the following states of nodes:
+
+
Main node - node of main object(s), which were selected in Object
+Browser, OCC Viewer or Dependency Tree Viewer in order to build the
+dependency tree;
+\image html tree_main_node.png
+
+
Default node - node of published in study object, which participate in building of
+dependency tree as ascendant or descendant;
+\image html tree_default_node.png
+
+
Unpublished node - the same as "Default node", but
+corresponding object was not published in study;
+\image html tree_unpublished_node.png
+
+
Highlighted node - the state of node when mouse
+cursor is over it;
+\image html tree_highlighted_node.png
+
+
Selected node - the state of node when user
+clicks the left mouse button on node.
+\image html tree_selected_node.png
+
+
+\anchor dependency_tree_links_anchor
Links
+
+Dependency Tree Viewer shows oriented links between nodes to
+represent dependency direction. Viewer supports the following states
+of links:
+
+
Unidirectional link - shows that A object depends on
+B object;
+\image html tree_unidir_link.png
+
+
Bidirectional link - shows that A object depends on
+B object and, at the same time, B object depends on
+A object;
+\image html tree_bidir_link.png
+
+
Self-dependency link - shows that object depends on
+itself;
+\image html tree_selfdep_link.png
+
+
Cyclic dependency links - shows cyclic dependency of
+some nodes.
+\image html tree_cycldep_link.png
+
+
+\anchor dependency_tree_operations_anchor
Operations
+
+The dependency tree of a chosen %GEOM object is displayed in
+the dedicated 2D view window.
+\n The functionalities of 2D viewer are available via its Viewer
+Toolbar.
+
+Buttons marked with small downward triangles have extended
+functionality which can be accessed by locking on them with left
+mouse button.
+
+\image tree_tool_bar
+
+Dump View - exports an object from the viewer in bmp, png or
+jpeg image format.
+\image html tree_view_dump.png
+
+Fit all - scales the presentation so that it could fit within
+the Viewer boundaries.
+\image html tree_view_fitall.png
+
+Fit area - resizes the view to place in the visible area only
+the contents of a frame drawn with pressed left mouse button.
+\image html tree_view_fitarea.png
+
+Fit selection - resizes the view to fit in the visible area
+only currently selected objects.
+\image html tree_view_fitselect.png
+
+Zoom - allows to zoom in and out.
+\image html tree_view_zoom.png
+
+Panning - if the represented objects are greater that the
+visible area and you don't wish to use Fit all functionality,
+click on this button and you'll be able to drag the scene to see its
+remote parts.
+\image html tree_view_pan.png
+
+Global panning - allows to select a point to be the center of
+the presentation showing all displayed objects in the visible ares.
+\image html tree_view_glpan.png
+
+Hierarchy depth - allows to change the number of hierarchy
+levels to be shown in the dependency tree.
+\image html tree_hierarchy_type.png
+
+
Level 1 corresponds to the parents and children of the selected
+object(s);
+
Level 2 is Level 1 plus the grand-parents and grand-children
+of the selected object(s);
+
etc...
+
+
+Display ascendants - allows user to control the displaying
+of ascendants.
+\image html tree_disp_ascendants.png
+
+Display descendants - allows user to control the displaying
+of descendants.
+\image html tree_disp_descendants.png
+
+Move nodes - enables/disables of moving the nodes.
+\image html tree_move_nodes.png
+
+Update - allows user to update a dependency tree model and the view.
+\image html tree_button_update.png
+
+
+\anchor dependency_tree_navigation_anchor
Navigation
+
+Dependency Tree 2D Viewer supports the following navigation mode:
+
+
+
rectangle selection in this mode is performed by the left mouse
+button
;
+
multiple selection is available when \b Shift button
+is pressed.
+
+
+Also, holding \b Ctrl key with pressed mouse buttons performs
+the following view transformations:
+
+
Ctrl + left mouse button - zooming;
+
Ctrl + middle mouse button - panning;
+
+
+
+\anchor dependency_tree_popup_menu_anchor
Popup Menu
+
+After the object has appeared in the Dependency Tree 2D Viewer,
+user can select it with left mouse click to change its presentation
+parameters and get access to other useful options by right-clicking on
+the selected object.
+
+\image html tree_popup_menu1.png
+
+
+
\b Show - allows to show selected object(s) in OCC 3D Viewer;
+
Show Only - allows to show only selected object(s)
+in OCC 3D Viewer;
+
Rebuild the tree - allows to rebuild the dependency tree
+for selected object(s);
+
\ref reduce_study_page "Reduce study" - allows to reduce study.
+
+
+Some functionalities are available through right-clicking on
+the viewer background:
+
+\image html tree_popup_menu2.png
+
+Dependency Tree 2D Viewer background can be customized using the
+"Change background" popup menu command that opens standard
+"Select Color" dialog box:
+
+\image html selectcolor.png
+
+*/
diff --git a/doc/salome/gui/GEOM/input/geometry_preferences.doc b/doc/salome/gui/GEOM/input/geometry_preferences.doc
index 6ad3270cb..6d322fcb6 100644
--- a/doc/salome/gui/GEOM/input/geometry_preferences.doc
+++ b/doc/salome/gui/GEOM/input/geometry_preferences.doc
@@ -2,6 +2,8 @@
\page geometry_preferences_page Geometry preferences
+\anchor pref_settings
Settings
+
In the \b Geometry module you can set preferences for visualisation of
geometrical figures, which can be used in later sessions with this module.
There is also a special group of preferences controlling input
@@ -128,5 +130,35 @@ system immediately after the module activation.
+\anchor pref_dependency_tree
Dependency Tree
+
+Also user can set preferences for visualisation of Dependency Tree in 2D Viewer.
+
+\image html pref_dep_tree.png
+
+
+
General
+
+
Hierarchy type - allows to choose default displaying mode of dependency tree.
+
Possibility to move nodes - enable/disable the possibility of moving nodes by default.
+
+
+
+
+
Color
+
+
Background color - allows to select default background color.
+
Default node color - allows to select default node color.
+
Main node color - allows to select default main node color.
+
Unpublished node color - allows to select default node color
+for unpublished objects.
+
Selected node color - allows to select default selected node color.
+
Default arrow color - allows to select default arrow color.
+
Highlighted arrow color - allows to select default highlighted
+arrow color.
+
Selected arrow color - allows to select default selected
+arrow color.
+
+
*/
diff --git a/doc/salome/gui/GEOM/input/reduce_study.doc b/doc/salome/gui/GEOM/input/reduce_study.doc
new file mode 100644
index 000000000..8a3c7e766
--- /dev/null
+++ b/doc/salome/gui/GEOM/input/reduce_study.doc
@@ -0,0 +1,58 @@
+/*!
+
+\page reduce_study_page Reduce Study
+
+The user sometimes needs to keep in the study only some objects that
+present the final result(s) of the design operations and to delete all
+other objects which do not contribute to these results.
+
+The feature is especially useful when the user designs the whole model
+through the GUI and wants to generate simplified "clean" Python dump only
+at the end of the model construction with no "useless" objects in the
+%GEOM module.
+
+User can open dialog box by selecting desirable object(s) in Object
+Browser or OCC Viewer and calling "Reduce study" popup item.
+
+\image html reduce_study_dialog.png
+
+
+
+
Objects to be kept - objects that will be kept in the study after
+applying operation of reduce study. The list of objects being selected by
+the user are highlighted in bold font.
+
+
Objects to be removed - objects that will be deleted.
+
+\note Mentioned views provide possibility to show/hide object(s) in
+current Viewer using "eye" icon near each item of tree. Also user can
+show/hide ALL objects in tree by clicking "eye" icon in the head of tree view.
+
+
Intermediate objects group box allows to choose an action
+that will be performed with the objects that took part in the operations
+chain to produce the selected object(s):
+
+
Keep - object(s) will be kept in the study;
+
Unpublish - object(s) will be unpublished (hidden) from the study;
+
Remove - object(s) will be removed from the study. \note Since use of
+this option can lead to the broken Dump Python script, the warning message
+will be shown at the operation commiting to confirm/reject removing
+intermediate objects.
+
+
+
+
Sub-objects group box allows to choose the same operations for
+sub-objects of selected item(s): keep, unpublish or remove.
+
+
Remove empty folders - if this option is checked, then all folders,
+which will become empty after removing unused objects from the study,
+will be also removed; otherwise, empty folders will be kept.
+
+
Soft removal - if this option is checked, operation will just
+unpublish the redundant objects from the study instead of their hard delete.
+\n Soft removal would keep all the data in the study to give the user a
+chance to revert this operation using \ref publish_hidden_objects
+"Publish Objects" dialog box.
+
+
+*/
diff --git a/doc/salome/gui/GEOM/input/viewing_geom_obj.doc b/doc/salome/gui/GEOM/input/viewing_geom_obj.doc
index 38246c570..29a43cfbf 100644
--- a/doc/salome/gui/GEOM/input/viewing_geom_obj.doc
+++ b/doc/salome/gui/GEOM/input/viewing_geom_obj.doc
@@ -21,6 +21,7 @@ other useful options by right-clicking on the selected object.
object.
Delete - irreversibly deletes the selected object from the
viewer and from the Object Browser.
+
Create Group - allows to create group.
\subpage display_mode_page "Display Mode" - allows to select between
Wireframe and Shading presentation.
\subpage bring_to_front_page "Bring To Front" - allows to bring to
@@ -63,6 +64,10 @@ geometrical object. TUI Command: sg.DisplayOnly(ID)
Show all dimensions - shows all of the persistent dimensions created for the selected geometrical object.
Hide all dimensions - hides all of the persistent dimensions created for the selected geometrical object.
+
\subpage dependency_tree_page "Show dependency tree" - shows dependency tree of selected objects
+in new 2D View Window.
+
\subpage reduce_study_page "Reduce study" - allows to reduce study
+by automatic removing objects according to user's options.
Dump view - exports an object from the viewer in bmp, png,
jpg or jpeg image format.
Change background - allows to redefine the background
diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl
index ecf0308db..bbaafca6b 100644
--- a/idl/GEOM_Gen.idl
+++ b/idl/GEOM_Gen.idl
@@ -5089,6 +5089,35 @@ module GEOM
void Move( in object_list what,
in SALOMEDS::SObject where,
in long row );
+
+ /*!
+ * \brief Collects dependencies of the given objects from other ones
+ * \param theStudy The study in which the object is published
+ * \param theListOfEntries List of GEOM object entries in OCAF tree (not in study)
+ * \return Struct of dependent entries and its links as a byte array
+ * \note This method is supposed to be used by GUI only.
+ */
+ SALOMEDS::TMPFile GetDependencyTree(in SALOMEDS::Study theStudy,
+ in string_array theListOfEntries);
+
+ /*!
+ * \brief Fills 3 lists that is used to reduce study of redundant objects:
+ * - dependencies of the given objects from other ones;
+ * - children of the given objects;
+ * - all other objects in study.
+ * \param theStudy The study in which the object was published
+ * \param theSelectedEntries List of GEOM object entries in OCAF tree
+ * \param theParentEntries List of GEOM object entries on which the given objects depend
+ * \param theSubEntries Children entries list of the given objects
+ * \param theOtherEntries List of GEOM object entries which are in the study, but not in parents and children lists
+ * \note This method is supposed to be used by GUI only.
+ */
+ void GetEntriesToReduceStudy(in SALOMEDS::Study theStudy,
+ inout string_array theSelectedEntries,
+ inout string_array theParentEntries,
+ inout string_array theSubEntries,
+ inout string_array theOtherEntries);
+
};
};
diff --git a/resources/SalomeApp.xml.in b/resources/SalomeApp.xml.in
index 0cdf1cf72..24a0f148d 100644
--- a/resources/SalomeApp.xml.in
+++ b/resources/SalomeApp.xml.in
@@ -38,6 +38,7 @@
+
@@ -67,6 +68,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a40066e58..641853c22 100755
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -51,7 +51,7 @@ ENDIF()
IF(SALOME_BUILD_GUI)
SET(SUBDIRS_GUI
OBJECT DlgRef GEOMFiltersSelection Material GEOMGUI
- GEOMBase GEOMToolsGUI DisplayGUI BasicGUI PrimitiveGUI GenerationGUI
+ GEOMBase DependencyTree GEOMToolsGUI DisplayGUI BasicGUI PrimitiveGUI GenerationGUI
EntityGUI BuildGUI BooleanGUI TransformationGUI OperationGUI
RepairGUI MeasureGUI GroupGUI BlocksGUI AdvancedGUI ImportExportGUI
GEOM_SWIG_WITHIHM
diff --git a/src/DependencyTree/CMakeLists.txt b/src/DependencyTree/CMakeLists.txt
new file mode 100644
index 000000000..91580628d
--- /dev/null
+++ b/src/DependencyTree/CMakeLists.txt
@@ -0,0 +1,99 @@
+# Copyright (C) 2012-2014 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+INCLUDE(UseQt4Ext)
+
+# --- options ---
+
+# additional include directories
+INCLUDE_DIRECTORIES(
+ ${QT_INCLUDES}
+ ${GUI_INCLUDE_DIRS}
+ ${PROJECT_SOURCE_DIR}/src/GEOMGUI
+ ${PROJECT_SOURCE_DIR}/src/GEOMBase
+ ${PROJECT_SOURCE_DIR}/src/GEOM
+ ${PROJECT_SOURCE_DIR}/src/OBJECT
+ ${PROJECT_SOURCE_DIR}/src/GEOMUtils
+ ${PROJECT_SOURCE_DIR}/src/GEOMClient
+ ${PROJECT_SOURCE_DIR}/src/GEOMToolsGUI
+ ${PROJECT_BINARY_DIR}/idl
+ )
+
+# additional preprocessor / compiler flags
+ADD_DEFINITIONS(
+ ${QT_DEFINITIONS}
+ ${GUI_DEFINITIONS}
+ ${CAS_DEFINITIONS}
+ )
+
+# libraries to link to
+SET(_link_LIBRARIES
+ ${QT_LIBRARIES}
+ ${GUI_SalomeApp}
+ ${GUI_GraphicsView}
+ GEOM
+ GEOMBase
+ )
+
+# --- headers ---
+
+SET(DependencyTree_HEADERS
+ DependencyTree_Arrow.h
+ DependencyTree_Object.h
+ DependencyTree_Selector.h
+ )
+
+# header files / to be processed by moc
+SET(_moc_HEADERS
+ DependencyTree_View.h
+ DependencyTree_ViewModel.h
+ )
+
+# --- sources ---
+
+# sources / moc wrappings
+QT4_WRAP_CPP(_moc_SOURCES ${_moc_HEADERS})
+
+SET(DependencyTree_SOURCES
+ DependencyTree_Arrow.cxx
+ DependencyTree_Object.cxx
+ DependencyTree_Selector.cxx
+ DependencyTree_View.cxx
+ DependencyTree_ViewModel.cxx
+ ${_moc_SOURCES}
+ )
+
+# --- resources ---
+
+# resource files / to be processed by lrelease
+SET(_res_files
+ resources/DependencyTree_msg_en.ts
+ resources/DependencyTree_msg_fr.ts
+ resources/DependencyTree_msg_ja.ts
+ )
+
+# --- rules ---
+
+ADD_LIBRARY(DependencyTree ${DependencyTree_SOURCES})
+TARGET_LINK_LIBRARIES(DependencyTree ${_link_LIBRARIES})
+INSTALL(TARGETS DependencyTree EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS})
+
+INSTALL(FILES ${DependencyTree_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS})
+
+QT4_INSTALL_TS_RESOURCES("${_res_files}" "${SALOME_GEOM_INSTALL_RES_DATA}")
diff --git a/src/DependencyTree/DependencyTree_Arrow.cxx b/src/DependencyTree/DependencyTree_Arrow.cxx
new file mode 100644
index 000000000..81784d1a0
--- /dev/null
+++ b/src/DependencyTree/DependencyTree_Arrow.cxx
@@ -0,0 +1,260 @@
+// Copyright (C) 2014 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// internal includes
+#include "DependencyTree_Arrow.h"
+#include "DependencyTree_Object.h"
+
+// GUI includes
+#include
+#include
+
+// Qt includes
+#include
+
+#include
+
+const qreal arrowSize = 20;
+
+DependencyTree_Arrow::DependencyTree_Arrow( DependencyTree_Object* theStartItem,
+ DependencyTree_Object* theEndItem,
+ QGraphicsItem* parent, QGraphicsScene* scene )
+:QGraphicsLineItem( parent, scene ),
+myIsBiLink( false ),
+myStartItem( theStartItem ),
+myEndItem( theEndItem )
+{
+ SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+
+ myColor = resMgr->colorValue( "Geometry", "dependency_tree_arrow_color", QColor( 0, 0, 130 ) );
+ myHighlightColor = resMgr->colorValue( "Geometry", "dependency_tree_highlight_arrow_color", QColor( 0, 0, 255 ) );
+ mySelectColor = resMgr->colorValue( "Geometry", "dependency_tree_select_arrow_color", QColor( 255, 0, 0 ) );
+
+ myStartItem = theStartItem;
+ myEndItem = theEndItem;
+
+ myLine = QLineF( myStartItem->pos(), myEndItem->pos() );
+ myArrowHead = createArrowHead( myStartItem->pos(), myEndItem->pos() );
+ myReverseArrowHead = createArrowHead( myEndItem->pos(), myStartItem->pos() );
+
+ mySelfDependencyArrow = QRectF();
+
+ setPen( QPen( myColor, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
+ setColor( myColor );
+
+ setFlag( QGraphicsItem::ItemIsSelectable, true );
+ setZValue( -1000.0 );
+}
+
+DependencyTree_Arrow::~DependencyTree_Arrow()
+{
+}
+
+//=================================================================================
+// function : boundingRect()
+// purpose : return the outer bounds of the item as a rectangle.
+// QGraphicsView uses this to determine whether the item requires redrawing
+//=================================================================================
+QRectF DependencyTree_Arrow::boundingRect() const
+{
+ qreal extra;
+ QRectF boundingRect;
+ if( myStartItem == myEndItem ) {
+ extra = arrowSize / 2.0 + 2.0;
+ boundingRect = mySelfDependencyArrow;
+ }
+ else {
+ extra = ( pen().width() + 20 ) / 2.0;
+ boundingRect = QRectF( myLine.p1(), QSizeF( myLine.p2().x() - myLine.p1().x(),
+ myLine.p2().y() - myLine.p1().y() ) );
+ }
+ return boundingRect.normalized().adjusted( -extra, -extra, extra, extra );
+}
+
+//=================================================================================
+// function : shape()
+// purpose : return the shape of this item to define an area of preselection
+//=================================================================================
+QPainterPath DependencyTree_Arrow::shape() const
+{
+ QPainterPath path;
+
+ if( myStartItem == myEndItem ) {
+ qreal extra = 5;
+ QPolygonF aPolygonBigger( mySelfDependencyArrow.normalized()
+ .adjusted( -extra, -extra, extra, extra ) );
+ QPolygonF aPolygonSmaller( mySelfDependencyArrow.normalized()
+ .adjusted( extra, extra, -extra, -extra ) );
+ path.addPolygon( aPolygonBigger.subtracted( aPolygonSmaller ) );
+ path.addPolygon(myArrowHead);
+ }
+ else {
+ QPolygonF aShapePolygon;
+ QPolygon anArrowHead = myArrowHead.toPolygon();
+ QPolygon anReverseArrowHead = myReverseArrowHead.toPolygon();
+ aShapePolygon << anArrowHead.point(1) << anArrowHead.point(0) << anArrowHead.point(2) <<
+ anReverseArrowHead.point(1) << anReverseArrowHead.point(0) << anReverseArrowHead.point(2);
+ path.addPolygon( aShapePolygon );
+ }
+ return path;
+ }
+
+//=================================================================================
+// function : setColor()
+// purpose : set default color for arrow
+//=================================================================================
+void DependencyTree_Arrow::setColor( const QColor& theColor )
+{
+ myColor = theColor;
+}
+
+//=================================================================================
+// function : setHighlightColor()
+// purpose : set color for highlighted arrow
+//=================================================================================
+void DependencyTree_Arrow::setHighlightColor( const QColor& theColor )
+{
+ myHighlightColor = theColor;
+}
+
+//=================================================================================
+// function : setSelectColor()
+// purpose : set color for selected arrow
+//=================================================================================
+void DependencyTree_Arrow::setSelectColor( const QColor& theColor )
+{
+ mySelectColor = theColor;
+}
+
+//=================================================================================
+// function : getStartItem()
+// purpose : get start item of arrow
+//=================================================================================
+DependencyTree_Object* DependencyTree_Arrow::getStartItem() const
+{
+ return myStartItem;
+}
+
+//=================================================================================
+// function : getEndItem()
+// purpose : get end item of arrow
+//=================================================================================
+DependencyTree_Object* DependencyTree_Arrow::getEndItem() const
+{
+ return myEndItem;
+}
+
+//=================================================================================
+// function : setIsBiLink()
+// purpose : set true if current arrow is bi-directional link, else set false
+//=================================================================================
+void DependencyTree_Arrow::setIsBiLink( bool theIsBiLink )
+{
+ myIsBiLink = theIsBiLink;
+}
+
+//=================================================================================
+// function : paint()
+// purpose : paint the contents of an item in local coordinates (called by QGraphicsView)
+//=================================================================================
+void DependencyTree_Arrow::paint( QPainter* painter, const QStyleOptionGraphicsItem*, QWidget* )
+{
+ if( isSelected() ) {
+ painter->setBrush( mySelectColor );
+ painter->setPen( QPen( mySelectColor, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
+ }
+ else if( isUnderMouse() ) {
+ painter->setBrush( myHighlightColor );
+ painter->setPen( QPen( myHighlightColor, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
+ }
+ else {
+ painter->setBrush( myColor );
+ painter->setPen( QPen( myColor, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
+ }
+
+ if( myStartItem == myEndItem ) {
+ int lineSize = 60;
+ QPointF p1( myStartItem->pos().x() - myStartItem->boundingRect().width()/2,
+ myStartItem->pos().y() );
+ QPointF p2( p1.x() - lineSize + myStartItem->boundingRect().height()/2, p1.y() );
+ QPointF p3( p2.x(), p2.y() - lineSize );
+ QPointF p4( p3.x() + lineSize, p3.y() );
+ QPointF p5( p4.x(), p4.y() + lineSize - myStartItem->boundingRect().height()/2 );
+ mySelfDependencyArrow = QRectF( p3.x(), p3.y(), lineSize, lineSize );
+ myArrowHead = createArrowHead( p4, p5, false );
+ QVector pointVector;
+ pointVector << p1 << p2 << p2 << p3 << p3 << p4 << p4 << p5;
+
+ painter->drawLines( pointVector);
+ painter->drawPolygon(myArrowHead);
+ }
+ else {
+ if (myStartItem->collidesWithItem(myEndItem))
+ return;
+
+ myArrowHead = createArrowHead( myStartItem->pos(), myEndItem->pos() );
+ myReverseArrowHead = createArrowHead( myEndItem->pos(), myStartItem->pos() );
+
+ painter->drawLine( myLine );
+ painter->drawPolygon( myArrowHead );
+ if( myIsBiLink )
+ painter->drawPolygon( myReverseArrowHead );
+ }
+}
+
+//=================================================================================
+// function : createArrowHead()
+// purpose : create a head of arrow from start point to end point
+//=================================================================================
+QPolygonF DependencyTree_Arrow::createArrowHead( QPointF theStartPoint, QPointF theEndPoint,
+ bool theIsDynamic )
+{
+ if( theIsDynamic ) {
+ QLineF centerLine( theStartPoint, theEndPoint );
+ QPolygonF endPolygon = QPolygonF( myEndItem->boundingRect() );
+ QPointF p1 = endPolygon.first() + theEndPoint;
+ QPointF p2;
+ QPointF intersectPoint;
+ QLineF polyLine;
+ for( int i = 1; i < endPolygon.count(); ++i ) {
+ p2 = endPolygon.at(i) + theEndPoint;
+ polyLine = QLineF( p1, p2 );
+ QLineF::IntersectType intersectType = polyLine.intersect( centerLine, &intersectPoint );
+ if( intersectType == QLineF::BoundedIntersection )
+ break;
+ p1 = p2;
+ }
+ myLine = QLineF( intersectPoint, theStartPoint );
+ }
+ else
+ myLine = QLineF( theEndPoint, theStartPoint );
+
+ double angle = acos(myLine.dx() / myLine.length());
+ if( myLine.dy() >= 0 )
+ angle = ( M_PI * 2 ) - angle;
+
+ QPointF arrowP1 = myLine.p1() + QPointF( sin( angle + M_PI / 3 ) * arrowSize,
+ cos( angle + M_PI / 3 ) * arrowSize );
+ QPointF arrowP2 = myLine.p1() + QPointF( sin( angle + M_PI - M_PI / 3 ) * arrowSize,
+ cos( angle + M_PI - M_PI / 3 ) * arrowSize );
+
+ QPolygonF anArrowHead;
+ anArrowHead << myLine.p1() << arrowP1 << arrowP2;
+ return anArrowHead;
+}
diff --git a/src/DependencyTree/DependencyTree_Arrow.h b/src/DependencyTree/DependencyTree_Arrow.h
new file mode 100644
index 000000000..087755651
--- /dev/null
+++ b/src/DependencyTree/DependencyTree_Arrow.h
@@ -0,0 +1,74 @@
+// Copyright (C) 2014 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef DEPENDENCYTREE_ARROW_H
+#define DEPENDENCYTREE_ARROW_H
+
+#include
+
+class DependencyTree_Object;
+
+class DependencyTree_Arrow : public QGraphicsLineItem
+{
+
+public:
+
+ DependencyTree_Arrow( DependencyTree_Object* startItem, DependencyTree_Object* endItem,
+ QGraphicsItem* parent = 0, QGraphicsScene* scene = 0 );
+ ~DependencyTree_Arrow();
+
+ virtual QRectF boundingRect() const;
+ virtual QPainterPath shape() const;
+
+ void setColor(const QColor& );
+ void setHighlightColor(const QColor& );
+ void setSelectColor(const QColor& );
+
+ DependencyTree_Object* getStartItem() const;
+ DependencyTree_Object* getEndItem() const;
+
+ void setIsBiLink( bool );
+
+protected:
+
+ void paint( QPainter*, const QStyleOptionGraphicsItem*, QWidget* = 0 );
+
+private:
+
+ QPolygonF createArrowHead( QPointF , QPointF, bool = true );
+
+ DependencyTree_Object* myStartItem;
+ DependencyTree_Object* myEndItem;
+
+ QColor myColor;
+ QColor mySelectColor;
+ QColor myHighlightColor;
+
+ QPolygonF myArrowHead;
+ QPolygonF myReverseArrowHead;
+
+ bool myIsBiLink;
+
+ QRectF mySelfDependencyArrow;
+
+ QLineF myLine;
+
+};
+
+#endif
diff --git a/src/DependencyTree/DependencyTree_Object.cxx b/src/DependencyTree/DependencyTree_Object.cxx
new file mode 100644
index 000000000..a25f4caa3
--- /dev/null
+++ b/src/DependencyTree/DependencyTree_Object.cxx
@@ -0,0 +1,270 @@
+// Copyright (C) 2014 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// internal includes
+#include "DependencyTree_Object.h"
+
+// GEOM includes
+#include
+
+// GUI includes
+#include
+#include
+#include
+#include
+
+// Qt includes
+#include
+
+const int itemH = 20;
+const int itemW = 90;
+
+DependencyTree_Object::DependencyTree_Object( const std::string& theEntry, QGraphicsItem* theParent )
+:GraphicsView_Object( theParent ),
+myIsMainObject( false )
+{
+ SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+
+ myColor = resMgr->colorValue( "Geometry", "dependency_tree_node_color", QColor( 62, 180, 238 ) );
+ mySelectColor = resMgr->colorValue( "Geometry", "dependency_tree_select_node_color", QColor( 237, 243, 58 ) );
+ myMainObjectColor = resMgr->colorValue( "Geometry", "dependency_tree_main_node_color", QColor( 238, 90, 125 ) );
+ myUnpublishObjectColor = resMgr->colorValue( "Geometry", "dependency_tree_unpublish_node_color", QColor( 255, 255, 255 ) );
+
+ myPolygonItem = new QGraphicsPolygonItem();
+ QPolygonF myPolygon;
+ myPolygon << QPointF( -itemW, -itemH ) << QPointF( itemW, -itemH ) << QPointF( itemW, itemH )
+ << QPointF( -itemW, itemH ) << QPointF( -itemW, -itemH );
+
+ myPolygonItem->setPolygon( myPolygon );
+
+ myTextItem = new QGraphicsSimpleTextItem();
+ QFont textFont;
+ textFont.setPointSize( itemH );
+ myTextItem->setFont( textFont );
+
+ myEntry = theEntry;
+
+ SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
+ if ( !app ) return;
+ SalomeApp_Study* study = dynamic_cast(app->activeStudy());
+ int studyId = GeometryGUI::ClientStudyToStudy( study->studyDS())->StudyId();
+ myGeomObject = GeometryGUI::GetGeomGen()->GetObject( studyId, myEntry.c_str() );
+
+ updateName();
+
+ addToGroup( myPolygonItem );
+ addToGroup( myTextItem );
+}
+
+DependencyTree_Object::~DependencyTree_Object()
+{
+}
+
+//=================================================================================
+// function : highlight()
+// purpose : highlight current item
+//=================================================================================
+bool DependencyTree_Object::highlight( double theX, double theY )
+{
+ if( !isHighlighted() ) {
+ QColor color = myPolygonItem->brush().color();
+ int saturation = ( color.saturation() - 100 ) > 10 ? color.saturation() - 100 : 10;
+ color.setHsv( color.hsvHue(), saturation, color.value() );
+
+ myPolygonItem->setBrush( color );
+ myPolygonItem->setPen( getPen( color ) );
+
+ myPolygonItem->setToolTip( getName() );
+ }
+ return GraphicsView_Object::highlight( theX, theY );
+}
+
+//=================================================================================
+// function : unhighlight()
+// purpose : set properties for unhighlighted item
+//=================================================================================
+void DependencyTree_Object::unhighlight()
+{
+ if( isSelected() )
+ myPolygonItem->setBrush( mySelectColor );
+ else if( myIsMainObject )
+ myPolygonItem->setBrush( myMainObjectColor );
+ else
+ myPolygonItem->setBrush( myColor );
+
+ myPolygonItem->setPen( getPen( myPolygonItem->brush().color() ) );
+
+ GraphicsView_Object::unhighlight();
+}
+
+//=================================================================================
+// function : select()
+// purpose : select current item
+//=================================================================================
+bool DependencyTree_Object::select( double theX, double theY, const QRectF& theRect )
+{
+ myPolygonItem->setBrush( mySelectColor );
+ myPolygonItem->setPen( getPen( mySelectColor ) );
+
+ return GraphicsView_Object::select( theX, theY, theRect );
+}
+
+//=================================================================================
+// function : unselect()
+// purpose : set properties for unselected item
+//=================================================================================
+void DependencyTree_Object::unselect()
+{
+ if( myIsMainObject )
+ myPolygonItem->setBrush( myMainObjectColor );
+ else
+ myPolygonItem->setBrush( myColor );
+
+ myPolygonItem->setPen( getPen( myPolygonItem->brush().color() ) );
+
+ GraphicsView_Object::unselect();
+}
+
+//=================================================================================
+// function : getEntry()
+// purpose : get entry of current item
+//=================================================================================
+std::string DependencyTree_Object::getEntry() const
+{
+ return myEntry;
+}
+
+//=================================================================================
+// function : getGeomObject()
+// purpose : get geometry object of current item
+//=================================================================================
+GEOM::GEOM_BaseObject_var DependencyTree_Object::getGeomObject() const
+{
+ return myGeomObject;
+}
+
+//=================================================================================
+// function : updateName()
+// purpose : update name of current item using its entry
+//=================================================================================
+void DependencyTree_Object::updateName()
+{
+
+ QString name = myGeomObject->GetName();
+ QString studyEntry = myGeomObject->GetStudyEntry();
+
+ if( studyEntry.isEmpty() ) {
+ if( name.isEmpty() )
+ name = "unpublished";
+ myColor = myUnpublishObjectColor;
+ }
+
+ myPolygonItem->setBrush( myColor );
+ myPolygonItem->setPen( getPen( myColor ) );
+
+ setName( name );
+
+ myTextItem->setText( name );
+ double textWidth = myTextItem->sceneBoundingRect().width();
+ double textHeight = myTextItem->sceneBoundingRect().height();
+
+ double polygonWidth = myPolygonItem->sceneBoundingRect().width();
+ double polygonHeight = myPolygonItem->sceneBoundingRect().height();
+
+ if( ( textWidth - 4 ) > polygonWidth ) {
+ int numberSymbol = int( polygonWidth * name.length() / textWidth );
+ QString newName = name.left( numberSymbol - 3 ) + "...";
+ myTextItem->setText( newName );
+ textWidth = myTextItem->sceneBoundingRect().width();
+ }
+ myTextItem->setPos( ( polygonWidth - textWidth ) / 2 - itemW,
+ ( polygonHeight - textHeight ) / 2 - itemH );
+}
+
+//=================================================================================
+// function : setColor()
+// purpose : set default color of current item
+//=================================================================================
+void DependencyTree_Object::setColor( const QColor& theColor )
+{
+ QString studyEntry = myGeomObject->GetStudyEntry();
+ if( studyEntry.isEmpty() )
+ myColor = myUnpublishObjectColor;
+ else
+ myColor = theColor;
+
+}
+
+//=================================================================================
+// function : setSelectColor()
+// purpose : set color of selected item
+//=================================================================================
+void DependencyTree_Object::setSelectColor( const QColor& theColor )
+{
+ mySelectColor = theColor;
+}
+
+//=================================================================================
+// function : setMainObjectColor()
+// purpose : set color if current item is main object of dependency tree
+//=================================================================================
+void DependencyTree_Object::setMainObjectColor( const QColor& theColor )
+{
+ myMainObjectColor = theColor;
+}
+
+//=================================================================================
+// function : setUnpublishObjectColor()
+// purpose : set color if current item is unpublished object
+//=================================================================================
+void DependencyTree_Object::setUnpublishObjectColor( const QColor& theColor )
+{
+ myUnpublishObjectColor = theColor;
+ QString studyEntry = myGeomObject->GetStudyEntry();
+ if( studyEntry.isEmpty() )
+ myColor = myUnpublishObjectColor;
+}
+
+//=================================================================================
+// function : setIsMainObject()
+// purpose : set true if current item is main object of dependency tree
+//=================================================================================
+void DependencyTree_Object::setIsMainObject( bool theIsMainObject )
+{
+ myIsMainObject = theIsMainObject;
+
+ if( myIsMainObject )
+ myPolygonItem->setBrush( myMainObjectColor );
+ else
+ myPolygonItem->setBrush( myColor );
+
+ myPolygonItem->setPen( getPen( myPolygonItem->brush().color() ) );
+}
+
+//=================================================================================
+// function : getPen()
+// purpose : get pen which is dependent of current color
+//=================================================================================
+QPen DependencyTree_Object::getPen( const QColor& theColor )
+{
+ int value = ( theColor.value() - 100 ) > 10 ? theColor.value() - 100 : 10;
+ QColor penColor;
+ penColor.setHsv( theColor.hsvHue(), theColor.saturation(), value );
+ return QPen( QBrush( penColor ), 4 );
+}
diff --git a/src/DependencyTree/DependencyTree_Object.h b/src/DependencyTree/DependencyTree_Object.h
new file mode 100644
index 000000000..fae775edc
--- /dev/null
+++ b/src/DependencyTree/DependencyTree_Object.h
@@ -0,0 +1,79 @@
+// Copyright (C) 2014 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef DEPENDENCYTREE_OBJECT_H
+#define DEPENDENCYTREE_OBJECT_H
+
+#include
+
+// GEOM includes
+#include
+#include CORBA_CLIENT_HEADER(GEOM_Gen)
+
+#include
+
+class DependencyTree_Object: public GraphicsView_Object
+{
+
+public:
+
+ DependencyTree_Object( const std::string&, QGraphicsItem* = 0 );
+ ~DependencyTree_Object();
+
+ virtual void compute() {};
+
+ virtual bool highlight( double, double );
+ virtual void unhighlight();
+
+ virtual bool select( double, double, const QRectF& );
+ virtual void unselect();
+
+ std::string getEntry() const;
+
+ GEOM::GEOM_BaseObject_var getGeomObject() const;
+
+ void updateName();
+
+ void setColor( const QColor& );
+ void setSelectColor( const QColor& );
+ void setMainObjectColor( const QColor& );
+ void setUnpublishObjectColor( const QColor& );
+
+ void setIsMainObject( bool );
+
+private:
+
+ QPen getPen( const QColor& );
+
+ QColor myColor;
+ QColor mySelectColor;
+ QColor myMainObjectColor;
+ QColor myUnpublishObjectColor;
+
+ QGraphicsPolygonItem* myPolygonItem;
+ QGraphicsSimpleTextItem* myTextItem;
+
+ GEOM::GEOM_BaseObject_var myGeomObject;
+ std::string myEntry;
+
+ bool myIsMainObject;
+
+};
+
+#endif
diff --git a/src/DependencyTree/DependencyTree_Selector.cxx b/src/DependencyTree/DependencyTree_Selector.cxx
new file mode 100644
index 000000000..370e4511c
--- /dev/null
+++ b/src/DependencyTree/DependencyTree_Selector.cxx
@@ -0,0 +1,105 @@
+// Copyright (C) 2014 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// internal includes
+#include "DependencyTree_Selector.h"
+#include "DependencyTree_View.h"
+#include "DependencyTree_ViewModel.h"
+#include "DependencyTree_Object.h"
+
+// GUI includes
+#include
+
+//GEOM includes
+#include
+#include
+
+DependencyTree_Selector::DependencyTree_Selector( DependencyTree_ViewModel* theModel, SUIT_SelectionMgr* theSelMgr )
+:LightApp_GVSelector( (GraphicsView_Viewer*)theModel, theSelMgr )
+{
+ myView = dynamic_cast( theModel->getActiveViewPort() );
+}
+
+DependencyTree_Selector::~DependencyTree_Selector()
+{
+}
+
+//=================================================================================
+// function : getSelection()
+// purpose : get list of selected Data Owner objects.
+//=================================================================================
+void DependencyTree_Selector::getSelection( SUIT_DataOwnerPtrList& theList ) const
+{
+ for( myView->initSelected(); myView->moreSelected(); myView->nextSelected() )
+ if( DependencyTree_Object* treeObject = dynamic_cast( myView->selectedObject() ) ) {
+ const char* entry;
+ const char* name;
+ GEOM::GEOM_BaseObject_var anObj = GeometryGUI::GetGeomGen()->GetObject( myView->getStudyId(),
+ treeObject->getEntry().c_str() );
+ if( anObj->_is_nil() )
+ continue;
+ QString studyEntry = anObj->GetStudyEntry();
+ if( studyEntry.isEmpty() ) {
+ entry = treeObject->getEntry().c_str();
+ name = "TEMP_IO_UNPUBLISHED";
+ }
+ else {
+ entry = studyEntry.toStdString().c_str();
+ name = "TEMP_IO";
+ }
+ Handle(SALOME_InteractiveObject) tmpIO =
+ new SALOME_InteractiveObject( entry, "GEOM", name);
+
+ theList.append( new LightApp_DataOwner( tmpIO ) );
+ }
+}
+
+//=================================================================================
+// function : setSelection()
+// purpose : set to selected list of Data Owner objects.
+//=================================================================================
+void DependencyTree_Selector::setSelection( const SUIT_DataOwnerPtrList& theList )
+{
+ myView->clearSelected();
+
+ for ( SUIT_DataOwnerPtrList::const_iterator it = theList.begin(); it != theList.end(); ++it ) {
+ const LightApp_DataOwner* owner = dynamic_cast( (*it).operator->() );
+ if ( owner )
+ if( !owner->IO().IsNull() ) {
+ const char* name = owner->IO()->getName();
+ const char* entry;
+ if( strcmp( owner->IO()->getComponentDataType(), "GEOM" ) != 0 )
+ return;
+
+ if( strcmp( name, "TEMP_IO_UNPUBLISHED" ) == 0 )
+ entry = owner->IO()->getEntry();
+ else {
+ GEOM::GEOM_Object_var geomObject = GEOMBase::ConvertIOinGEOMObject( owner->IO() );
+ if( geomObject->_is_nil() )
+ return;
+ entry = geomObject->GetEntry();
+ }
+ DependencyTree_Object* object = myView->getObjectByEntry( entry );
+ if( object ) {
+ myView->setSelected( object );
+ object->select( object->pos().x(), object->pos().y(), object->getRect() );
+ }
+ }
+ }
+}
diff --git a/src/DependencyTree/DependencyTree_Selector.h b/src/DependencyTree/DependencyTree_Selector.h
new file mode 100644
index 000000000..b5096920a
--- /dev/null
+++ b/src/DependencyTree/DependencyTree_Selector.h
@@ -0,0 +1,47 @@
+// Copyright (C) 2014 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef DEPENDENCYTREE_SELECTOR_H
+#define DEPENDENCYTREE_SELECTOR_H
+
+#include
+
+class DependencyTree_ViewModel;
+class DependencyTree_View;
+
+class DependencyTree_Selector: public LightApp_GVSelector
+{
+
+public:
+
+ DependencyTree_Selector( DependencyTree_ViewModel*, SUIT_SelectionMgr* );
+ ~DependencyTree_Selector();
+
+protected:
+
+ virtual void getSelection( SUIT_DataOwnerPtrList& ) const;
+ virtual void setSelection( const SUIT_DataOwnerPtrList& );
+
+private:
+
+ DependencyTree_View* myView;
+
+};
+
+#endif
diff --git a/src/DependencyTree/DependencyTree_View.cxx b/src/DependencyTree/DependencyTree_View.cxx
new file mode 100644
index 000000000..884446e6e
--- /dev/null
+++ b/src/DependencyTree/DependencyTree_View.cxx
@@ -0,0 +1,798 @@
+// Copyright (C) 2014 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// Internal includes
+#include "DependencyTree_View.h"
+#include "DependencyTree_Object.h"
+#include "DependencyTree_Arrow.h"
+
+// GUI includes
+#include
+#include
+#include
+#include
+#include
+#include
+
+// GEOM includes
+#include
+
+// Qt includes
+#include
+#include
+#include
+
+DependencyTree_View::DependencyTree_View( QWidget* theParent )
+:GraphicsView_ViewPort( theParent ),
+myLevelsNumber(0),
+myMaxDownwardLevelsNumber(0),
+myMaxUpwardLevelsNumber(0),
+myIsUpdate( true )
+{
+ SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
+ if ( !app ) return;
+
+ SalomeApp_Study* study = dynamic_cast( app->activeStudy() );
+ myStudy = GeometryGUI::ClientStudyToStudy( study->studyDS());
+
+ mySelectionMgr = app->selectionMgr();
+ if ( !mySelectionMgr ) return;
+
+ myMainEntries = new GEOM::string_array();
+
+ getNewTreeModel();
+}
+
+DependencyTree_View::~DependencyTree_View()
+{
+ clearView( true );
+}
+
+//=================================================================================
+// function : init()
+// purpose : this method is obligatory for initialize view frame actions
+//=================================================================================
+void DependencyTree_View::init( GraphicsView_ViewFrame* theViewFrame )
+{
+ myNodesMovable = new QCheckBox( tr( "MOVE_NODES" ) );
+ QWidgetAction* nodesMovableAction = new QWidgetAction( theViewFrame );
+ nodesMovableAction->setDefaultWidget( myNodesMovable );
+
+ myDisplayAscendants = new QCheckBox( tr( "DISPLAY_ASCENDANTS" ) );
+ QWidgetAction* displayAscendantsAction = new QWidgetAction( theViewFrame );
+ displayAscendantsAction->setDefaultWidget( myDisplayAscendants );
+
+ myDisplayDescendants = new QCheckBox(tr("DISPLAY_DESCENDANTS"));
+ QWidgetAction* displayDescendantsAction = new QWidgetAction( theViewFrame );
+ displayDescendantsAction->setDefaultWidget( myDisplayDescendants );
+
+ QLabel* hierarchyDepthLabel = new QLabel( tr( "HIERARCHY_DEPTH" ) );
+ QWidgetAction* hierarchyDepthLabelAction = new QWidgetAction( theViewFrame );
+ hierarchyDepthLabelAction->setDefaultWidget( hierarchyDepthLabel );
+
+ myLevelsNumber = checkMaxLevelsNumber();
+
+ myHierarchyDepth = new QSpinBox();
+ myHierarchyDepth->setRange( 0, checkMaxLevelsNumber() );
+ myHierarchyDepth->setSpecialValueText( tr( "SHOW_ALL" ) );
+ myHierarchyDepth->setValue( 0 );
+ QWidgetAction* hierarchyDepthAction = new QWidgetAction( theViewFrame );
+ hierarchyDepthAction->setDefaultWidget( myHierarchyDepth );
+
+ updateButton = new QPushButton( tr( "UPDATE" ) );
+ QWidgetAction* updateAction = new QWidgetAction( theViewFrame );
+ updateAction->setDefaultWidget( updateButton );
+
+ QAction* separator1 = theViewFrame->toolMgr()->separator( false );
+ QAction* separator2 = theViewFrame->toolMgr()->separator( false );
+
+ theViewFrame->toolMgr()->append( separator1, theViewFrame->getToolBarId() );
+ theViewFrame->toolMgr()->append( hierarchyDepthLabelAction, theViewFrame->getToolBarId() );
+ theViewFrame->toolMgr()->append( hierarchyDepthAction, theViewFrame->getToolBarId() );
+ theViewFrame->toolMgr()->append( displayAscendantsAction, theViewFrame->getToolBarId() );
+ theViewFrame->toolMgr()->append( displayDescendantsAction, theViewFrame->getToolBarId() );
+ theViewFrame->toolMgr()->append( nodesMovableAction, theViewFrame->getToolBarId() );
+
+ theViewFrame->toolMgr()->append( separator2, theViewFrame->getToolBarId() );
+ theViewFrame->toolMgr()->append( updateAction, theViewFrame->getToolBarId() );
+
+ connect( myNodesMovable, SIGNAL( toggled( bool ) ), this, SLOT( onMoveNodes( bool ) ) );
+ connect( myHierarchyDepth, SIGNAL( valueChanged ( int ) ), this, SLOT( onHierarchyType() ) );
+ connect( myDisplayAscendants , SIGNAL( toggled( bool ) ), this, SLOT( onHierarchyType() ) );
+ connect( myDisplayDescendants, SIGNAL( toggled( bool ) ), this, SLOT( onHierarchyType() ) );
+ connect( updateButton, SIGNAL( clicked() ), this, SLOT( onUpdateModel() ) );
+
+ SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
+ GeometryGUI* aGeomGUI = dynamic_cast( app->module( "Geometry" ) );
+ if ( aGeomGUI ) {
+ connect( aGeomGUI, SIGNAL( SignalDependencyTreeParamChanged( const QString&, const QString& ) ),
+ this, SLOT( onPreferenceChanged( const QString&, const QString& ) ) );
+ connect( aGeomGUI, SIGNAL( SignalDependencyTreeRenameObject( const QString& ) ),
+ this, SLOT( onRenameObject( const QString& ) ) );
+ }
+
+ SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+ setPrefBackgroundColor( resMgr->colorValue( "Geometry", "dependency_tree_background_color", QColor( 255, 255, 255 ) ) );
+ setNodesMovable( resMgr->booleanValue( "Geometry", "dependency_tree_move_nodes", true ) );
+ setHierarchyType( resMgr->integerValue( "Geometry", "dependency_tree_hierarchy_type", 0 ) );
+}
+
+//=================================================================================
+// function : updateModel()
+// purpose : run all stage of dependency tree creation
+//=================================================================================
+void DependencyTree_View::updateModel( bool theUseSelectedObject, bool theUseOB )
+{
+ getNewTreeModel( theUseSelectedObject, theUseOB );
+ onHierarchyType();
+}
+
+//=================================================================================
+// function : mouseMoveEvent()
+// purpose : make some actions when mouse was moved
+//=================================================================================
+void DependencyTree_View::mouseMoveEvent( QMouseEvent *event )
+{
+ QGraphicsView::mouseMoveEvent( event );
+ ArrowsInfo::const_iterator i;
+ for( i = myArrows.begin(); i != myArrows.end(); i++ ) {
+ if( DependencyTree_Arrow* arrow = myArrows[ i->first ] )
+ arrow->update();
+ }
+}
+
+//=================================================================================
+// function : wheelEvent()
+// purpose : add zoom action when wheel is spinning
+//=================================================================================
+void DependencyTree_View::wheelEvent( QWheelEvent* event )
+{
+ int inc = 10; // zoom coefficient
+ double cx = width() / 2;
+ double cy = height() / 2;
+ if( event->delta() > 0 )
+ zoom( cx, cy, cx + inc, cy + inc );
+ else
+ zoom( cx, cy, cx - inc, cy - inc );
+
+ QGraphicsView::wheelEvent( event );
+}
+
+//=================================================================================
+// function : getViewName()
+// purpose : return the name of current view
+//=================================================================================
+QString DependencyTree_View::getViewName() const
+{
+ return tr( "DEPENDENCY_TREE" );
+}
+
+//=================================================================================
+// function : getStudyId()
+// purpose : return Id of current study
+//=================================================================================
+int DependencyTree_View::getStudyId() const
+{
+ return myStudy->StudyId();
+}
+
+//=================================================================================
+// function : getObjectByEntry()
+// purpose : return DependencyTree_Object by entry
+//=================================================================================
+DependencyTree_Object* DependencyTree_View::getObjectByEntry( const std::string& theEntry )
+{
+ return myTreeMap[ theEntry ];
+}
+
+//=================================================================================
+// function : setHierarchyType()
+// purpose : set hierarchy type of dependency tree
+//=================================================================================
+void DependencyTree_View::setHierarchyType( const int theType )
+{
+ myIsUpdate = false;
+ switch( theType ) {
+ case 0:
+ myDisplayAscendants->setChecked( true );
+ myDisplayDescendants->setChecked( true );
+ break;
+ case 1:
+ myDisplayAscendants->setChecked( true );
+ myDisplayDescendants->setChecked( false );
+ break;
+ case 2:
+ myDisplayAscendants->setChecked( false );
+ myDisplayDescendants->setChecked( true );
+ break;
+ }
+ myIsUpdate = true;
+ myLevelsNumber = checkMaxLevelsNumber();
+ onHierarchyType();
+}
+
+//=================================================================================
+// function : setNodesMovable()
+// purpose : set possibility to move nodes or not
+//=================================================================================
+void DependencyTree_View::setNodesMovable( const bool theIsMovable )
+{
+ myNodesMovable->setChecked( theIsMovable );
+}
+
+//=================================================================================
+// function : setPrefBackgroundColor()
+// purpose : set background color from preferences
+//=================================================================================
+void DependencyTree_View::setPrefBackgroundColor( const QColor& theColor )
+{
+ if( isForegroundEnabled() )
+ {
+ setForegroundColor( theColor );
+ updateForeground();
+ }
+ else
+ setBackgroundColor( theColor );
+}
+
+//=================================================================================
+// function : setNodeColor()
+// purpose : set node color from preferences
+//=================================================================================
+void DependencyTree_View::setNodeColor( const QColor& theColor )
+{
+ EntryObjectMap::const_iterator i;
+ for( i = myTreeMap.begin(); i != myTreeMap.end(); i++ ) {
+ DependencyTree_Object* object = myTreeMap[ i->first ];
+ object->setColor( theColor );
+ }
+}
+
+//=================================================================================
+// function : setMainNodeColor()
+// purpose : set main node color from preferences
+//=================================================================================
+void DependencyTree_View::setMainNodeColor( const QColor& theColor )
+{
+ EntryObjectMap::const_iterator i;
+ for( i = myTreeMap.begin(); i != myTreeMap.end(); i++ ) {
+ DependencyTree_Object* object = myTreeMap[ i->first ];
+ object->setMainObjectColor( theColor );
+ }
+}
+
+//=================================================================================
+// function : setUnpublishNodeColor()
+// purpose : set unpublished node color from preferences
+//=================================================================================
+void DependencyTree_View::setUnpublishNodeColor( const QColor& theColor )
+{
+ EntryObjectMap::const_iterator i;
+ for( i = myTreeMap.begin(); i != myTreeMap.end(); i++ ) {
+ DependencyTree_Object* object = myTreeMap[ i->first ];
+ object->setUnpublishObjectColor( theColor );
+ }
+}
+
+//=================================================================================
+// function : setSelectNodeColor()
+// purpose : set selected node color from preferences
+//=================================================================================
+void DependencyTree_View::setSelectNodeColor( const QColor& theColor )
+{
+ EntryObjectMap::const_iterator i;
+ for( i = myTreeMap.begin(); i != myTreeMap.end(); i++ ) {
+ DependencyTree_Object* object = myTreeMap[ i->first ];
+ object->setSelectColor( theColor );
+ }
+}
+
+//=================================================================================
+// function : setArrowColor()
+// purpose : set arrow color from preferences
+//=================================================================================
+void DependencyTree_View::setArrowColor( const QColor& theColor )
+{
+ ArrowsInfo::const_iterator i;
+ for( i = myArrows.begin(); i != myArrows.end(); i++ ) {
+ DependencyTree_Arrow* arrow = myArrows[ i->first ];
+ arrow->setColor( theColor );
+ }
+}
+
+//=================================================================================
+// function : setHighlightArrowColor()
+// purpose : set highlighted arrow color from preferences
+//=================================================================================
+void DependencyTree_View::setHighlightArrowColor( const QColor& theColor )
+{
+ ArrowsInfo::const_iterator i;
+ for( i = myArrows.begin(); i != myArrows.end(); i++ ) {
+ DependencyTree_Arrow* arrow = myArrows[ i->first ];
+ arrow->setHighlightColor( theColor );
+ }
+}
+
+//=================================================================================
+// function : setSelectArrowColor()
+// purpose : set selected arrow color from preferences
+//=================================================================================
+void DependencyTree_View::setSelectArrowColor( const QColor& theColor )
+{
+ ArrowsInfo::const_iterator i;
+ for( i = myArrows.begin(); i != myArrows.end(); i++ ) {
+ DependencyTree_Arrow* arrow = myArrows[ i->first ];
+ arrow->setSelectColor( theColor );
+ }
+}
+
+//=================================================================================
+// function : onRebuildModel()
+// purpose : slot for updating tree model using selected objects in viewer
+//=================================================================================
+void DependencyTree_View::onRebuildModel()
+{
+ updateModel( true, false );
+}
+
+//=================================================================================
+// function : onUpdateModel()
+// purpose : slot for updating tree model for main objects in viewer
+//=================================================================================
+void DependencyTree_View::onUpdateModel()
+{
+ updateModel( false );
+}
+
+//=================================================================================
+// function : onMoveNodes()
+// purpose : slot for setting the possibility to move nodes in viewer
+//=================================================================================
+void DependencyTree_View::onMoveNodes( bool theIsMoveNodes )
+{
+ EntryObjectMap::const_iterator i;
+ for( i = myTreeMap.begin(); i != myTreeMap.end(); i++ ) {
+ DependencyTree_Object* object = myTreeMap[ i->first ];
+ if( object )
+ object->setMovable( theIsMoveNodes );
+ }
+}
+
+//=================================================================================
+// function : onHierarchyType()
+// purpose : slot for setting the hierarchy type of tree
+//=================================================================================
+void DependencyTree_View::onHierarchyType()
+{
+ myHierarchyDepth->setRange( 0, checkMaxLevelsNumber() );
+ if( myHierarchyDepth->value() > checkMaxLevelsNumber() )
+ myHierarchyDepth->setValue( checkMaxLevelsNumber() );
+
+ if( myHierarchyDepth->value() == 0 )
+ myLevelsNumber = myHierarchyDepth->maximum();
+ else
+ myLevelsNumber = myHierarchyDepth->value();
+
+ updateView();
+}
+
+//=================================================================================
+// function : onPreferencesChanged()
+// purpose : slot for changing tree parameters from preferences
+//=================================================================================
+void DependencyTree_View::onPreferenceChanged( const QString& section, const QString& param )
+{
+ SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+
+ if( param == QString("dependency_tree_hierarchy_type") ) {
+ int hierarchyType = resMgr->integerValue( section, param, 0);
+ setHierarchyType( hierarchyType );
+ }
+ else if( param == QString("dependency_tree_move_nodes") ) {
+ bool isNodesMovable = resMgr->booleanValue( section, param, true);
+ setNodesMovable( isNodesMovable );
+ }
+ else if( param == QString("dependency_tree_background_color") ) {
+ QColor c = resMgr->colorValue( section, param, QColor( 255, 255, 255 ) );
+ setPrefBackgroundColor( c );
+ }
+ else if( param == QString("dependency_tree_node_color") ) {
+ QColor c = resMgr->colorValue( section, param, QColor( 62, 180, 238 ) );
+ setNodeColor( c );
+ }
+ else if( param == QString("dependency_tree_main_node_color") ) {
+ QColor c = resMgr->colorValue( section, param, QColor( 238, 90, 125 ) );
+ setMainNodeColor( c );
+ }
+ else if( param == QString("dependency_tree_unpublish_node_color") ) {
+ QColor c = resMgr->colorValue( section, param, QColor( 255, 255, 255 ) );
+ setUnpublishNodeColor( c );
+ }
+ else if( param == QString("dependency_tree_select_node_color") ) {
+ QColor c = resMgr->colorValue( section, param, QColor( 237, 243, 58 ) );
+ setSelectNodeColor( c );
+ }
+ else if( param == QString("dependency_tree_arrow_color") ) {
+ QColor c = resMgr->colorValue( section, param, QColor( 0, 0, 130 ) );
+ setArrowColor( c );
+ }
+ else if( param == QString("dependency_tree_highlight_arrow_color") ) {
+ QColor c = resMgr->colorValue( section, param, QColor( 0, 0, 255 ) );
+ setHighlightArrowColor( c );
+ }
+ else if( param == QString("dependency_tree_select_arrow_color") ) {
+ QColor c = resMgr->colorValue( section, param, QColor( 255, 0, 0 ) );
+ setSelectArrowColor( c );
+ }
+}
+
+//=================================================================================
+// function : onRenameObject()
+// purpose : update object name, having edited it in Object Browser
+//=================================================================================
+void DependencyTree_View::onRenameObject( const QString& theEntry )
+{
+ if( DependencyTree_Object* object = getObjectByEntry( theEntry.toStdString() ) )
+ object->updateName();
+}
+
+//=================================================================================
+// function : parseTree()
+// purpose : parse created model to initialize all nodes and arrows
+//=================================================================================
+void DependencyTree_View::parseTree()
+{
+ GEOMUtils::TreeModel::const_iterator i;
+ for( i = myTreeModel.begin(); i != myTreeModel.end(); i++ ) {
+ std::string objectEntry = i->first;
+ addNode( objectEntry );
+ parseTreeWard( i->second.first );
+ if( i->second.first.size() > myMaxUpwardLevelsNumber )
+ myMaxUpwardLevelsNumber = i->second.first.size();
+ parseTreeWard( i->second.second );
+ if( i->second.second.size() > myMaxDownwardLevelsNumber )
+ myMaxDownwardLevelsNumber = i->second.second.size();
+ }
+
+ for( i = myTreeModel.begin(); i != myTreeModel.end(); i++ ) {
+ DependencyTree_Object* Main_object = myTreeMap[ i->first ];
+ if( i->second.first.size() > 0 ) {
+ GEOMUtils::LevelInfo Levelup = i->second.first.at(0);
+ GEOMUtils::LevelInfo::const_iterator node;
+ for( node = Levelup.begin(); node != Levelup.end(); node++ ) {
+ DependencyTree_Object* object = myTreeMap[ node->first ];
+ addArrow( Main_object, object );
+ }
+ }
+ parseTreeWardArrow( i->second.first );
+ parseTreeWardArrow( i->second.second );
+ }
+}
+
+//=================================================================================
+// function : parseTreeWard()
+// purpose : parse tree ward to initialize all nodes of current ward
+//=================================================================================
+void DependencyTree_View::parseTreeWard( const GEOMUtils::LevelsList& theWard )
+{
+ int levelsNumber = theWard.size();
+ for( int level = 0; level < levelsNumber; level++ ) {
+ GEOMUtils::LevelInfo levelInfo = theWard[ level ];
+ GEOMUtils::LevelInfo::const_iterator node;
+ for( node = levelInfo.begin(); node != levelInfo.end(); node++ )
+ addNode( node->first );
+ }
+}
+
+//=================================================================================
+// function : parseTreeWardArrow()
+// purpose : parse tree ward to initialize all arrows of current ward
+//=================================================================================
+void DependencyTree_View::parseTreeWardArrow( const GEOMUtils::LevelsList& theWard)
+{
+ for( int j = 0; j < theWard.size(); j++ ) {
+ GEOMUtils::LevelInfo Level = theWard.at(j);
+ GEOMUtils::LevelInfo::const_iterator node;
+ for( node = Level.begin(); node != Level.end(); node++ ) {
+ DependencyTree_Object* object = myTreeMap[ node->first ];
+ std::vector Links = node->second;
+ for( int link = 0; link < Links.size(); link++ ) {
+ DependencyTree_Object* LinkObject = myTreeMap[ Links[ link ] ];
+ if( object && LinkObject )
+ addArrow( object, LinkObject );
+ }
+ }
+ }
+}
+
+//=================================================================================
+// function : addNode()
+// purpose : add node to viewer
+//=================================================================================
+void DependencyTree_View::addNode( const std::string& theEntry )
+{
+ if( !myTreeMap[theEntry] )
+ myTreeMap[theEntry] = new DependencyTree_Object( theEntry );
+}
+
+//=================================================================================
+// function : addArrow()
+// purpose : add arrow to viewer
+//=================================================================================
+void DependencyTree_View::addArrow( DependencyTree_Object* startItem, DependencyTree_Object* endItem )
+{
+ bool isFind = false;
+
+ ArrowsInfo::const_iterator i;
+ for( i = myArrows.begin(); i != myArrows.end(); i++ ) {
+ DependencyTree_Arrow* arrow = i->second;
+ if( arrow->getStartItem() == startItem && arrow->getEndItem() == endItem )
+ isFind = true;
+ else if( arrow->getStartItem() == endItem && arrow->getEndItem() == startItem ) {
+ arrow->setIsBiLink( true );
+ isFind = true;
+ }
+ }
+ if( !isFind ) {
+ DependencyTree_Arrow *arrow = new DependencyTree_Arrow( startItem, endItem );
+ myArrows[ std::pair( startItem, endItem ) ] = arrow;
+ }
+}
+
+//=================================================================================
+// function : drawTree()
+// purpose : redraw dependency tree using existing model
+//=================================================================================
+void DependencyTree_View::drawTree()
+{
+ clearView( false );
+ clearSelected();
+
+ // draw nodes on scene
+ std::map< std::string, int > entryLevelMap;
+ std::map< int, std::vector< std::string > > levelObjects;
+ int currentLevel;
+ int horDistance, verDistance;
+ GEOMUtils::TreeModel::const_reverse_iterator i;
+ for( i = myTreeModel.rbegin(); i != myTreeModel.rend(); i++ ) {
+ currentLevel = 0;
+ std::string objectEntry = i->first;
+ DependencyTree_Object* objectItem = myTreeMap[ objectEntry ];
+ horDistance = 100 + int( objectItem->boundingRect().width() );
+ verDistance = 3 * int( objectItem->boundingRect().height() );
+ if( isItemAdded( objectItem ) )
+ currentLevel = entryLevelMap[ objectEntry ];
+ else {
+ addItem( objectItem );
+ objectItem->unselect();
+ entryLevelMap[ objectEntry ] = currentLevel;
+ levelObjects[ currentLevel ].push_back( objectEntry );
+ }
+ objectItem->setIsMainObject( true );
+
+ if( myDisplayAscendants->isChecked() )
+ drawWard( i->second.first, entryLevelMap, levelObjects, currentLevel, -1 );
+ if( myDisplayDescendants->isChecked() )
+ drawWard( i->second.second, entryLevelMap, levelObjects, currentLevel, 1 );
+ }
+
+ std::map< int, std::vector< std::string > >::const_iterator level;
+ for( level = levelObjects.begin(); level != levelObjects.end(); level++ ) {
+ int step = -horDistance * ( level->second.size() - 1 ) / 2;
+ for( int objIter = 0; objIter < level->second.size(); objIter++ ) {
+ DependencyTree_Object* anObject = myTreeMap[ level->second.at( objIter ) ];
+ anObject->setPos( step, verDistance * level->first );
+ step += horDistance;
+ }
+ }
+
+ // draw arrows on scene
+ GEOMUtils::TreeModel::const_iterator j;
+ for( j = myTreeModel.begin(); j != myTreeModel.end(); j++ ) {
+ DependencyTree_Object* Main_object = myTreeMap[ j->first ];
+ if( j->second.first.size() > 0 ) {
+ GEOMUtils::LevelInfo Levelup = j->second.first.at(0);
+ if( myDisplayAscendants ->isChecked() ) {
+ GEOMUtils::LevelInfo::const_iterator node;
+ for( node = Levelup.begin(); node != Levelup.end(); node++ ) {
+ DependencyTree_Object* object = myTreeMap[ node->first ];
+ DependencyTree_Arrow* arrow =
+ myArrows[ std::pair( Main_object, object )];
+ if( arrow && !isItemAdded( arrow ) )
+ addItem( arrow );
+ }
+ }
+ }
+ if( myDisplayAscendants->isChecked() )
+ drawWardArrows( j->second.first );
+ if( myDisplayDescendants->isChecked() )
+ drawWardArrows( j->second.second );
+ }
+}
+
+//=================================================================================
+// function : drawWard()
+// purpose : draw nodes of dependency tree ward (ascendant or descendant)
+//=================================================================================
+void DependencyTree_View::drawWard( const GEOMUtils::LevelsList& theWard,
+ std::map< std::string, int >& theEntryLevelMap,
+ std::map< int, std::vector< std::string > >& theLevelObjects,
+ int theCurrentLevel, const int theLevelStep )
+{
+ for( int level = 0; level < theWard.size(); level++ ) {
+ if( level >= myLevelsNumber )
+ return;
+ theCurrentLevel += theLevelStep;
+ GEOMUtils::LevelInfo levelInfo = theWard.at( level );
+ GEOMUtils::LevelInfo::const_iterator node;
+ for( node = levelInfo.begin(); node != levelInfo.end(); node++ ) {
+ DependencyTree_Object* object = myTreeMap[ node->first ];
+ if( object && !isItemAdded( object ) ) {
+ addItem( object );
+ object->unselect();
+ theEntryLevelMap[ node->first ] = theCurrentLevel;
+ theLevelObjects[ theCurrentLevel ].push_back( node->first );
+ }
+ }
+ }
+}
+
+//=================================================================================
+// function : drawWardArrows()
+// purpose : draw arrows of dependency tree ward (ascendant or descendant)
+//=================================================================================
+void DependencyTree_View::drawWardArrows( const GEOMUtils::LevelsList& theWard )
+{
+ for( int j = 0; j < theWard.size(); j++ ) {
+ if( j >= myLevelsNumber )
+ break;
+ GEOMUtils::LevelInfo Level = theWard.at(j);
+ GEOMUtils::LevelInfo::const_iterator node;
+ for( node = Level.begin(); node != Level.end(); node++ ) {
+ DependencyTree_Object* object = myTreeMap[ node->first ];
+ GEOMUtils::NodeLinks Links = node->second;
+ for( int link = 0; link < Links.size(); link++ ) {
+ DependencyTree_Object* LinkObject = myTreeMap[ Links[ link ] ];
+ if( isItemAdded( object ) && isItemAdded( LinkObject ) ) {
+ DependencyTree_Arrow* arrow = myArrows[ std::pair( object, LinkObject ) ];
+ if( arrow && !isItemAdded( arrow ) )
+ addItem( arrow );
+ }
+ }
+ }
+ }
+}
+
+//=================================================================================
+// function : updateView()
+// purpose : update viewer using created dependency tree model
+//=================================================================================
+void DependencyTree_View::updateView()
+{
+ if( !myIsUpdate )
+ return;
+
+ drawTree();
+ fitAll();
+}
+
+//=================================================================================
+// function : clearView()
+// purpose : clear viewer and initialize all variables
+//=================================================================================
+void DependencyTree_View::clearView( bool isClearModel )
+{
+ EntryObjectMap::const_iterator objectIter;
+ for( objectIter = myTreeMap.begin(); objectIter != myTreeMap.end(); objectIter++ ) {
+ if( DependencyTree_Object* object = objectIter->second )
+ if( isItemAdded( object ) )
+ removeItem( object );
+ }
+
+ ArrowsInfo::const_iterator arrowIter;
+ for( arrowIter = myArrows.begin(); arrowIter != myArrows.end(); arrowIter++ ) {
+ if( DependencyTree_Arrow* arrow = arrowIter->second )
+ if( isItemAdded( arrow ) )
+ removeItem( arrow );
+ }
+
+ if( isClearModel ) {
+ EntryObjectMap::const_iterator objectIter;
+ for( objectIter = myTreeMap.begin(); objectIter != myTreeMap.end(); objectIter++ ) {
+ if( DependencyTree_Object* object = objectIter->second )
+ delete object;
+ }
+
+ ArrowsInfo::const_iterator arrowIter;
+ for( arrowIter = myArrows.begin(); arrowIter != myArrows.end(); arrowIter++ ) {
+ if( DependencyTree_Arrow* arrow = arrowIter->second )
+ delete arrow;
+ }
+ myTreeMap.clear();
+ myArrows.clear();
+ myTreeModel.clear();
+ myLevelsNumber = 0;
+ myMaxDownwardLevelsNumber = 0;
+ myMaxUpwardLevelsNumber = 0;
+ myIsUpdate = true;
+ }
+}
+
+//=================================================================================
+// function : getNewTreeModel()
+// purpose : get dependency tree model from engine
+//=================================================================================
+void DependencyTree_View::getNewTreeModel( bool theUseSelectedObject, bool theUseOB )
+{
+ GEOM::string_array_var objectsEntry = new GEOM::string_array();
+ int iter = 0;
+
+ if( theUseSelectedObject ) {
+ if( theUseOB ) {
+ SALOME_ListIO mainObjects;
+ mySelectionMgr->selectedObjects( mainObjects );
+ // create a list of selected object entry
+ objectsEntry->length( mainObjects.Extent() );
+ for ( SALOME_ListIteratorOfListIO It( mainObjects ); It.More(); It.Next(), iter++ ) {
+ Handle( SALOME_InteractiveObject ) io = It.Value();
+ if( !io->hasEntry() )
+ continue;
+ GEOM::GEOM_Object_var geomObject = GEOM::GEOM_Object::_nil();
+ geomObject = GEOMBase::ConvertIOinGEOMObject( io );
+ QString entry = geomObject->GetEntry();
+ objectsEntry[ iter ] = entry.toLatin1().constData();
+ }
+ }
+ else {
+ objectsEntry->length( nbSelected() );
+ for( initSelected(); moreSelected(); nextSelected(), iter++ )
+ if( DependencyTree_Object* treeObject = dynamic_cast( selectedObject() ) )
+ objectsEntry[ iter ] = treeObject->getEntry().c_str();
+ }
+ myMainEntries = objectsEntry;
+ }
+
+ // get string which describes dependency tree structure
+ SALOMEDS::TMPFile_var SeqFile =
+ GeometryGUI::GetGeomGen()->GetDependencyTree( myStudy, myMainEntries );
+ char* buf = (char*)&SeqFile[0];
+
+ clearView( true );
+ mySelectionMgr->clearSelected();
+
+ // get dependency tree structure
+ GEOMUtils::ConvertStringToTree( buf, myTreeModel );
+
+ parseTree();
+}
+
+//=================================================================================
+// function : checkMaxLevelsNumber()
+// purpose : calculate max levels number
+//=================================================================================
+int DependencyTree_View::checkMaxLevelsNumber()
+{
+ if( myDisplayAscendants->isChecked() && myDisplayDescendants->isChecked() )
+ return myMaxUpwardLevelsNumber > myMaxDownwardLevelsNumber ?
+ myMaxUpwardLevelsNumber : myMaxDownwardLevelsNumber;
+ else if( myDisplayAscendants ->isChecked() )
+ return myMaxUpwardLevelsNumber;
+ else if( myDisplayDescendants->isChecked() )
+ return myMaxDownwardLevelsNumber;
+}
diff --git a/src/DependencyTree/DependencyTree_View.h b/src/DependencyTree/DependencyTree_View.h
new file mode 100644
index 000000000..6c606d401
--- /dev/null
+++ b/src/DependencyTree/DependencyTree_View.h
@@ -0,0 +1,132 @@
+// Copyright (C) 2014 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef DEPENDENCYTREE_VIEW_H
+#define DEPENDENCYTREE_VIEW_H
+
+// GEOM includes
+#include
+#include
+
+// GUI includes
+#include
+#include
+
+#include
+
+// QT includes
+#include
+#include
+#include
+
+class DependencyTree_Object;
+class DependencyTree_Arrow;
+class DependencyTree_View;
+
+typedef std::map EntryObjectMap;
+typedef std::map,DependencyTree_Arrow*> ArrowsInfo;
+
+class DependencyTree_View: public GraphicsView_ViewPort
+{
+ Q_OBJECT
+
+public:
+
+ DependencyTree_View( QWidget* = 0 );
+ ~DependencyTree_View();
+
+ void init( GraphicsView_ViewFrame* );
+ void updateModel( bool = true, bool = true );
+
+ void mouseMoveEvent(QMouseEvent* event);
+ void wheelEvent( QWheelEvent* event );
+
+ QString getViewName() const;
+ int getStudyId() const;
+
+ DependencyTree_Object* getObjectByEntry( const std::string& );
+
+public slots:
+
+ void onRebuildModel();
+
+private slots:
+
+ void onUpdateModel();
+ void onMoveNodes( bool );
+ void onHierarchyType();
+ void onPreferenceChanged( const QString&, const QString& );
+ void onRenameObject( const QString& theEntry );
+
+private:
+
+ void parseTree();
+ void parseTreeWard( const GEOMUtils::LevelsList& );
+ void parseTreeWardArrow( const GEOMUtils::LevelsList& );
+
+ void addNode( const std::string& );
+ void addArrow( DependencyTree_Object*, DependencyTree_Object* );
+
+ void drawTree();
+ void drawWard( const GEOMUtils::LevelsList&, std::map< std::string, int >&,
+ std::map< int, std::vector< std::string > >&, int, const int );
+ void drawWardArrows( const GEOMUtils::LevelsList& );
+
+ void updateView();
+ void clearView( bool );
+
+ int checkMaxLevelsNumber();
+
+ void getNewTreeModel( bool = true, bool = true );
+
+ void setHierarchyType( const int );
+ void setNodesMovable( const bool );
+ void setPrefBackgroundColor( const QColor& );
+ void setNodeColor( const QColor& );
+ void setMainNodeColor( const QColor& );
+ void setUnpublishNodeColor( const QColor& );
+ void setSelectNodeColor( const QColor& );
+ void setArrowColor( const QColor& );
+ void setHighlightArrowColor( const QColor& );
+ void setSelectArrowColor( const QColor& );
+
+ GEOMUtils::TreeModel myTreeModel;
+
+ EntryObjectMap myTreeMap;
+ ArrowsInfo myArrows;
+
+ int myLevelsNumber;
+ int myMaxDownwardLevelsNumber;
+ int myMaxUpwardLevelsNumber;
+
+ QCheckBox* myNodesMovable;
+ QSpinBox* myHierarchyDepth;
+ QCheckBox* myDisplayAscendants;
+ QCheckBox* myDisplayDescendants;
+ QPushButton* updateButton;
+
+ SALOMEDS::Study_var myStudy;
+ LightApp_SelectionMgr* mySelectionMgr;
+ GEOM::string_array_var myMainEntries;
+
+ bool myIsUpdate;
+
+};
+
+#endif
diff --git a/src/DependencyTree/DependencyTree_ViewModel.cxx b/src/DependencyTree/DependencyTree_ViewModel.cxx
new file mode 100644
index 000000000..3c03d67ac
--- /dev/null
+++ b/src/DependencyTree/DependencyTree_ViewModel.cxx
@@ -0,0 +1,148 @@
+// Copyright (C) 2014 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// internal includes
+#include "DependencyTree_ViewModel.h"
+#include "DependencyTree_View.h"
+
+// GUI includes
+#include
+#include
+#include
+#include
+#include
+#include
+
+// GEOM includes
+#include
+#include
+
+// QT includes
+#include
+
+DependencyTree_ViewModel::DependencyTree_ViewModel( const QString& title )
+: GraphicsView_Viewer( title )
+{
+}
+
+DependencyTree_ViewModel::DependencyTree_ViewModel( const QString& title, QWidget* w )
+: GraphicsView_Viewer( title, w )
+{
+}
+
+DependencyTree_ViewModel::~DependencyTree_ViewModel()
+{
+}
+
+//=================================================================================
+// function : onShowSelected()
+// purpose : slot for showing selected objects in OCC Viewer
+//=================================================================================
+void DependencyTree_ViewModel::onShowSelected()
+{
+ SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
+ if ( !app ) return;
+
+ app->getViewManager( OCCViewer_Viewer::Type(), /*create=*/ true );
+
+ LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
+ if ( !aSelMgr ) return;
+
+ SALOME_ListIO aSelList;
+ aSelMgr->selectedObjects(aSelList);
+
+ SalomeApp_Study* appStudy = dynamic_cast( app->activeStudy() );
+ GEOM_Displayer* disp = new GEOM_Displayer( appStudy );
+
+ OCCViewer_ViewManager* anOCCVM = ( OCCViewer_ViewManager* ) app->getViewManager( OCCViewer_Viewer::Type(), /*create=*/ true );
+
+ if ( SUIT_ViewModel* viewModel = anOCCVM->getViewModel() ) {
+ if ( SALOME_View* viewFrame = dynamic_cast( viewModel ) ) {
+ SALOME_ListIteratorOfListIO Iter( aSelList );
+ for ( ; Iter.More(); Iter.Next() )
+ disp->Display( Iter.Value(), false, viewFrame );
+ viewFrame->Repaint();
+ }
+ }
+}
+
+//=================================================================================
+// function : onShowOnlySelected()
+// purpose : slot for showing only selected objects in OCC Viewer
+//=================================================================================
+void DependencyTree_ViewModel::onShowOnlySelected()
+{
+ SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
+ if ( !app ) return;
+
+ LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
+ if ( !aSelMgr ) return;
+
+ SALOME_ListIO aSelList;
+ aSelMgr->selectedObjects( aSelList );
+
+ SalomeApp_Study* appStudy = dynamic_cast( app->activeStudy() );
+ GEOM_Displayer* disp = new GEOM_Displayer( appStudy );
+
+ OCCViewer_ViewManager* anOCCVM = (OCCViewer_ViewManager*) app->getViewManager( OCCViewer_Viewer::Type(), /*create=*/ true );
+
+ if ( SUIT_ViewModel* viewModel = anOCCVM->getViewModel() ) {
+ if ( SALOME_View* viewFrame = dynamic_cast( viewModel ) ) {
+ disp->EraseAll( true, false, viewFrame );
+ SALOME_ListIteratorOfListIO Iter( aSelList );
+ for ( ; Iter.More(); Iter.Next() )
+ disp->Display( Iter.Value(), false, viewFrame );
+ viewFrame->Repaint();
+ }
+ }
+}
+
+//=================================================================================
+// function : onReduceStudy()
+// purpose : slot for showing dialog box "Reduce Study"
+//=================================================================================
+void DependencyTree_ViewModel::onReduceStudy()
+{
+ DependencyTree_View* viewPort = dynamic_cast( getActiveViewPort() );
+ QDialog* dlg = new GEOMToolsGUI_ReduceStudyDlg( viewPort );
+ if( dlg != NULL )
+ dlg->show();
+}
+
+//=================================================================================
+// function : contextMenuPopup()
+// purpose : process calling of context menu popup
+//=================================================================================
+void DependencyTree_ViewModel::contextMenuPopup( QMenu* theMenu )
+{
+ GraphicsView_Viewer::contextMenuPopup( theMenu );
+
+ if( DependencyTree_View* viewPort = dynamic_cast( getActiveViewPort() ) )
+ {
+ int aNbSelected = viewPort->nbSelected();
+ if( aNbSelected > 0 ) {
+ theMenu->clear();
+ theMenu->addAction( tr( "MEN_DISPLAY" ), this, SLOT( onShowSelected() ) );
+ theMenu->addAction( tr( "MEN_DISPLAY_ONLY" ), this, SLOT( onShowOnlySelected() ) );
+ theMenu->addAction( tr( "MEN_REBUILD_THE_TREE"), viewPort, SLOT( onRebuildModel() ) );
+ theMenu->addSeparator();
+ theMenu->addAction( tr( "MEN_REDUCE_STUDY" ), this, SLOT( onReduceStudy() ) );
+ }
+ }
+}
diff --git a/src/DependencyTree/DependencyTree_ViewModel.h b/src/DependencyTree/DependencyTree_ViewModel.h
new file mode 100644
index 000000000..afbfc0da0
--- /dev/null
+++ b/src/DependencyTree/DependencyTree_ViewModel.h
@@ -0,0 +1,46 @@
+// Copyright (C) 2014 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef DEPENDENCYTREE_VIEWMODEL_H
+#define DEPENDENCYTREE_VIEWMODEL_H
+
+#include
+
+class DependencyTree_ViewModel: public GraphicsView_Viewer
+{
+
+ Q_OBJECT
+
+public:
+
+ DependencyTree_ViewModel( const QString& title );
+ DependencyTree_ViewModel( const QString& title, QWidget* w );
+ ~DependencyTree_ViewModel();
+
+ virtual void contextMenuPopup( QMenu* );
+
+private slots:
+
+ void onShowSelected();
+ void onShowOnlySelected();
+ void onReduceStudy();
+
+};
+
+#endif
diff --git a/src/DependencyTree/resources/DependencyTree_msg_en.ts b/src/DependencyTree/resources/DependencyTree_msg_en.ts
new file mode 100644
index 000000000..c1c04a16d
--- /dev/null
+++ b/src/DependencyTree/resources/DependencyTree_msg_en.ts
@@ -0,0 +1,44 @@
+
+
+
+
+ DependencyTree_View
+
+
+ Dependency Tree
+
+
+
+ Move nodes
+
+
+
+ Hierarchy depth
+
+
+
+ Display ascendants
+
+
+
+ Display descendants
+
+
+
+ Show all
+
+
+
+ Update
+
+ DependencyTree_ViewModel
+
+
+ Rebuild the tree
+
+
+
+ Reduce study
+
+
+
diff --git a/src/DependencyTree/resources/DependencyTree_msg_fr.ts b/src/DependencyTree/resources/DependencyTree_msg_fr.ts
new file mode 100644
index 000000000..ffeb404bc
--- /dev/null
+++ b/src/DependencyTree/resources/DependencyTree_msg_fr.ts
@@ -0,0 +1,44 @@
+
+
+
+
+ DependencyTree_View
+
+
+ Dependency Tree
+
+
+
+ Move nodes
+
+
+
+ Hierarchy depth
+
+
+
+ Display ascendants
+
+
+
+ Display descendants
+
+
+
+ Show all
+
+
+
+ Update
+
+ DependencyTree_ViewModel
+
+
+ Rebuild the tree
+
+
+
+ Reduce study
+
+
+
diff --git a/src/DependencyTree/resources/DependencyTree_msg_ja.ts b/src/DependencyTree/resources/DependencyTree_msg_ja.ts
new file mode 100644
index 000000000..642f04c6a
--- /dev/null
+++ b/src/DependencyTree/resources/DependencyTree_msg_ja.ts
@@ -0,0 +1,44 @@
+
+
+
+
+ DependencyTree_View
+
+
+ Dependency Tree
+
+
+
+ Move nodes
+
+
+
+ Hierarchy depth
+
+
+
+ Display ascendants
+
+
+
+ Display descendants
+
+
+
+ Show all
+
+
+
+ Update
+
+ DependencyTree_ViewModel
+
+
+ Rebuild the tree
+
+
+
+ Reduce study
+
+
+
\ No newline at end of file
diff --git a/src/DependencyTree/resources/tree_view_dump.png b/src/DependencyTree/resources/tree_view_dump.png
new file mode 100644
index 000000000..b02616f29
Binary files /dev/null and b/src/DependencyTree/resources/tree_view_dump.png differ
diff --git a/src/DependencyTree/resources/tree_view_fitall.png b/src/DependencyTree/resources/tree_view_fitall.png
new file mode 100644
index 000000000..386c966d1
Binary files /dev/null and b/src/DependencyTree/resources/tree_view_fitall.png differ
diff --git a/src/DependencyTree/resources/tree_view_fitarea.png b/src/DependencyTree/resources/tree_view_fitarea.png
new file mode 100644
index 000000000..e83d023a3
Binary files /dev/null and b/src/DependencyTree/resources/tree_view_fitarea.png differ
diff --git a/src/DependencyTree/resources/tree_view_fitselect.png b/src/DependencyTree/resources/tree_view_fitselect.png
new file mode 100755
index 000000000..e52598d7b
Binary files /dev/null and b/src/DependencyTree/resources/tree_view_fitselect.png differ
diff --git a/src/DependencyTree/resources/tree_view_glpan.png b/src/DependencyTree/resources/tree_view_glpan.png
new file mode 100644
index 000000000..28ab547ea
Binary files /dev/null and b/src/DependencyTree/resources/tree_view_glpan.png differ
diff --git a/src/DependencyTree/resources/tree_view_pan.png b/src/DependencyTree/resources/tree_view_pan.png
new file mode 100644
index 000000000..ec56cacc7
Binary files /dev/null and b/src/DependencyTree/resources/tree_view_pan.png differ
diff --git a/src/DependencyTree/resources/tree_view_reset.png b/src/DependencyTree/resources/tree_view_reset.png
new file mode 100644
index 000000000..66f81e604
Binary files /dev/null and b/src/DependencyTree/resources/tree_view_reset.png differ
diff --git a/src/DependencyTree/resources/tree_view_zoom.png b/src/DependencyTree/resources/tree_view_zoom.png
new file mode 100644
index 000000000..386c966d1
Binary files /dev/null and b/src/DependencyTree/resources/tree_view_zoom.png differ
diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts
index 30942dd61..e125146d8 100644
--- a/src/GEOMGUI/GEOM_msg_en.ts
+++ b/src/GEOMGUI/GEOM_msg_en.ts
@@ -4760,6 +4760,14 @@ Please, select face, shell or solid and try again
Manage measurement dimensions of an object
+
+
+ Show dependency tree
+
+
+
+ Reduce study
+ Show all dimensions
@@ -5024,6 +5032,66 @@ Please, select face, shell or solid and try again
Preview
+
+
+ Dependency Tree
+
+
+
+ Hierarchy type
+
+
+
+ Display only ascendants tree
+
+
+
+ Display only descendants tree
+
+
+
+ Display both ascendants and descendants trees
+
+
+
+ Possibility to move nodes
+
+
+
+ Color
+
+
+
+ Background color
+
+
+
+ Default node color
+
+
+
+ Main node color
+
+
+
+ Unpublished node color
+
+
+
+ Selected node color
+
+
+
+ Default arrow color
+
+
+
+ Highlighted arrow color
+
+
+
+ Selected arrow color
+ All supported formats ( %1 )
@@ -6821,6 +6889,61 @@ Do you want to create new material?
P&ublish And Close
+
+ GEOMToolsGUI_ReduceStudyDlg
+
+
+ Reduce study
+
+
+
+ Objects to be kept
+
+
+
+ Objects to be removed
+
+
+
+ Name
+
+
+
+ Options
+
+
+
+ Intermediate objects
+
+
+
+ Sub-objects
+
+
+
+ Keep
+
+
+
+ Unpublish
+
+
+
+ Remove
+
+
+
+ Remove empty folders
+
+
+
+ Soft removal
+
+
+
+ Do you really want to delete intermediate objects? After applying this operation study will be broken.
+
+RepairGUI_UnionFacesDlg
diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts
index df93751d1..4aa87fa5a 100644
--- a/src/GEOMGUI/GEOM_msg_fr.ts
+++ b/src/GEOMGUI/GEOM_msg_fr.ts
@@ -4760,6 +4760,14 @@ Choisissez une face, une coque ou un solide et essayez de nouveau
Gérer la cotation d'un objet
+
+
+ Show dependency tree
+
+
+
+ Reduce study
+ Afficher les cotations
@@ -5024,6 +5032,66 @@ Choisissez une face, une coque ou un solide et essayez de nouveau
Prévisualiser
+
+
+ Dependency Tree
+
+
+
+ Hierarchy type
+
+
+
+ Display only ascendants tree
+
+
+
+ Display only descendants tree
+
+
+
+ Display both ascendants and descendants trees
+
+
+
+ Possibility to move nodes
+
+
+
+ Color
+
+
+
+ Background color
+
+
+
+ Default node color
+
+
+
+ Main node color
+
+
+
+ Unpublished node color
+
+
+
+ Selected node color
+
+
+
+ Arrow color
+
+
+
+ Highlighted arrow color
+
+
+
+ Selected arrow color
+ Tous les formats supportés ( %1 )
@@ -6821,6 +6889,61 @@ Voulez-vous en créer un nouveau ?
P&ublier et fermer
+
+ GEOMToolsGUI_ReduceStudyDlg
+
+
+ Reduce study
+
+
+
+ Objects to be kept
+
+
+
+ Objects to be removed
+
+
+
+ Name
+
+
+
+ Options
+
+
+
+ Intermediate objects
+
+
+
+ Sub-objects
+
+
+
+ Keep
+
+
+
+ Unpublish
+
+
+
+ Remove
+
+
+
+ Remove empty folders
+
+
+
+ Soft removal
+
+
+
+ Do you really want to delete intermediate objects? After applying this operation study will be broken.
+
+RepairGUI_UnionFacesDlg
diff --git a/src/GEOMGUI/GEOM_msg_ja.ts b/src/GEOMGUI/GEOM_msg_ja.ts
index dc0079230..e6ff64c64 100644
--- a/src/GEOMGUI/GEOM_msg_ja.ts
+++ b/src/GEOMGUI/GEOM_msg_ja.ts
@@ -4755,6 +4755,14 @@
オブジェクトの基準寸法を管理
+
+
+ Show dependency tree
+
+
+
+ Reduce study
+ すべての寸法を表示
@@ -5019,6 +5027,66 @@
プレビュー
+
+
+ Dependency Tree
+
+
+
+ Hierarchy type
+
+
+
+ Display only ascendants tree
+
+
+
+ Display only descendants tree
+
+
+
+ Display both ascendants and descendants trees
+
+
+
+ Possibility to move nodes
+
+
+
+ Color
+
+
+
+ Background color
+
+
+
+ Default node color
+
+
+
+ Main node color
+
+
+
+ Unpublished node color
+
+
+
+ Selected node color
+
+
+
+ Arrow color
+
+
+
+ Highlighted arrow color
+
+
+
+ Selected arrow color
+ サポートされているすべての形式 (%1)
@@ -6801,6 +6869,61 @@
発行し閉じる(&u)
+
+ GEOMToolsGUI_ReduceStudyDlg
+
+
+ Reduce study
+
+
+
+ Objects to be kept
+
+
+
+ Objects to be removed
+
+
+
+ Name
+
+
+
+ Options
+
+
+
+ Intermediate objects
+
+
+
+ Sub-objects
+
+
+
+ Keep
+
+
+
+ Unpublish
+
+
+
+ Remove
+
+
+
+ Remove empty folders
+
+
+
+ Soft removal
+
+
+
+ Do you really want to delete intermediate objects? After applying this operation study will be broken.
+
+ RepairGUI_UnionFacesDlg
diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx
index 48f06c4ad..e8745c0f2 100644
--- a/src/GEOMGUI/GeometryGUI.cxx
+++ b/src/GEOMGUI/GeometryGUI.cxx
@@ -502,6 +502,8 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam )
case GEOMOp::OpClsBringToFront: //
case GEOMOp::OpCreateFolder: // POPUP MENU - CREATE FOLDER
case GEOMOp::OpSortChildren: // POPUP MENU - SORT CHILD ITEMS
+ case GEOMOp::OpShowDependencyTree: // POPUP MENU - SHOW DEPENDENCY TREE
+ case GEOMOp::OpReduceStudy: // POPUP MENU - REDUCE STUDY
libName = "GEOMToolsGUI";
break;
case GEOMOp::OpDMWireframe: // MENU VIEW - WIREFRAME
@@ -1077,6 +1079,8 @@ void GeometryGUI::initialize( CAM_Application* app )
createGeomAction( GEOMOp::OpPredefMaterCustom, "POP_PREDEF_MATER_CUSTOM" );
createGeomAction( GEOMOp::OpCreateFolder, "POP_CREATE_FOLDER" );
createGeomAction( GEOMOp::OpSortChildren, "POP_SORT_CHILD_ITEMS" );
+ createGeomAction( GEOMOp::OpShowDependencyTree, "POP_SHOW_DEPENDENCY_TREE" );
+ createGeomAction( GEOMOp::OpReduceStudy, "POP_REDUCE_STUDY" );
createGeomAction( GEOMOp::OpShowAllDimensions, "POP_SHOW_ALL_DIMENSIONS" );
createGeomAction( GEOMOp::OpHideAllDimensions, "POP_HIDE_ALL_DIMENSIONS" );
@@ -1622,6 +1626,14 @@ void GeometryGUI::initialize( CAM_Application* app )
mgr->insert( action( GEOMOp::OpSortChildren ), -1, -1 ); // Sort child items
mgr->setRule( action( GEOMOp::OpSortChildren ), QString("client='ObjectBrowser' and $component={'GEOM'} and nbChildren>1"), QtxPopupMgr::VisibleRule );
+ mgr->insert( separator(), -1, -1 ); // -----------
+ mgr->insert( action( GEOMOp::OpShowDependencyTree ), -1, -1 ); // Show dependency tree
+ mgr->setRule( action( GEOMOp::OpShowDependencyTree ), clientOCCorVTKorOB + " and selcount>0 and ($component={'GEOM'}) and type='Shape'", QtxPopupMgr::VisibleRule );
+
+ mgr->insert( separator(), -1, -1 ); // -----------
+ mgr->insert( action( GEOMOp::OpReduceStudy ), -1, -1 ); // Reduce Study
+ mgr->setRule( action( GEOMOp::OpReduceStudy ), clientOCCorVTKorOB + " and selcount>0 and ($component={'GEOM'}) and type='Shape'", QtxPopupMgr::VisibleRule );
+
mgr->hide( mgr->actionId( action( myEraseAll ) ) );
SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
@@ -2603,6 +2615,54 @@ void GeometryGUI::createPreferences()
addPreference( tr( "GEOM_PREVIEW" ), operationsGroup,
LightApp_Preferences::Bool, "Geometry", "geom_preview" );
+
+ int DependencyViewId = addPreference( tr( "PREF_TAB_DEPENDENCY_VIEW" ) );
+
+ int treeGeneralGroup = addPreference( tr( "PREF_GROUP_GENERAL" ), DependencyViewId );
+
+ int hierarchy_type = addPreference( tr( "PREF_HIERARCHY_TYPE" ), treeGeneralGroup,
+ LightApp_Preferences::Selector, "Geometry", "dependency_tree_hierarchy_type" );
+
+ QStringList aHierarchyTypeList;
+ aHierarchyTypeList.append( tr("MEN_BOTH_ASCENDANTS_DESCENDANTS") );
+ aHierarchyTypeList.append( tr("MEN_ONLY_ASCENDANTS") );
+ aHierarchyTypeList.append( tr("MEN_ONLY_DESCENDANTS") );
+
+ QList aHierarchyTypeIndexesList;
+ aHierarchyTypeIndexesList.append(0);
+ aHierarchyTypeIndexesList.append(1);
+ aHierarchyTypeIndexesList.append(2);
+
+ setPreferenceProperty( hierarchy_type, "strings", aHierarchyTypeList );
+ setPreferenceProperty( hierarchy_type, "indexes", aHierarchyTypeIndexesList );
+
+ addPreference( tr( "GEOM_MOVE_POSSIBILITY" ), treeGeneralGroup,
+ LightApp_Preferences::Bool, "Geometry", "dependency_tree_move_nodes" );
+
+ int treeColorGroup = addPreference( tr( "PREF_GROUP_DEPENDENCY_VIEW_COLOR" ), DependencyViewId );
+
+ addPreference( tr( "PREF_DEPENDENCY_VIEW_BACKGROUND_COLOR"), treeColorGroup,
+ LightApp_Preferences::Color, "Geometry", "dependency_tree_background_color" );
+
+ addPreference( tr( "PREF_DEPENDENCY_VIEW_NODE_COLOR"), treeColorGroup,
+ LightApp_Preferences::Color, "Geometry", "dependency_tree_node_color" );
+ addPreference( tr( "PREF_DEPENDENCY_VIEW_MAIN_NODE_COLOR"), treeColorGroup,
+ LightApp_Preferences::Color, "Geometry", "dependency_tree_main_node_color" );
+ addPreference( tr( "PREF_DEPENDENCY_VIEW_UNPUBLISH_NODE_COLOR"), treeColorGroup,
+ LightApp_Preferences::Color, "Geometry", "dependency_tree_unpublish_node_color" );
+ addPreference( tr( "PREF_DEPENDENCY_VIEW_SELECT_NODE_COLOR"), treeColorGroup,
+ LightApp_Preferences::Color, "Geometry", "dependency_tree_select_node_color" );
+
+ addPreference( tr( "PREF_DEPENDENCY_VIEW_ARROW_COLOR"), treeColorGroup,
+ LightApp_Preferences::Color, "Geometry", "dependency_tree_arrow_color" );
+ addPreference( tr( "PREF_DEPENDENCY_VIEW_HIGHLIGHT_ARROW_COLOR"), treeColorGroup,
+ LightApp_Preferences::Color, "Geometry", "dependency_tree_highlight_arrow_color" );
+ addPreference( tr( "PREF_DEPENDENCY_VIEW_SELECT_ARROW_COLOR"), treeColorGroup,
+ LightApp_Preferences::Color, "Geometry", "dependency_tree_select_arrow_color" );
+
+
+
+
}
void GeometryGUI::preferencesChanged( const QString& section, const QString& param )
@@ -2673,6 +2733,8 @@ void GeometryGUI::preferencesChanged( const QString& section, const QString& par
aDisplayer.UpdateViewer();
}
+ else if ( param.startsWith( "dependency_tree") )
+ emit SignalDependencyTreeParamChanged( section, param );
}
}
@@ -3226,6 +3288,7 @@ bool GeometryGUI::renameObject( const QString& entry, const QString& name)
GEOM::GEOM_Object_var anObj = GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(obj));
if (!CORBA::is_nil(anObj)) {
anObj->SetName( name.toLatin1().data() ); // Rename the corresponding GEOM_Object
+ emit SignalDependencyTreeRenameObject( anObj->GetEntry() );
}
result = true;
}
diff --git a/src/GEOMGUI/GeometryGUI.h b/src/GEOMGUI/GeometryGUI.h
index 4f28fc928..f2f2ad8e5 100644
--- a/src/GEOMGUI/GeometryGUI.h
+++ b/src/GEOMGUI/GeometryGUI.h
@@ -182,6 +182,8 @@ signals :
void SignalDeactivateActiveDialog();
void SignalCloseAllDialogs();
void SignalDefaultStepValueChanged( double newVal );
+ void SignalDependencyTreeParamChanged( const QString&, const QString& );
+ void SignalDependencyTreeRenameObject( const QString& );
protected:
virtual LightApp_Selection* createSelection() const;
diff --git a/src/GEOMGUI/GeometryGUI_Operations.h b/src/GEOMGUI/GeometryGUI_Operations.h
index 1f2dc8186..5a33af0dc 100644
--- a/src/GEOMGUI/GeometryGUI_Operations.h
+++ b/src/GEOMGUI/GeometryGUI_Operations.h
@@ -61,6 +61,8 @@ namespace GEOMOp {
OpIsosWidth = 1261, // POPUP MENU - LINE WIDTH - ISOS WIDTH
OpCreateFolder = 1262, // POPUP MENU - CREATE FOLDER
OpSortChildren = 1263, // POPUP MENU - SORT CHILD ITEMS
+ OpShowDependencyTree = 1264, // POPUP MENU - SHOW DEPENDENCY TREE
+ OpReduceStudy = 1265, // POPUP MENU - REDUCE STUDY
// DisplayGUI ------------------//--------------------------------
OpSwitchVectors = 2001, // MENU VIEW - DISPLAY MODE - SHOW/HIDE EDGE DIRECTION
OpShowAll = 2002, // MENU VIEW - SHOW ALL
diff --git a/src/GEOMToolsGUI/CMakeLists.txt b/src/GEOMToolsGUI/CMakeLists.txt
index 143d07826..fe6a01b4e 100755
--- a/src/GEOMToolsGUI/CMakeLists.txt
+++ b/src/GEOMToolsGUI/CMakeLists.txt
@@ -38,6 +38,8 @@ INCLUDE_DIRECTORIES(
${PROJECT_SOURCE_DIR}/src/GEOMGUI
${PROJECT_SOURCE_DIR}/src/GEOMBase
${PROJECT_SOURCE_DIR}/src/Material
+ ${PROJECT_SOURCE_DIR}/src/DependencyTree
+ ${PROJECT_SOURCE_DIR}/src/GEOMUtils
${CMAKE_CURRENT_SOURCE_DIR}
)
@@ -56,6 +58,7 @@ SET(_link_LIBRARIES
GEOM
GEOMBase
Material
+ DependencyTree
)
# --- headers ---
@@ -71,6 +74,7 @@ SET(GEOMToolsGUI_HEADERS
GEOMToolsGUI_PublishDlg.h
GEOMToolsGUI_MaterialPropertiesDlg.h
GEOMToolsGUI_LineWidthDlg.h
+ GEOMToolsGUI_ReduceStudyDlg.h
)
# header files / to be processed by moc
@@ -83,6 +87,7 @@ SET(_moc_HEADERS
GEOMToolsGUI_PublishDlg.h
GEOMToolsGUI_MaterialPropertiesDlg.h
GEOMToolsGUI_LineWidthDlg.h
+ GEOMToolsGUI_ReduceStudyDlg.h
)
# --- sources ---
@@ -101,6 +106,7 @@ SET(GEOMToolsGUI_SOURCES
GEOMToolsGUI_PublishDlg.cxx
GEOMToolsGUI_MaterialPropertiesDlg.cxx
GEOMToolsGUI_LineWidthDlg.cxx
+ GEOMToolsGUI_ReduceStudyDlg.cxx
${_moc_SOURCES}
)
diff --git a/src/GEOMToolsGUI/GEOMToolsGUI.cxx b/src/GEOMToolsGUI/GEOMToolsGUI.cxx
index daf888e2d..0c514cb78 100644
--- a/src/GEOMToolsGUI/GEOMToolsGUI.cxx
+++ b/src/GEOMToolsGUI/GEOMToolsGUI.cxx
@@ -422,7 +422,13 @@ bool GEOMToolsGUI::OnGUIEvent(int theCommandID, SUIT_Desktop* parent)
break;
case GEOMOp::OpSortChildren:
OnSortChildren();
+ break;
+ case GEOMOp::OpShowDependencyTree:
+ OnShowDependencyTree();
break;
+ case GEOMOp::OpReduceStudy:
+ OnReduceStudy();
+ break;
default:
SUIT_Session::session()->activeApplication()->putInfo(tr("GEOM_PRP_COMMAND").arg(theCommandID));
break;
diff --git a/src/GEOMToolsGUI/GEOMToolsGUI.h b/src/GEOMToolsGUI/GEOMToolsGUI.h
index 683fffc7c..4ed7f9495 100644
--- a/src/GEOMToolsGUI/GEOMToolsGUI.h
+++ b/src/GEOMToolsGUI/GEOMToolsGUI.h
@@ -90,6 +90,8 @@ private:
void OnClsBringToFront();
void OnCreateFolder();
void OnSortChildren();
+ void OnShowDependencyTree();
+ void OnReduceStudy();
// Shortcut commands
void OnChangeTransparency( bool );
diff --git a/src/GEOMToolsGUI/GEOMToolsGUI_1.cxx b/src/GEOMToolsGUI/GEOMToolsGUI_1.cxx
index ea5f7b1c9..2ca503aae 100644
--- a/src/GEOMToolsGUI/GEOMToolsGUI_1.cxx
+++ b/src/GEOMToolsGUI/GEOMToolsGUI_1.cxx
@@ -34,6 +34,7 @@
#include "GEOMToolsGUI_PublishDlg.h"
#include "GEOMToolsGUI_MaterialPropertiesDlg.h"
#include "GEOMToolsGUI_LineWidthDlg.h"
+#include "GEOMToolsGUI_ReduceStudyDlg.h"
#include
#include
@@ -46,6 +47,10 @@
#include
#include
+#include
+#include
+#include
+
#include
#include
@@ -862,3 +867,43 @@ void GEOMToolsGUI::OnSortChildren()
app->updateObjectBrowser( true );
}
+
+void GEOMToolsGUI::OnShowDependencyTree()
+{
+ SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+
+ SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
+ if ( !app ) return;
+
+ SUIT_ViewManager *svm = app->getViewManager( GraphicsView_Viewer::Type(), false );
+
+ if( !svm ) {
+ DependencyTree_View* view = new DependencyTree_View();
+ DependencyTree_ViewModel* viewModel = new DependencyTree_ViewModel( GraphicsView_Viewer::Type(), view );
+ SUIT_ViewManager *svm = app->createViewManager( viewModel );
+
+ LightApp_SelectionMgr* selMgr = app->selectionMgr();
+ new DependencyTree_Selector( viewModel, (SUIT_SelectionMgr*)selMgr );
+
+ SUIT_ViewWindow* svw = svm->getActiveView();
+ GraphicsView_ViewFrame* aViewFrame = 0;
+ if (!svw) svw = svm->createViewWindow();
+ if (svw) aViewFrame = dynamic_cast(svw);
+
+ view->init( aViewFrame );
+ svm->setTitle( view->getViewName() );
+ }
+ else
+ if( DependencyTree_ViewModel* viewModel = dynamic_cast( svm->getViewModel() ) )
+ if( DependencyTree_View* view = dynamic_cast( viewModel->getActiveViewPort() ) ) {
+ svm->getActiveView()->setFocus();
+ view->updateModel();
+ }
+}
+
+void GEOMToolsGUI::OnReduceStudy()
+{
+ QDialog* dlg = new GEOMToolsGUI_ReduceStudyDlg( SUIT_Session::session()->activeApplication()->desktop() );
+ if( dlg != NULL )
+ dlg->show();
+}
diff --git a/src/GEOMToolsGUI/GEOMToolsGUI_ReduceStudyDlg.cxx b/src/GEOMToolsGUI/GEOMToolsGUI_ReduceStudyDlg.cxx
new file mode 100644
index 000000000..4fa9d4efa
--- /dev/null
+++ b/src/GEOMToolsGUI/GEOMToolsGUI_ReduceStudyDlg.cxx
@@ -0,0 +1,727 @@
+// Copyright (C) 2014 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// internal includes
+#include "GEOMToolsGUI_ReduceStudyDlg.h"
+
+// GEOM includes
+#include
+
+// GUI includes
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+
+// Qt includes
+#include
+#include
+#include
+#include
+#include
+
+GEOMToolsGUI_ReduceStudyDlg::GEOMToolsGUI_ReduceStudyDlg( QWidget* parent )
+:QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
+myDisplayer(NULL)
+{
+ SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+ myVisible = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) );
+ myInvisible = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) ) );
+
+ myApp = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
+ if ( !myApp ) return;
+ SalomeApp_Study* study = dynamic_cast( myApp->activeStudy() );
+ myStudy = dynamic_cast( myApp->activeStudy() )->studyDS();
+ myDisplayer = GEOM_Displayer( study );
+
+ setWindowTitle( tr( "GEOM_REDUCE_STUDY_TITLE" ) );
+ setAttribute(Qt::WA_DeleteOnClose);
+
+ QGridLayout* topLayout = new QGridLayout( this );
+ topLayout->setMargin( 11 ); topLayout->setSpacing( 6 );
+
+ /********************** Objects to be kept **********************/
+ QGroupBox* groupKeptObjects = new QGroupBox( tr( "GEOM_REDUCE_STUDY_KEPT_OBJECTS" ) );
+ QGridLayout* layoutKeptObjects = new QGridLayout( groupKeptObjects );
+ createTreeWidget( myTreeKeptObjects = new QTreeWidget() );
+ layoutKeptObjects->addWidget( myTreeKeptObjects );
+
+ /********************** Objects to be removed **********************/
+ QGroupBox* groupRemoveObjects = new QGroupBox( tr( "GEOM_REDUCE_STUDY_REMOVE_OBJECTS" ) );
+ QGridLayout* layoutRemoveObjects = new QGridLayout( groupRemoveObjects );
+ createTreeWidget( myTreeRemoveObjects = new QTreeWidget() );
+ layoutRemoveObjects->addWidget( myTreeRemoveObjects );
+
+ /********************** Options **********************/
+ QGroupBox* groupOptions = new QGroupBox( tr( "GEOM_REDUCE_STUDY_OPTIONS" ) );
+ QVBoxLayout* layoutOptions = new QVBoxLayout( groupOptions );
+
+ // Intermediate objects
+ QGroupBox* groupIntermediates = createButtonGroup( myGroupIntermediates = new QButtonGroup() );
+ groupIntermediates->setTitle( tr( "GEOM_REDUCE_STUDY_INTERMEDIATES" ) );
+
+ // Sub-objects
+ QGroupBox* groupSubObjects = createButtonGroup( myGroupSubObjects = new QButtonGroup() );
+ groupSubObjects->setTitle( tr( "GEOM_REDUCE_STUDY_SUB_OBJECTS" ) );
+
+ // Others
+ myCBRemoveEmptyFolder = new QCheckBox( tr( "GEOM_REDUCE_STUDY_REMOVE_EMPTY_FOLDER" ) );
+ myCBRemoveEmptyFolder->setChecked( true );
+ myCBSoftRemoval = new QCheckBox( tr( "GEOM_REDUCE_STUDY_SOFT_REMOVAL" ) );
+
+ layoutOptions->addWidget( groupIntermediates );
+ layoutOptions->addWidget( groupSubObjects );
+ layoutOptions->addWidget( myCBRemoveEmptyFolder );
+ layoutOptions->addWidget( myCBSoftRemoval );
+
+ /********************** Buttons **********************/
+ QGroupBox* groupButtons = new QGroupBox();
+ QHBoxLayout* layoutButtons = new QHBoxLayout( groupButtons );
+
+ QPushButton* buttonOk = new QPushButton( tr( "GEOM_BUT_OK" ) );
+ QPushButton* buttonCancel = new QPushButton( tr( "GEOM_BUT_CANCEL" ) );
+ QPushButton* buttonHelp = new QPushButton( tr( "GEOM_BUT_HELP" ) );
+
+ layoutButtons->addWidget( buttonOk );
+ layoutButtons->addStretch();
+ layoutButtons->addWidget( buttonCancel );
+ layoutButtons->addWidget( buttonHelp );
+
+ topLayout->addWidget( groupKeptObjects, 0, 0 );
+ topLayout->addWidget( groupRemoveObjects, 0, 1 );
+ topLayout->addWidget( groupOptions, 1, 0, 1, 2 );
+ topLayout->addWidget( groupButtons, 2, 0, 1, 2 );
+
+ // Signals and slots connections
+
+ connect( myTreeKeptObjects, SIGNAL( itemClicked( QTreeWidgetItem*, int) ), this, SLOT( onItemClicked( QTreeWidgetItem*, int ) ) );
+ connect( myTreeRemoveObjects, SIGNAL( itemClicked( QTreeWidgetItem*, int) ), this, SLOT( onItemClicked( QTreeWidgetItem*, int ) ) );
+ connect( myTreeKeptObjects->header(), SIGNAL( sectionClicked ( int ) ), this, SLOT( onHeaderClicked( int ) ) );
+ connect( myTreeRemoveObjects->header(), SIGNAL( sectionClicked ( int ) ), this, SLOT( onHeaderClicked( int ) ) );
+
+ connect( myGroupIntermediates, SIGNAL( buttonClicked( int ) ), this, SLOT( update() ) );
+ connect( myGroupSubObjects, SIGNAL( buttonClicked( int ) ), this, SLOT( update() ) );
+
+ connect( buttonOk, SIGNAL( clicked() ), this, SLOT( clickOnOk() ) );
+ connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
+ connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( clickOnHelp() ) );
+
+ connect( myApp->selectionMgr(), SIGNAL( currentSelectionChanged() ),
+ this, SLOT( selectionChanged() ) );
+
+ init( getSelectedObjects() );
+}
+
+GEOMToolsGUI_ReduceStudyDlg::~GEOMToolsGUI_ReduceStudyDlg()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+//=================================================================================
+// function : init()
+// purpose : initialize dialog data
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::init( const std::set& theObjectEntries )
+{
+ myMainEntries.clear();
+
+ myKeptObjects.clear();
+ myListParents.clear();
+ myListSubObjects.clear();
+ myRemovedObjects.clear();
+
+ myMainEntries = theObjectEntries;
+
+ GEOM::string_array_var keptObjects = new GEOM::string_array();
+ int It = 0;
+ keptObjects->length( theObjectEntries.size() );
+ std::set::iterator iter;
+ for( iter=theObjectEntries.begin(); iter!=theObjectEntries.end(); ++iter, It++ )
+ keptObjects[ It ] = (*iter).c_str();
+
+ GEOM::string_array_var parentsObjects = new GEOM::string_array();
+ GEOM::string_array_var subObjects = new GEOM::string_array();
+ GEOM::string_array_var otherObjects = new GEOM::string_array();
+
+ GeometryGUI::GetGeomGen()->GetEntriesToReduceStudy( GeometryGUI::ClientStudyToStudy( myStudy ),
+ keptObjects, parentsObjects,
+ subObjects, otherObjects );
+
+ for ( int i = 0; i < keptObjects->length(); i++ )
+ myKeptObjects.insert( keptObjects[i].in() );
+ for( int i = 0; i< otherObjects->length(); i++ )
+ myRemovedObjects.insert( otherObjects[i].in() );
+ for( int i = 0; i< parentsObjects->length(); i++ )
+ myListParents.insert( parentsObjects[i].in() );
+ for( int i = 0; i< subObjects->length(); i++ )
+ myListSubObjects.insert( subObjects[i].in() );
+
+ update();
+
+ checkVisibleIcon( myTreeKeptObjects );
+ checkVisibleIcon( myTreeRemoveObjects );
+}
+
+//=================================================================================
+// function : getSelectedObjects()
+// purpose : get selected objects in object browser
+//=================================================================================
+std::set GEOMToolsGUI_ReduceStudyDlg::getSelectedObjects() const
+{
+ std::set objects;
+
+ SALOME_ListIO selected;
+ myApp->selectionMgr()->selectedObjects( selected );
+
+ for( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
+ Handle( SALOME_InteractiveObject ) io = It.Value();
+ if( !io->hasEntry() )
+ continue;
+ GEOM::GEOM_Object_var geomObject = GEOM::GEOM_Object::_nil();
+ geomObject = GEOMBase::ConvertIOinGEOMObject( io );
+ if( geomObject->_is_nil() )
+ continue;
+ QString entry = geomObject->GetEntry();
+ objects.insert( entry.toStdString().c_str() );
+ }
+ return objects;
+}
+
+//=================================================================================
+// function : createTreeWidget()
+// purpose : create tree widget for unpublished or removed objects
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::createTreeWidget( QTreeWidget* theTreeWidget )
+{
+ theTreeWidget->setColumnCount( 2 );
+ QStringList columnNames;
+ columnNames.append(tr( "GEOM_REDUCE_STUDY_NAME" ));
+ columnNames.append("");
+ theTreeWidget->setHeaderLabels( columnNames );
+ QTreeWidgetItem * headerItem = new QTreeWidgetItem( columnNames );
+ theTreeWidget->setHeaderItem ( headerItem );
+ theTreeWidget->header()->moveSection( 1, 0 );
+ theTreeWidget->header()->setClickable( true );
+ theTreeWidget->header()->setMovable( false );
+ theTreeWidget->header()->setResizeMode( 1, QHeaderView::ResizeToContents );
+ theTreeWidget->setSelectionMode( QAbstractItemView::ExtendedSelection );
+}
+
+//=================================================================================
+// function : createButtonGroup()
+// purpose : create button group for intermediate objects or sub-objects
+//=================================================================================
+QGroupBox* GEOMToolsGUI_ReduceStudyDlg::createButtonGroup( QButtonGroup* theButtonGroup )
+{
+ QGroupBox* groupObjects = new QGroupBox();
+ QHBoxLayout* layoutObjects = new QHBoxLayout( groupObjects );
+
+ QRadioButton* buttonKeep = new QRadioButton( tr( "GEOM_REDUCE_STUDY_KEEP") );
+ theButtonGroup->addButton( buttonKeep, 0 );
+ QRadioButton* buttonUnpublish = new QRadioButton( tr( "GEOM_REDUCE_STUDY_UNPUBLISH") );
+ theButtonGroup->addButton( buttonUnpublish, 1 );
+ QRadioButton* buttonRemove = new QRadioButton( tr( "GEOM_REDUCE_STUDY_REMOVE") );
+ theButtonGroup->addButton( buttonRemove, 2 );
+
+ theButtonGroup->button( 0 )->setChecked( true );
+ theButtonGroup->setExclusive( true );
+
+ layoutObjects->addWidget( buttonKeep );
+ layoutObjects->addWidget( buttonUnpublish );
+ layoutObjects->addWidget( buttonRemove );
+
+ return groupObjects;
+}
+
+//=================================================================================
+// function : addObjectsToTree()
+// purpose : add the list of objects to tree
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::addObjectsToTree( QTreeWidget* theWidget, std::set& theObjects )
+{
+ std::set::iterator it;
+ for( it = theObjects.begin(); it != theObjects.end(); ++it ) {
+ std::string objectEntry = *it;
+ GEOM::GEOM_BaseObject_var GeomBaseObject = GeometryGUI::GetGeomGen()->GetObject( myStudy->StudyId(), objectEntry.c_str() );
+ GEOM::GEOM_Object_var GeomObject = GEOM::GEOM_Object::_narrow( GeomBaseObject );
+ QString studyEntry = GeomBaseObject->GetStudyEntry();
+ if( GeomObject->_is_nil() || studyEntry.isEmpty() || !isObjectDrawable( studyEntry.toStdString() ) )
+ continue;
+ addSubObject( theWidget, theObjects, GeomObject );
+ }
+}
+
+//=================================================================================
+// function : addSubObject()
+// purpose : add sub-object to parent object in the tree
+//=================================================================================
+GEOMToolsGUI_TreeWidgetItem* GEOMToolsGUI_ReduceStudyDlg::addSubObject( QTreeWidget* theWidget,
+ std::set& theObjects,
+ GEOM::GEOM_Object_var theObject )
+{
+ GEOMToolsGUI_TreeWidgetItem* item;
+ if( !theObject->IsMainShape() ) {
+ GEOMToolsGUI_TreeWidgetItem* parentItem = addSubObject( theWidget, theObjects, theObject->GetMainShape() );
+ item = findObjectInTree( theWidget, theObject );
+ if( !item )
+ item = new GEOMToolsGUI_TreeWidgetItem( parentItem, QStringList() << theObject->GetName(), theObject->GetStudyEntry() );
+ }
+ else {
+ item = findObjectInTree( theWidget, theObject );
+ if( !item )
+ item = new GEOMToolsGUI_TreeWidgetItem( theWidget, QStringList() << theObject->GetName(), theObject->GetStudyEntry() );
+ }
+
+ bool isDisplayed = false;
+ if( theObjects.find( theObject->GetEntry() ) != theObjects.end() ) {
+ isDisplayed = myDisplayer.IsDisplayed( theObject->GetStudyEntry() );
+ if ( isDisplayed )
+ item->setVisible( true, myVisible );
+ else
+ item->setVisible( false, myInvisible );
+
+ if( myMainEntries.find( theObject->GetEntry() ) != myMainEntries.end() ) {
+ QFont Textfont = item->font(0);
+ Textfont.setBold( true );
+ item->setFont( 0, Textfont );
+ }
+ }
+ else {
+ item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
+ item->setTextColor( 0, QColor( 150, 150, 150 ) );
+ }
+ return item;
+}
+
+//=================================================================================
+// function : findObjectInTree()
+// purpose : find object in the tree
+//=================================================================================
+GEOMToolsGUI_TreeWidgetItem* GEOMToolsGUI_ReduceStudyDlg::findObjectInTree( QTreeWidget* theWidget, GEOM::GEOM_Object_var theObject )
+{
+ QTreeWidgetItemIterator it( theWidget );
+ while(*it) {
+ GEOMToolsGUI_TreeWidgetItem* item = dynamic_cast(*it);
+ if( QString( item->getStudyEntry() ) == QString( theObject->GetStudyEntry() ) )
+ return item;
+ ++it;
+ }
+ return NULL;
+}
+
+//=================================================================================
+// function : checkVisibleIcon()
+// purpose : set visible or invisible icon in the header of tree
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::checkVisibleIcon( QTreeWidget* theWidget )
+{
+ bool isInvisible = false;
+ QTreeWidgetItemIterator it( theWidget );
+ while(*it) {
+ GEOMToolsGUI_TreeWidgetItem* item = dynamic_cast(*it);
+ const char* entry = item->getStudyEntry();
+ if( item->flags() & Qt::ItemIsSelectable )
+ if( !item->isVisible() )
+ isInvisible = true;
+ ++it;
+ }
+
+ if( isInvisible ) {
+ theWidget->headerItem()->setIcon( 1, myInvisible );
+ myMapTreeSelectAll[ theWidget ] = false;
+ }
+ else {
+ theWidget->headerItem()->setIcon( 1, myVisible );
+ myMapTreeSelectAll[ theWidget ] = true;
+ }
+}
+
+//=================================================================================
+// function : isObjectDrawable()
+// purpose : return true if object is drawable, and false if object is hidden in the study
+//=================================================================================
+bool GEOMToolsGUI_ReduceStudyDlg::isObjectDrawable( std::string theStudyEntry )
+{
+ _PTR(StudyBuilder) aStudyBuilder = myStudy->NewBuilder();
+ //If object hasn't "AttributeDrawable" => it visible
+ bool isDrawable = true;
+ _PTR(SObject) SO ( myStudy->FindObjectID( theStudyEntry ) );
+ _PTR(GenericAttribute) anAttr;
+ if ( SO && SO->FindAttribute( anAttr, "AttributeDrawable" ) ) {
+ _PTR(AttributeDrawable) aDrw (anAttr);
+ isDrawable = aDrw->IsDrawable();
+ }
+ return isDrawable;
+}
+
+//=================================================================================
+// function : unpublishObjects()
+// purpose : unpublish(hide) objects in the study
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::unpublishObjects( std::set& theObjects )
+{
+ _PTR(StudyBuilder) aStudyBuilder = myStudy->NewBuilder();
+ std::set::iterator it;
+ for( it = theObjects.begin(); it != theObjects.end(); ++it ) {
+ std::string objectEntry = *it;
+ GEOM::GEOM_BaseObject_var GeomBaseObject = GeometryGUI::GetGeomGen()->GetObject( myStudy->StudyId(),
+ objectEntry.c_str() );
+ std::string studyEntry = GeomBaseObject->GetStudyEntry();
+ if ( studyEntry == "" || !isObjectDrawable( studyEntry ) )
+ continue;
+ _PTR(SObject) obj ( myStudy->FindObjectID( studyEntry.c_str() ) );
+ _PTR(GenericAttribute) anAttr;
+ if ( obj ) {
+ _PTR(AttributeDrawable) aDrw = aStudyBuilder->FindOrCreateAttribute( obj, "AttributeDrawable" );
+ aDrw->SetDrawable( false );
+ myDisplayer.EraseWithChildren( new SALOME_InteractiveObject( studyEntry.c_str(), "GEOM", "TEMP_IO" ) );
+ }
+ }
+ myApp->updateObjectBrowser( false );
+ myApp->updateActions();
+}
+
+//=================================================================================
+// function : removeObjects()
+// purpose : remove objects from the study
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::removeObjects( std::set& theObjects )
+{
+ std::set::iterator it;
+ for( it = theObjects.begin(); it != theObjects.end(); ++it ) {
+ std::string objectEntry = *it;
+ GEOM::GEOM_BaseObject_var GeomBaseObject = GeometryGUI::GetGeomGen()->GetObject( myStudy->StudyId(),
+ objectEntry.c_str() );
+ std::string studyEntry = GeomBaseObject->GetStudyEntry();
+ if ( studyEntry == "" )
+ GeometryGUI::GetGeomGen()->RemoveObject( GeomBaseObject );
+ else {
+ if( !isObjectDrawable( studyEntry ) )
+ continue;
+ removeObject( studyEntry );
+ }
+ }
+ myApp->updateObjectBrowser( false );
+ myApp->updateActions();
+}
+
+//=================================================================================
+// function : removeObject()
+// purpose : remove object with given study entry
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::removeObject( std::string& theStudyEntry )
+{
+ SalomeApp_Study* appStudy = dynamic_cast( myApp->activeStudy() );
+ _PTR(StudyBuilder) aStudyBuilder = myStudy->NewBuilder();
+ _PTR(UseCaseBuilder) aUseCaseBuilder = myStudy->GetUseCaseBuilder();
+
+ _PTR(SObject) obj ( myStudy->FindObjectID( theStudyEntry.c_str() ) );
+ if ( obj ) {
+ // remove visual properties of the object
+ appStudy->removeObjectFromAll(obj->GetID().c_str());
+ // remove references to this object
+ appStudy->deleteReferencesTo( obj );
+ // remove objects from study
+ aStudyBuilder->RemoveObjectWithChildren( obj );
+ // remove object from use case tree
+ aUseCaseBuilder->Remove( obj );
+ myDisplayer.EraseWithChildren( new SALOME_InteractiveObject( theStudyEntry.c_str(), "GEOM", "TEMP_IO" ) );
+ }
+}
+
+//=================================================================================
+// function : removeEmptyFolders()
+// purpose : remove empty folders from the study
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::removeEmptyFolders()
+{
+ std::set emptyFolders;
+
+ _PTR(SComponent) SC ( myStudy->FindComponent( "GEOM" ) );
+ if ( !SC )
+ return;
+ _PTR(ChildIterator) anIter ( myStudy->NewChildIterator( SC ) );
+ anIter->InitEx( true );
+ while( anIter->More() ) {
+ _PTR(SObject) valSO ( anIter->Value() );
+ _PTR(SObject) refSO;
+ if ( !valSO->ReferencedObject( refSO ) )
+ getEmptyFolders( valSO, emptyFolders );
+ anIter->Next();
+ }
+
+ std::set::iterator iter;
+ for( iter = emptyFolders.begin(); iter != emptyFolders.end(); ++iter ) {
+ std::string studyEntry = *iter;
+ removeObject( studyEntry );
+ }
+ myApp->updateObjectBrowser( false );
+ myApp->updateActions();
+}
+
+//=================================================================================
+// function : removeEmptyFolders()
+// purpose : remove empty folders from the study
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::getEmptyFolders( _PTR(SObject) theSO, std::set& theFolders )
+{
+ _PTR(UseCaseBuilder) aUseCaseBuilder = myStudy->GetUseCaseBuilder();
+
+ bool isFolder = false;
+ _PTR(GenericAttribute) anAttr;
+ if ( theSO->FindAttribute(anAttr, "AttributeLocalID") ) {
+ _PTR(AttributeLocalID) aLocalID( anAttr );
+ isFolder = aLocalID->Value() == 999;
+ }
+ QString studyEntry = theSO->GetID().c_str();
+ if ( isFolder ) {
+ if( !aUseCaseBuilder->HasChildren( theSO ) )
+ theFolders.insert( studyEntry.toStdString() );
+ else {
+ _PTR(UseCaseIterator) ucit ( aUseCaseBuilder->GetUseCaseIterator( theSO ) );
+ for ( ucit->Init( false ); ucit->More(); ucit->Next() )
+ getEmptyFolders( ucit->Value(), theFolders );
+ }
+ }
+}
+
+//=================================================================================
+// function : onItemClicked()
+// purpose : called when tree item was clicked
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::onItemClicked( QTreeWidgetItem* theItem, int theColumn )
+{
+ if( theColumn != 1 || !( theItem->flags() & Qt::ItemIsSelectable ) )
+ return;
+
+ GEOMToolsGUI_TreeWidgetItem* item = dynamic_cast( theItem );
+
+ const char* entry = item->getStudyEntry();
+ Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject( entry, "GEOM", "TEMP_IO" );
+ if( myDisplayer.IsDisplayed( entry ) ) {
+ item->setVisible( false, myInvisible );
+ myDisplayer.Erase( io );
+ }
+ else {
+ item->setVisible( true, myVisible );
+ myDisplayer.Display( io );
+ }
+ myDisplayer.UpdateViewer();
+ checkVisibleIcon( item->treeWidget() );
+}
+
+//=================================================================================
+// function : onHeaderClicked()
+// purpose : called when header item of tree was clicked
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::onHeaderClicked( int theColumn )
+{
+ if( theColumn != 1 )
+ return;
+
+ QTreeWidget* treeWidget = dynamic_cast(sender()->parent());
+ if( myMapTreeSelectAll[ treeWidget ] ) {
+ myMapTreeSelectAll[ treeWidget ] = false;
+ treeWidget->headerItem()->setIcon( 1, myInvisible );
+ QTreeWidgetItemIterator it( treeWidget );
+ while(*it) {
+ GEOMToolsGUI_TreeWidgetItem* item = dynamic_cast(*it);
+ if( ( item->flags() & Qt::ItemIsSelectable ) && item->isVisible() ) {
+ const char* entry = item->getStudyEntry();
+ item->setVisible( false, myInvisible );
+ myDisplayer.Erase( new SALOME_InteractiveObject( entry, "GEOM", "TEMP_IO" ) );
+ }
+ ++it;
+ }
+ }
+ else {
+ myMapTreeSelectAll[ treeWidget ] = true;
+ treeWidget->headerItem()->setIcon( 1, myVisible );
+ QTreeWidgetItemIterator it( treeWidget );
+ while(*it) {
+ GEOMToolsGUI_TreeWidgetItem* item = dynamic_cast(*it);
+ if( ( item->flags() & Qt::ItemIsSelectable ) && !item->isVisible() ) {
+ const char* entry = item->getStudyEntry();
+ item->setVisible( true, myVisible );
+ myDisplayer.Display( new SALOME_InteractiveObject( entry, "GEOM", "TEMP_IO" ) );
+ }
+ ++it;
+ }
+ }
+ myDisplayer.UpdateViewer();
+}
+
+//=================================================================================
+// function : selectionChanged()
+// purpose : called when selection of object browser was changed
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::selectionChanged()
+{
+ init( getSelectedObjects() );
+}
+
+//=================================================================================
+// function : update()
+// purpose : update tree data
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::update()
+{
+ myTreeKeptObjects->clear();
+ myTreeRemoveObjects->clear();
+
+ std::set keptObjects( myKeptObjects );
+ std::set removeObjects( myRemovedObjects );
+
+ // Intermediate objects
+ if( myGroupIntermediates->checkedId() == 2 ) { // remove
+ std::set::iterator iter;
+ for( iter=myListParents.begin(); iter!=myListParents.end(); ++iter)
+ removeObjects.insert( *iter );
+ }
+ else { // keep or unpublish
+ std::set::iterator iter;
+ for( iter=myListParents.begin(); iter!=myListParents.end(); ++iter)
+ keptObjects.insert( *iter );
+ }
+
+ // Sub-objects
+ if( myGroupSubObjects->checkedId() == 2 ) {
+ std::set::iterator iter;
+ for( iter=myListSubObjects.begin(); iter!=myListSubObjects.end(); ++iter)
+ removeObjects.insert( *iter );
+ }
+ else {
+ std::set::iterator iter;
+ for( iter=myListSubObjects.begin(); iter!=myListSubObjects.end(); ++iter)
+ keptObjects.insert( *iter );
+ }
+
+ addObjectsToTree( myTreeKeptObjects, keptObjects );
+ addObjectsToTree( myTreeRemoveObjects, removeObjects );
+
+ myTreeKeptObjects->collapseAll();
+ myTreeRemoveObjects->collapseAll();
+
+}
+
+//=================================================================================
+// function : clickOnOk()
+// purpose : called when OK button was clicked
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::clickOnOk()
+{
+ std::set objectsToBeRemoved = myRemovedObjects;
+ std::set objectsToBeUnpublished;
+
+ // Create lists of intermediate objects to be removed or to be unpublished
+ std::set::iterator iter;
+ if( myGroupIntermediates->checkedId() == 1 ) { // unpublish
+ for( iter = myListParents.begin(); iter != myListParents.end(); ++iter )
+ objectsToBeUnpublished.insert( *iter );
+ }
+ if( myGroupIntermediates->checkedId() == 2 ) { // remove
+ if( !myCBSoftRemoval->isChecked() &&
+ SUIT_MessageBox::question( this,
+ tr( "GEOM_WRN_WARNING" ),
+ tr( "GEOM_REDUCE_STUDY_WARNING_DELETE" ),
+ QMessageBox::Yes | QMessageBox::No,
+ QMessageBox::Yes ) == QMessageBox::No ) {
+ return;
+ }
+ for( iter = myListParents.begin(); iter != myListParents.end(); ++iter )
+ objectsToBeRemoved.insert( *iter );
+ }
+
+ // Create lists of sub-objects to be removed or to be unpublished
+ if( myGroupSubObjects->checkedId() == 1 ) { // unpublish
+ for( iter = myListSubObjects.begin(); iter != myListSubObjects.end(); ++iter )
+ objectsToBeUnpublished.insert( *iter );
+ }
+ else if( myGroupSubObjects->checkedId() == 2 ) { // remove
+ for( iter = myListSubObjects.begin(); iter != myListSubObjects.end(); ++iter )
+ objectsToBeRemoved.insert( *iter );
+ }
+
+ // if user chosen the soft removal
+ if( myCBSoftRemoval->isChecked() ) {
+ for( iter = objectsToBeRemoved.begin(); iter != objectsToBeRemoved.end(); ++iter )
+ objectsToBeUnpublished.insert( *iter );
+ unpublishObjects( objectsToBeUnpublished );
+ }
+ else {
+ unpublishObjects( objectsToBeUnpublished );
+ removeObjects( objectsToBeRemoved );
+ }
+
+ // if user want to delete the empty folders
+ if( myCBRemoveEmptyFolder->isChecked() )
+ removeEmptyFolders();
+
+ accept();
+}
+
+//=================================================================================
+// function : clickOnHelp()
+// purpose : called when Help button was clicked to open a help page
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::clickOnHelp()
+{
+ myApp->onHelpContextModule( "GEOM", "reduce_study_page.html" );
+}
+
+GEOMToolsGUI_TreeWidgetItem::GEOMToolsGUI_TreeWidgetItem( QTreeWidget* view, const QStringList &strings,
+ char* studyEntry, int type )
+:QTreeWidgetItem( view, strings, type ),
+ myStudyEntry( studyEntry ),
+ myVisible( false )
+{
+}
+
+GEOMToolsGUI_TreeWidgetItem::GEOMToolsGUI_TreeWidgetItem( QTreeWidgetItem* parent, const QStringList &strings,
+ char* studyEntry, int type )
+:QTreeWidgetItem( parent, strings, type ),
+ myStudyEntry( studyEntry ),
+ myVisible( false )
+{
+}
+
+GEOMToolsGUI_TreeWidgetItem::~GEOMToolsGUI_TreeWidgetItem()
+{
+}
+
+bool GEOMToolsGUI_TreeWidgetItem::isVisible()
+{
+ return myVisible;
+}
+
+void GEOMToolsGUI_TreeWidgetItem::setVisible( bool theIsVisible, QIcon& theIcon )
+{
+ myVisible = theIsVisible;
+ setIcon( 1, theIcon );
+}
+
+char* GEOMToolsGUI_TreeWidgetItem::getStudyEntry() const
+{
+ return myStudyEntry;
+}
diff --git a/src/GEOMToolsGUI/GEOMToolsGUI_ReduceStudyDlg.h b/src/GEOMToolsGUI/GEOMToolsGUI_ReduceStudyDlg.h
new file mode 100644
index 000000000..ce69292e8
--- /dev/null
+++ b/src/GEOMToolsGUI/GEOMToolsGUI_ReduceStudyDlg.h
@@ -0,0 +1,127 @@
+// Copyright (C) 2014 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef GEOMTOOLSGUI_REDUCESTUDYDLG_H
+#define GEOMTOOLSGUI_REDUCESTUDYDLG_H
+
+// internal includes
+#include "GEOM_ToolsGUI.hxx"
+
+// GEOM includes
+#include
+#include
+#include
+
+// Qt includes
+#include
+#include
+#include
+#include
+#include
+
+// Cpp includes
+#include
+
+class GEOMToolsGUI_TreeWidgetItem : public QTreeWidgetItem
+{
+
+public:
+ GEOMToolsGUI_TreeWidgetItem( QTreeWidget*, const QStringList&, char*, int = Type );
+ GEOMToolsGUI_TreeWidgetItem( QTreeWidgetItem*, const QStringList&, char*, int = Type );
+ ~GEOMToolsGUI_TreeWidgetItem();
+
+ bool isVisible();
+ void setVisible( bool, QIcon& );
+
+ char* getStudyEntry() const;
+
+private:
+ bool myVisible;
+ char* myStudyEntry;
+
+};
+
+class GEOMTOOLSGUI_EXPORT GEOMToolsGUI_ReduceStudyDlg : public QDialog
+{
+ Q_OBJECT
+
+public:
+ GEOMToolsGUI_ReduceStudyDlg( QWidget* );
+ ~GEOMToolsGUI_ReduceStudyDlg();
+
+private slots:
+ void onItemClicked(QTreeWidgetItem*, int );
+ void onHeaderClicked( int );
+
+ void selectionChanged();
+
+ void update();
+
+ void clickOnOk();
+ void clickOnHelp();
+
+private:
+ void init( const std::set& theObjectEntries );
+ std::set getSelectedObjects() const;
+
+ void createTreeWidget( QTreeWidget* );
+ QGroupBox* createButtonGroup( QButtonGroup* );
+
+ void addObjectsToTree( QTreeWidget*, std::set& );
+ GEOMToolsGUI_TreeWidgetItem* addSubObject( QTreeWidget*, std::set&, GEOM::GEOM_Object_var );
+ GEOMToolsGUI_TreeWidgetItem* findObjectInTree( QTreeWidget*, GEOM::GEOM_Object_var );
+
+ void checkVisibleIcon( QTreeWidget* );
+ bool isObjectDrawable( std::string );
+
+ void unpublishObjects( std::set& );
+
+ void removeObjects( std::set& );
+ void removeObject( std::string& );
+
+ void removeEmptyFolders();
+ void getEmptyFolders( _PTR(SObject), std::set& );
+
+ QTreeWidget* myTreeKeptObjects;
+ QTreeWidget* myTreeRemoveObjects;
+ std::map myMapTreeSelectAll;
+
+ QButtonGroup* myGroupIntermediates;
+ QButtonGroup* myGroupSubObjects;
+
+ QCheckBox* myCBRemoveEmptyFolder;
+ QCheckBox* myCBSoftRemoval;
+
+ std::set myMainEntries;
+
+ std::set myKeptObjects;
+ std::set myRemovedObjects;
+ std::set myListParents;
+ std::set myListSubObjects;
+
+ QIcon myVisible;
+ QIcon myInvisible;
+
+ GEOM_Displayer myDisplayer;
+ SalomeApp_Application* myApp;
+ _PTR(Study) myStudy;
+
+};
+
+#endif
diff --git a/src/GEOMUtils/GEOMUtils.cxx b/src/GEOMUtils/GEOMUtils.cxx
index 468a7f883..89b13d96b 100644
--- a/src/GEOMUtils/GEOMUtils.cxx
+++ b/src/GEOMUtils/GEOMUtils.cxx
@@ -87,6 +87,7 @@
#include
#include
+#include
#include
#include
@@ -94,11 +95,13 @@
#define STD_SORT_ALGO 1
+namespace GEOMUtils {
+
//=======================================================================
//function : GetPosition
//purpose :
//=======================================================================
-gp_Ax3 GEOMUtils::GetPosition (const TopoDS_Shape& theShape)
+gp_Ax3 GetPosition (const TopoDS_Shape& theShape)
{
gp_Ax3 aResult;
@@ -158,7 +161,7 @@ gp_Ax3 GEOMUtils::GetPosition (const TopoDS_Shape& theShape)
//function : GetVector
//purpose :
//=======================================================================
-gp_Vec GEOMUtils::GetVector (const TopoDS_Shape& theShape,
+gp_Vec GetVector (const TopoDS_Shape& theShape,
Standard_Boolean doConsiderOrientation)
{
if (theShape.IsNull())
@@ -227,7 +230,7 @@ std::pair ShapeToDouble (const TopoDS_Shape& S, bool isOldSortin
//function : CompareShapes::operator()
//purpose : used by std::sort(), called from SortShapes()
//=======================================================================
-bool GEOMUtils::CompareShapes::operator() (const TopoDS_Shape& theShape1,
+bool CompareShapes::operator() (const TopoDS_Shape& theShape1,
const TopoDS_Shape& theShape2)
{
if (!myMap.IsBound(theShape1)) {
@@ -287,7 +290,7 @@ bool GEOMUtils::CompareShapes::operator() (const TopoDS_Shape& theShape1,
//function : SortShapes
//purpose :
//=======================================================================
-void GEOMUtils::SortShapes (TopTools_ListOfShape& SL,
+void SortShapes (TopTools_ListOfShape& SL,
const Standard_Boolean isOldSorting)
{
#ifdef STD_SORT_ALGO
@@ -425,7 +428,7 @@ void GEOMUtils::SortShapes (TopTools_ListOfShape& SL,
//function : CompsolidToCompound
//purpose :
//=======================================================================
-TopoDS_Shape GEOMUtils::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
+TopoDS_Shape CompsolidToCompound (const TopoDS_Shape& theCompsolid)
{
if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
return theCompsolid;
@@ -452,7 +455,7 @@ TopoDS_Shape GEOMUtils::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
//function : AddSimpleShapes
//purpose :
//=======================================================================
-void GEOMUtils::AddSimpleShapes (const TopoDS_Shape& theShape, TopTools_ListOfShape& theList)
+void AddSimpleShapes (const TopoDS_Shape& theShape, TopTools_ListOfShape& theList)
{
if (theShape.ShapeType() != TopAbs_COMPOUND &&
theShape.ShapeType() != TopAbs_COMPSOLID) {
@@ -480,7 +483,7 @@ void GEOMUtils::AddSimpleShapes (const TopoDS_Shape& theShape, TopTools_ListOfSh
//function : CheckTriangulation
//purpose :
//=======================================================================
-bool GEOMUtils::CheckTriangulation (const TopoDS_Shape& aShape)
+bool CheckTriangulation (const TopoDS_Shape& aShape)
{
bool isTriangulation = true;
@@ -530,7 +533,7 @@ bool GEOMUtils::CheckTriangulation (const TopoDS_Shape& aShape)
//function : GetTypeOfSimplePart
//purpose :
//=======================================================================
-TopAbs_ShapeEnum GEOMUtils::GetTypeOfSimplePart (const TopoDS_Shape& theShape)
+TopAbs_ShapeEnum GetTypeOfSimplePart (const TopoDS_Shape& theShape)
{
TopAbs_ShapeEnum aType = theShape.ShapeType();
if (aType == TopAbs_VERTEX) return TopAbs_VERTEX;
@@ -551,7 +554,7 @@ TopAbs_ShapeEnum GEOMUtils::GetTypeOfSimplePart (const TopoDS_Shape& theShape)
//function : GetEdgeNearPoint
//purpose :
//=======================================================================
-TopoDS_Shape GEOMUtils::GetEdgeNearPoint (const TopoDS_Shape& theShape,
+TopoDS_Shape GetEdgeNearPoint (const TopoDS_Shape& theShape,
const TopoDS_Vertex& thePoint)
{
TopoDS_Shape aResult;
@@ -619,7 +622,7 @@ TopoDS_Shape GEOMUtils::GetEdgeNearPoint (const TopoDS_Shape& theShape,
//function : PreciseBoundingBox
//purpose :
//=======================================================================
-Standard_Boolean GEOMUtils::PreciseBoundingBox
+Standard_Boolean PreciseBoundingBox
(const TopoDS_Shape &theShape, Bnd_Box &theBox)
{
Standard_Real aBound[6];
@@ -665,7 +668,7 @@ Standard_Boolean GEOMUtils::PreciseBoundingBox
// Get minimal distance between planar face and shape.
Standard_Real aMinDist =
- GEOMUtils::GetMinDistance(aFace, theShape, aPMin[0], aPMin[1]);
+ GetMinDistance(aFace, theShape, aPMin[0], aPMin[1]);
if (aMinDist < 0.) {
return Standard_False;
@@ -681,173 +684,20 @@ Standard_Boolean GEOMUtils::PreciseBoundingBox
return Standard_True;
}
-//=======================================================================
-//function : GetMinDistanceSingular
-//purpose :
-//=======================================================================
-double GEOMUtils::GetMinDistanceSingular(const TopoDS_Shape& aSh1,
- const TopoDS_Shape& aSh2,
- gp_Pnt& Ptmp1, gp_Pnt& Ptmp2)
-{
- TopoDS_Shape tmpSh1;
- TopoDS_Shape tmpSh2;
- Standard_Real AddDist1 = 0.;
- Standard_Real AddDist2 = 0.;
- Standard_Boolean IsChange1 = GEOMUtils::ModifyShape(aSh1, tmpSh1, AddDist1);
- Standard_Boolean IsChange2 = GEOMUtils::ModifyShape(aSh2, tmpSh2, AddDist2);
-
- if( !IsChange1 && !IsChange2 )
- return -2.0;
-
- BRepExtrema_DistShapeShape dst(tmpSh1,tmpSh2);
- if (dst.IsDone()) {
- double MinDist = 1.e9;
- gp_Pnt PMin1, PMin2, P1, P2;
- for (int i = 1; i <= dst.NbSolution(); i++) {
- P1 = dst.PointOnShape1(i);
- P2 = dst.PointOnShape2(i);
- Standard_Real Dist = P1.Distance(P2);
- if (MinDist > Dist) {
- MinDist = Dist;
- PMin1 = P1;
- PMin2 = P2;
- }
- }
- if(MinDist<1.e-7) {
- Ptmp1 = PMin1;
- Ptmp2 = PMin2;
- }
- else {
- gp_Dir aDir(gp_Vec(PMin1,PMin2));
- if( MinDist > (AddDist1+AddDist2) ) {
- Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
- PMin1.Y() + aDir.Y()*AddDist1,
- PMin1.Z() + aDir.Z()*AddDist1 );
- Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
- PMin2.Y() - aDir.Y()*AddDist2,
- PMin2.Z() - aDir.Z()*AddDist2 );
- return (MinDist - AddDist1 - AddDist2);
- }
- else {
- if( AddDist1 > 0 ) {
- Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
- PMin1.Y() + aDir.Y()*AddDist1,
- PMin1.Z() + aDir.Z()*AddDist1 );
- Ptmp2 = Ptmp1;
- }
- else {
- Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
- PMin2.Y() - aDir.Y()*AddDist2,
- PMin2.Z() - aDir.Z()*AddDist2 );
- Ptmp1 = Ptmp2;
- }
- }
- }
- double res = MinDist - AddDist1 - AddDist2;
- if(res<0.) res = 0.0;
- return res;
- }
- return -2.0;
-}
-
-//=======================================================================
-//function : GetMinDistance
-//purpose :
-//=======================================================================
-Standard_Real GEOMUtils::GetMinDistance
- (const TopoDS_Shape& theShape1,
- const TopoDS_Shape& theShape2,
- gp_Pnt& thePnt1, gp_Pnt& thePnt2)
-{
- Standard_Real aResult = 1.e9;
-
- // Issue 0020231: A min distance bug with torus and vertex.
- // Make GetMinDistance() return zero if a sole VERTEX is inside any of SOLIDs
-
- // which of shapes consists of only one vertex?
- TopExp_Explorer exp1(theShape1,TopAbs_VERTEX), exp2(theShape2,TopAbs_VERTEX);
- TopoDS_Shape V1 = exp1.More() ? exp1.Current() : TopoDS_Shape();
- TopoDS_Shape V2 = exp2.More() ? exp2.Current() : TopoDS_Shape();
- exp1.Next(); exp2.Next();
- if ( exp1.More() ) V1.Nullify();
- if ( exp2.More() ) V2.Nullify();
- // vertex and container of solids
- TopoDS_Shape V = V1.IsNull() ? V2 : V1;
- TopoDS_Shape S = V1.IsNull() ? theShape1 : theShape2;
- if ( !V.IsNull() ) {
- // classify vertex against solids
- gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( V ) );
- for ( exp1.Init( S, TopAbs_SOLID ); exp1.More(); exp1.Next() ) {
- BRepClass3d_SolidClassifier classifier( exp1.Current(), p, 1e-6);
- if ( classifier.State() == TopAbs_IN ) {
- thePnt1 = p;
- thePnt2 = p;
- return 0.0;
- }
- }
- }
- // End Issue 0020231
-
- // skl 30.06.2008
- // additional workaround for bugs 19899, 19908 and 19910 from Mantis
- double dist = GEOMUtils::GetMinDistanceSingular
- (theShape1, theShape2, thePnt1, thePnt2);
-
- if (dist > -1.0) {
- return dist;
- }
-
- BRepExtrema_DistShapeShape dst (theShape1, theShape2);
- if (dst.IsDone()) {
- gp_Pnt P1, P2;
-
- for (int i = 1; i <= dst.NbSolution(); i++) {
- P1 = dst.PointOnShape1(i);
- P2 = dst.PointOnShape2(i);
-
- Standard_Real Dist = P1.Distance(P2);
- if (aResult > Dist) {
- aResult = Dist;
- thePnt1 = P1;
- thePnt2 = P2;
- }
- }
- }
-
- return aResult;
-}
-
-//=======================================================================
-// function : ConvertClickToPoint()
-// purpose : Returns the point clicked in 3D view
-//=======================================================================
-gp_Pnt GEOMUtils::ConvertClickToPoint( int x, int y, Handle(V3d_View) aView )
-{
- V3d_Coordinate XEye, YEye, ZEye, XAt, YAt, ZAt;
- aView->Eye( XEye, YEye, ZEye );
-
- aView->At( XAt, YAt, ZAt );
- gp_Pnt EyePoint( XEye, YEye, ZEye );
- gp_Pnt AtPoint( XAt, YAt, ZAt );
-
- gp_Vec EyeVector( EyePoint, AtPoint );
- gp_Dir EyeDir( EyeVector );
-
- gp_Pln PlaneOfTheView = gp_Pln( AtPoint, EyeDir );
- Standard_Real X, Y, Z;
- aView->Convert( x, y, X, Y, Z );
- gp_Pnt ConvertedPoint( X, Y, Z );
-
- gp_Pnt2d ConvertedPointOnPlane = ProjLib::Project( PlaneOfTheView, ConvertedPoint );
- gp_Pnt ResultPoint = ElSLib::Value( ConvertedPointOnPlane.X(), ConvertedPointOnPlane.Y(), PlaneOfTheView );
- return ResultPoint;
-}
-
//=======================================================================
// function : ModifyShape
-// purpose :
+// purpose : This function constructs and returns modified shape
+// from the original one for singular cases.
+// It is used for the method GetMinDistanceSingular.
+//
+// \param theShape the original shape
+// \param theModifiedShape output parameter. The modified shape.
+// \param theAddDist output parameter. The added distance for modified shape.
+// \retval true if the shape is modified; false otherwise.
+//
+
//=======================================================================
-Standard_Boolean GEOMUtils::ModifyShape(const TopoDS_Shape &theShape,
+Standard_Boolean ModifyShape(const TopoDS_Shape &theShape,
TopoDS_Shape &theModifiedShape,
Standard_Real &theAddDist)
{
@@ -950,3 +800,282 @@ Standard_Boolean GEOMUtils::ModifyShape(const TopoDS_Shape &theShape,
return isModified;
}
+
+//=======================================================================
+//function : GetMinDistanceSingular
+//purpose :
+//=======================================================================
+double GetMinDistanceSingular(const TopoDS_Shape& aSh1,
+ const TopoDS_Shape& aSh2,
+ gp_Pnt& Ptmp1, gp_Pnt& Ptmp2)
+{
+ TopoDS_Shape tmpSh1;
+ TopoDS_Shape tmpSh2;
+ Standard_Real AddDist1 = 0.;
+ Standard_Real AddDist2 = 0.;
+ Standard_Boolean IsChange1 = ModifyShape(aSh1, tmpSh1, AddDist1);
+ Standard_Boolean IsChange2 = ModifyShape(aSh2, tmpSh2, AddDist2);
+
+ if( !IsChange1 && !IsChange2 )
+ return -2.0;
+
+ BRepExtrema_DistShapeShape dst(tmpSh1,tmpSh2);
+ if (dst.IsDone()) {
+ double MinDist = 1.e9;
+ gp_Pnt PMin1, PMin2, P1, P2;
+ for (int i = 1; i <= dst.NbSolution(); i++) {
+ P1 = dst.PointOnShape1(i);
+ P2 = dst.PointOnShape2(i);
+ Standard_Real Dist = P1.Distance(P2);
+ if (MinDist > Dist) {
+ MinDist = Dist;
+ PMin1 = P1;
+ PMin2 = P2;
+ }
+ }
+ if(MinDist<1.e-7) {
+ Ptmp1 = PMin1;
+ Ptmp2 = PMin2;
+ }
+ else {
+ gp_Dir aDir(gp_Vec(PMin1,PMin2));
+ if( MinDist > (AddDist1+AddDist2) ) {
+ Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
+ PMin1.Y() + aDir.Y()*AddDist1,
+ PMin1.Z() + aDir.Z()*AddDist1 );
+ Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
+ PMin2.Y() - aDir.Y()*AddDist2,
+ PMin2.Z() - aDir.Z()*AddDist2 );
+ return (MinDist - AddDist1 - AddDist2);
+ }
+ else {
+ if( AddDist1 > 0 ) {
+ Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
+ PMin1.Y() + aDir.Y()*AddDist1,
+ PMin1.Z() + aDir.Z()*AddDist1 );
+ Ptmp2 = Ptmp1;
+ }
+ else {
+ Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
+ PMin2.Y() - aDir.Y()*AddDist2,
+ PMin2.Z() - aDir.Z()*AddDist2 );
+ Ptmp1 = Ptmp2;
+ }
+ }
+ }
+ double res = MinDist - AddDist1 - AddDist2;
+ if(res<0.) res = 0.0;
+ return res;
+ }
+ return -2.0;
+}
+
+//=======================================================================
+//function : GetMinDistance
+//purpose :
+//=======================================================================
+Standard_Real GetMinDistance
+ (const TopoDS_Shape& theShape1,
+ const TopoDS_Shape& theShape2,
+ gp_Pnt& thePnt1, gp_Pnt& thePnt2)
+{
+ Standard_Real aResult = 1.e9;
+
+ // Issue 0020231: A min distance bug with torus and vertex.
+ // Make GetMinDistance() return zero if a sole VERTEX is inside any of SOLIDs
+
+ // which of shapes consists of only one vertex?
+ TopExp_Explorer exp1(theShape1,TopAbs_VERTEX), exp2(theShape2,TopAbs_VERTEX);
+ TopoDS_Shape V1 = exp1.More() ? exp1.Current() : TopoDS_Shape();
+ TopoDS_Shape V2 = exp2.More() ? exp2.Current() : TopoDS_Shape();
+ exp1.Next(); exp2.Next();
+ if ( exp1.More() ) V1.Nullify();
+ if ( exp2.More() ) V2.Nullify();
+ // vertex and container of solids
+ TopoDS_Shape V = V1.IsNull() ? V2 : V1;
+ TopoDS_Shape S = V1.IsNull() ? theShape1 : theShape2;
+ if ( !V.IsNull() ) {
+ // classify vertex against solids
+ gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( V ) );
+ for ( exp1.Init( S, TopAbs_SOLID ); exp1.More(); exp1.Next() ) {
+ BRepClass3d_SolidClassifier classifier( exp1.Current(), p, 1e-6);
+ if ( classifier.State() == TopAbs_IN ) {
+ thePnt1 = p;
+ thePnt2 = p;
+ return 0.0;
+ }
+ }
+ }
+ // End Issue 0020231
+
+ // skl 30.06.2008
+ // additional workaround for bugs 19899, 19908 and 19910 from Mantis
+ double dist = GetMinDistanceSingular
+ (theShape1, theShape2, thePnt1, thePnt2);
+
+ if (dist > -1.0) {
+ return dist;
+ }
+
+ BRepExtrema_DistShapeShape dst (theShape1, theShape2);
+ if (dst.IsDone()) {
+ gp_Pnt P1, P2;
+
+ for (int i = 1; i <= dst.NbSolution(); i++) {
+ P1 = dst.PointOnShape1(i);
+ P2 = dst.PointOnShape2(i);
+
+ Standard_Real Dist = P1.Distance(P2);
+ if (aResult > Dist) {
+ aResult = Dist;
+ thePnt1 = P1;
+ thePnt2 = P2;
+ }
+ }
+ }
+
+ return aResult;
+}
+
+//=======================================================================
+// function : ConvertClickToPoint()
+// purpose : Returns the point clicked in 3D view
+//=======================================================================
+gp_Pnt ConvertClickToPoint( int x, int y, Handle(V3d_View) aView )
+{
+ V3d_Coordinate XEye, YEye, ZEye, XAt, YAt, ZAt;
+ aView->Eye( XEye, YEye, ZEye );
+
+ aView->At( XAt, YAt, ZAt );
+ gp_Pnt EyePoint( XEye, YEye, ZEye );
+ gp_Pnt AtPoint( XAt, YAt, ZAt );
+
+ gp_Vec EyeVector( EyePoint, AtPoint );
+ gp_Dir EyeDir( EyeVector );
+
+ gp_Pln PlaneOfTheView = gp_Pln( AtPoint, EyeDir );
+ Standard_Real X, Y, Z;
+ aView->Convert( x, y, X, Y, Z );
+ gp_Pnt ConvertedPoint( X, Y, Z );
+
+ gp_Pnt2d ConvertedPointOnPlane = ProjLib::Project( PlaneOfTheView, ConvertedPoint );
+ gp_Pnt ResultPoint = ElSLib::Value( ConvertedPointOnPlane.X(), ConvertedPointOnPlane.Y(), PlaneOfTheView );
+ return ResultPoint;
+}
+
+void parseWard( const LevelsList &theLevelList, std::string &treeStr )
+{
+ treeStr.append( "{" );
+ for( LevelsList::const_iterator j = theLevelList.begin();
+ j != theLevelList.end(); ++j ) {
+ if ( j != theLevelList.begin() ) {
+ treeStr.append( ";" );
+ }
+ LevelInfo level = (*j);
+ LevelInfo::iterator upIter;
+ for ( upIter = level.begin(); upIter != level.end(); ++upIter ) {
+ if ( upIter != level.begin() ) {
+ treeStr.append( "," );
+ }
+ treeStr.append( upIter->first );
+ for ( std::vector::iterator k = upIter->second.begin(); k != upIter->second.end(); ++k ) {
+ treeStr.append( "_" );
+ treeStr.append( *k );
+ }
+ }
+ }
+ treeStr.append( "}" );
+}
+
+//=======================================================================
+// function : ConvertTreeToString()
+// purpose : Returns the string representation of dependency tree
+//=======================================================================
+void ConvertTreeToString( const TreeModel &tree,
+ std::string &treeStr )
+{
+ TreeModel::const_iterator i;
+ for ( i = tree.begin(); i != tree.end(); ++i ) {
+ treeStr.append( i->first );
+ treeStr.append( "-" );
+ std::vector upLevelList = i->second.first;
+ treeStr.append( "upward" );
+ parseWard( upLevelList, treeStr );
+ std::vector downLevelList = i->second.second;
+ treeStr.append( "downward" );
+ parseWard( downLevelList, treeStr );
+ }
+}
+
+LevelsList parseWard( const std::string& theData, std::size_t& theCursor )
+{
+ std::size_t indexStart = theData.find( "{", theCursor ) + 1;
+ std::size_t indexEnd = theData.find( "}", indexStart );
+
+ std::string ward = theData.substr( indexStart, indexEnd - indexStart );
+ std::stringstream ss(ward);
+ std::string substr;
+ std::vector levelsListStr;
+ while ( std::getline( ss, substr, ';' ) ) {
+ if ( !substr.empty() )
+ levelsListStr.push_back( substr );
+ }
+ LevelsList levelsListData;
+ for( int level = 0; level < levelsListStr.size(); level++ ) {
+ std::vector namesListStr;
+ std::stringstream ss1( levelsListStr[level] );
+ while ( std::getline( ss1, substr, ',' ) ) {
+ if ( !substr.empty() )
+ namesListStr.push_back( substr );
+ }
+ LevelInfo levelInfoData;
+ for( int node = 0; node < namesListStr.size(); node++ ) {
+ std::vector linksListStr;
+ std::stringstream ss2( namesListStr[node] );
+ while ( std::getline( ss2, substr, '_' ) ) {
+ if ( !substr.empty() )
+ linksListStr.push_back( substr );
+ }
+ std::string nodeItem = linksListStr[0];
+ if( !nodeItem.empty() ) {
+ NodeLinks linksListData;
+ for( int link = 1; link < linksListStr.size(); link++ ) {
+ std::string linkItem = linksListStr[link];
+ linksListData.push_back( linkItem );
+ }// Links
+ levelInfoData[nodeItem] = linksListData;
+ }
+ }// Level's objects
+ levelsListData.push_back(levelInfoData);
+ }// Levels
+
+ theCursor = indexEnd + 1;
+ return levelsListData;
+}
+
+//=======================================================================
+// function : ConvertStringToTree()
+// purpose : Returns the dependency tree
+//=======================================================================
+void ConvertStringToTree( const std::string &theData,
+ TreeModel &tree )
+{
+ std::size_t cursor = 0;
+
+ while( theData.find('-',cursor) != std::string::npos ) //find next selected object
+ {
+ std::size_t objectIndex = theData.find( '-', cursor );
+ std::string objectEntry = theData.substr( cursor, objectIndex - cursor );
+ cursor = objectIndex;
+
+ std::size_t upwardIndexBegin = theData.find("{",cursor) + 1;
+ std::size_t upwardIndexFinish = theData.find("}",upwardIndexBegin);
+ LevelsList upwardList = parseWard( theData, cursor );
+
+ LevelsList downwardList = parseWard( theData, cursor );
+
+ tree[objectEntry] = std::pair( upwardList, downwardList );
+ }
+}
+
+} //namespace GEOMUtils
diff --git a/src/GEOMUtils/GEOMUtils.hxx b/src/GEOMUtils/GEOMUtils.hxx
index bbf8a7dbe..b35495b62 100644
--- a/src/GEOMUtils/GEOMUtils.hxx
+++ b/src/GEOMUtils/GEOMUtils.hxx
@@ -40,6 +40,11 @@
#include
+#include