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 + + + +\anchor dependency_tree_general_description_anchor

    General description

    + +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: + + +\image html tree_main_node.png + + +\image html tree_default_node.png + + +\image html tree_unpublished_node.png + + +\image html tree_highlighted_node.png + + +\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: + + +\image html tree_unidir_link.png + + +\image html tree_bidir_link.png + + +\image html tree_selfdep_link.png + + +\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 + + +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: + + + +Also, holding \b Ctrl key with pressed mouse buttons performs +the following view transformations: + + +
    +\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 + + + +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 + + + + */ 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 + + +*/ 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 + Dependency Tree + + + MOVE_NODES + Move nodes + + + HIERARCHY_DEPTH + Hierarchy depth + + + DISPLAY_ASCENDANTS + Display ascendants + + + DISPLAY_DESCENDANTS + Display descendants + + + SHOW_ALL + Show all + + + UPDATE + Update + + DependencyTree_ViewModel + + MEN_REBUILD_THE_TREE + Rebuild the tree + + + MEN_REDUCE_STUDY + 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 + Dependency Tree + + + MOVE_NODES + Move nodes + + + HIERARCHY_DEPTH + Hierarchy depth + + + DISPLAY_ASCENDANTS + Display ascendants + + + DISPLAY_DESCENDANTS + Display descendants + + + SHOW_ALL + Show all + + + UPDATE + Update + + DependencyTree_ViewModel + + MEN_REBUILD_THE_TREE + Rebuild the tree + + + MEN_REDUCE_STUDY + 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 + Dependency Tree + + + MOVE_NODES + Move nodes + + + HIERARCHY_DEPTH + Hierarchy depth + + + DISPLAY_ASCENDANTS + Display ascendants + + + DISPLAY_DESCENDANTS + Display descendants + + + SHOW_ALL + Show all + + + UPDATE + Update + + DependencyTree_ViewModel + + MEN_REBUILD_THE_TREE + Rebuild the tree + + + MEN_REDUCE_STUDY + 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 STB_MANAGE_DIMENSIONS Manage measurement dimensions of an object + + MEN_POP_SHOW_DEPENDENCY_TREE + Show dependency tree + + + MEN_POP_REDUCE_STUDY + Reduce study + MEN_POP_SHOW_ALL_DIMENSIONS Show all dimensions @@ -5024,6 +5032,66 @@ Please, select face, shell or solid and try again GEOM_PREVIEW Preview + + PREF_TAB_DEPENDENCY_VIEW + Dependency Tree + + + PREF_HIERARCHY_TYPE + Hierarchy type + + + MEN_ONLY_ASCENDANTS + Display only ascendants tree + + + MEN_ONLY_DESCENDANTS + Display only descendants tree + + + MEN_BOTH_ASCENDANTS_DESCENDANTS + Display both ascendants and descendants trees + + + GEOM_MOVE_POSSIBILITY + Possibility to move nodes + + + PREF_GROUP_DEPENDENCY_VIEW_COLOR + Color + + + PREF_DEPENDENCY_VIEW_BACKGROUND_COLOR + Background color + + + PREF_DEPENDENCY_VIEW_NODE_COLOR + Default node color + + + PREF_DEPENDENCY_VIEW_MAIN_NODE_COLOR + Main node color + + + PREF_DEPENDENCY_VIEW_UNPUBLISH_NODE_COLOR + Unpublished node color + + + PREF_DEPENDENCY_VIEW_SELECT_NODE_COLOR + Selected node color + + + PREF_DEPENDENCY_VIEW_ARROW_COLOR + Default arrow color + + + PREF_DEPENDENCY_VIEW_HIGHLIGHT_ARROW_COLOR + Highlighted arrow color + + + PREF_DEPENDENCY_VIEW_SELECT_ARROW_COLOR + Selected arrow color + GEOM_ALL_IMPORT_FILES All supported formats ( %1 ) @@ -6821,6 +6889,61 @@ Do you want to create new material? P&ublish And Close + + GEOMToolsGUI_ReduceStudyDlg + + GEOM_REDUCE_STUDY_TITLE + Reduce study + + + GEOM_REDUCE_STUDY_KEPT_OBJECTS + Objects to be kept + + + GEOM_REDUCE_STUDY_REMOVE_OBJECTS + Objects to be removed + + + GEOM_REDUCE_STUDY_NAME + Name + + + GEOM_REDUCE_STUDY_OPTIONS + Options + + + GEOM_REDUCE_STUDY_INTERMEDIATES + Intermediate objects + + + GEOM_REDUCE_STUDY_SUB_OBJECTS + Sub-objects + + + GEOM_REDUCE_STUDY_KEEP + Keep + + + GEOM_REDUCE_STUDY_UNPUBLISH + Unpublish + + + GEOM_REDUCE_STUDY_REMOVE + Remove + + + GEOM_REDUCE_STUDY_REMOVE_EMPTY_FOLDER + Remove empty folders + + + GEOM_REDUCE_STUDY_SOFT_REMOVAL + Soft removal + + + GEOM_REDUCE_STUDY_WARNING_DELETE + 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 STB_MANAGE_DIMENSIONS Gérer la cotation d'un objet + + MEN_POP_SHOW_DEPENDENCY_TREE + Show dependency tree + + + MEN_POP_SHOW_REDUCE_STUDY + Reduce study + MEN_POP_SHOW_ALL_DIMENSIONS Afficher les cotations @@ -5024,6 +5032,66 @@ Choisissez une face, une coque ou un solide et essayez de nouveau GEOM_PREVIEW Prévisualiser + + PREF_TAB_DEPENDENCY_VIEW + Dependency Tree + + + PREF_HIERARCHY_TYPE + Hierarchy type + + + MEN_ONLY_ASCENDANTS + Display only ascendants tree + + + MEN_ONLY_DESCENDANTS + Display only descendants tree + + + MEN_BOTH_ASCENDANTS_DESCENDANTS + Display both ascendants and descendants trees + + + GEOM_MOVE_POSSIBILITY + Possibility to move nodes + + + PREF_GROUP_DEPENDENCY_VIEW_COLOR + Color + + + PREF_DEPENDENCY_VIEW_BACKGROUND_COLOR + Background color + + + PREF_DEPENDENCY_VIEW_NODE_COLOR + Default node color + + + PREF_DEPENDENCY_VIEW_MAIN_NODE_COLOR + Main node color + + + PREF_DEPENDENCY_VIEW_UNPUBLISH_NODE_COLOR + Unpublished node color + + + PREF_DEPENDENCY_VIEW_SELECT_NODE_COLOR + Selected node color + + + PREF_DEPENDENCY_VIEW_ARROW_COLOR + Arrow color + + + PREF_DEPENDENCY_VIEW_HIGHLIGHT_ARROW_COLOR + Highlighted arrow color + + + PREF_DEPENDENCY_VIEW_SELECT_ARROW_COLOR + Selected arrow color + GEOM_ALL_IMPORT_FILES Tous les formats supportés ( %1 ) @@ -6821,6 +6889,61 @@ Voulez-vous en créer un nouveau ? P&ublier et fermer + + GEOMToolsGUI_ReduceStudyDlg + + GEOM_REDUCE_STUDY_TITLE + Reduce study + + + GEOM_REDUCE_STUDY_KEPT_OBJECTS + Objects to be kept + + + GEOM_REDUCE_STUDY_REMOVE_OBJECTS + Objects to be removed + + + GEOM_REDUCE_STUDY_NAME + Name + + + GEOM_REDUCE_STUDY_OPTIONS + Options + + + GEOM_REDUCE_STUDY_INTERMEDIATES + Intermediate objects + + + GEOM_REDUCE_STUDY_SUB_OBJECTS + Sub-objects + + + GEOM_REDUCE_STUDY_KEEP + Keep + + + GEOM_REDUCE_STUDY_UNPUBLISH + Unpublish + + + GEOM_REDUCE_STUDY_REMOVE + Remove + + + GEOM_REDUCE_STUDY_REMOVE_EMPTY_FOLDER + Remove empty folders + + + GEOM_REDUCE_STUDY_SOFT_REMOVAL + Soft removal + + + GEOM_REDUCE_STUDY_WARNING_DELETE + 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 @@ STB_MANAGE_DIMENSIONS オブジェクトの基準寸法を管理 + + MEN_POP_SHOW_DEPENDENCY_TREE + Show dependency tree + + + MEN_POP_SHOW_REDUCE_STUDY + Reduce study + MEN_POP_SHOW_ALL_DIMENSIONS すべての寸法を表示 @@ -5019,6 +5027,66 @@ GEOM_PREVIEW プレビュー + + PREF_TAB_DEPENDENCY_VIEW + Dependency Tree + + + PREF_HIERARCHY_TYPE + Hierarchy type + + + MEN_ONLY_ASCENDANTS + Display only ascendants tree + + + MEN_ONLY_DESCENDANTS + Display only descendants tree + + + MEN_BOTH_ASCENDANTS_DESCENDANTS + Display both ascendants and descendants trees + + + GEOM_MOVE_POSSIBILITY + Possibility to move nodes + + + PREF_GROUP_DEPENDENCY_VIEW_COLOR + Color + + + PREF_DEPENDENCY_VIEW_BACKGROUND_COLOR + Background color + + + PREF_DEPENDENCY_VIEW_NODE_COLOR + Default node color + + + PREF_DEPENDENCY_VIEW_MAIN_NODE_COLOR + Main node color + + + PREF_DEPENDENCY_VIEW_UNPUBLISH_NODE_COLOR + Unpublished node color + + + PREF_DEPENDENCY_VIEW_SELECT_NODE_COLOR + Selected node color + + + PREF_DEPENDENCY_VIEW_ARROW_COLOR + Arrow color + + + PREF_DEPENDENCY_VIEW_HIGHLIGHT_ARROW_COLOR + Highlighted arrow color + + + PREF_DEPENDENCY_VIEW_SELECT_ARROW_COLOR + Selected arrow color + GEOM_ALL_IMPORT_FILES サポートされているすべての形式 (%1) @@ -6801,6 +6869,61 @@ 発行し閉じる(&u) + + GEOMToolsGUI_ReduceStudyDlg + + GEOM_REDUCE_STUDY_TITLE + Reduce study + + + GEOM_REDUCE_STUDY_KEPT_OBJECTS + Objects to be kept + + + GEOM_REDUCE_STUDY_REMOVE_OBJECTS + Objects to be removed + + + GEOM_REDUCE_STUDY_NAME + Name + + + GEOM_REDUCE_STUDY_OPTIONS + Options + + + GEOM_REDUCE_STUDY_INTERMEDIATES + Intermediate objects + + + GEOM_REDUCE_STUDY_SUB_OBJECTS + Sub-objects + + + GEOM_REDUCE_STUDY_KEEP + Keep + + + GEOM_REDUCE_STUDY_UNPUBLISH + Unpublish + + + GEOM_REDUCE_STUDY_REMOVE + Remove + + + GEOM_REDUCE_STUDY_REMOVE_EMPTY_FOLDER + Remove empty folders + + + GEOM_REDUCE_STUDY_SOFT_REMOVAL + Soft removal + + + GEOM_REDUCE_STUDY_WARNING_DELETE + 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 +#include +#include +#include + class Bnd_Box; inline Standard_Boolean IsEqual (const TopoDS_Shape& S1, const TopoDS_Shape& S2) @@ -47,9 +52,13 @@ inline Standard_Boolean IsEqual (const TopoDS_Shape& S1, const TopoDS_Shape& S2) return S1.IsSame(S2); } -class GEOMUtils { +namespace GEOMUtils { + + typedef std::vector NodeLinks; + typedef std::map LevelInfo; + typedef std::vector LevelsList; + typedef std::map > TreeModel; - public: /*! * \brief Get Local Coordinate System, corresponding to the given shape. * @@ -57,7 +66,7 @@ class GEOMUtils { * Axes of the LCS are obtained from shape's location or, * if the shape is a planar face, from position of its plane. */ - Standard_EXPORT static gp_Ax3 GetPosition (const TopoDS_Shape& theShape); + Standard_EXPORT gp_Ax3 GetPosition (const TopoDS_Shape& theShape); /*! * \brief Get vector, defined by the given edge. @@ -67,7 +76,7 @@ class GEOMUtils { * the same edge can have different orientation depending on the way it was * extracted from a shape. */ - Standard_EXPORT static gp_Vec GetVector (const TopoDS_Shape& theShape, + Standard_EXPORT gp_Vec GetVector (const TopoDS_Shape& theShape, Standard_Boolean doConsiderOrientation); /*! @@ -89,7 +98,7 @@ class GEOMUtils { /*! * \brief Sort shapes by their centers of mass, using formula X*999 + Y*99 + Z*0.9 */ - Standard_EXPORT static void SortShapes (TopTools_ListOfShape& SL, + Standard_EXPORT void SortShapes (TopTools_ListOfShape& SL, const Standard_Boolean isOldSorting = Standard_True); /*! @@ -100,7 +109,7 @@ class GEOMUtils { * \param theCompsolid The compsolid to be converted. * \retval TopoDS_Shape Returns the resulting compound. */ - Standard_EXPORT static TopoDS_Shape CompsolidToCompound (const TopoDS_Shape& theCompsolid); + Standard_EXPORT TopoDS_Shape CompsolidToCompound (const TopoDS_Shape& theCompsolid); /*! * \brief Recursively extract all shapes from compounds and compsolids of the given shape into theList. @@ -110,7 +119,7 @@ class GEOMUtils { * \param theShape The shape to be exploded. * \param theList Output parameter. */ - Standard_EXPORT static void AddSimpleShapes (const TopoDS_Shape& theShape, + Standard_EXPORT void AddSimpleShapes (const TopoDS_Shape& theShape, TopTools_ListOfShape& theList); /*! @@ -118,14 +127,14 @@ class GEOMUtils { * \param theShape The shape to check/build triangulation on. * \retval bool Returns false if the shape has no faces, i.e. impossible to build triangulation. */ - Standard_EXPORT static bool CheckTriangulation (const TopoDS_Shape& theShape); + Standard_EXPORT bool CheckTriangulation (const TopoDS_Shape& theShape); /*! * \brief Return type of shape for explode. In case of compound it will be a type of its first sub shape. * \param theShape The shape to get type of. * \retval TopAbs_ShapeEnum Return type of shape for explode. */ - Standard_EXPORT static TopAbs_ShapeEnum GetTypeOfSimplePart (const TopoDS_Shape& theShape); + Standard_EXPORT TopAbs_ShapeEnum GetTypeOfSimplePart (const TopoDS_Shape& theShape); /*! * \brief Find an edge of theShape, closest to thePoint. @@ -134,7 +143,7 @@ class GEOMUtils { * \param thePoint The point near the required edge. * \retval TopoDS_Shape Returns the found edge or an empty shape if multiple edges found. */ - Standard_EXPORT static TopoDS_Shape GetEdgeNearPoint (const TopoDS_Shape& theShape, + Standard_EXPORT TopoDS_Shape GetEdgeNearPoint (const TopoDS_Shape& theShape, const TopoDS_Vertex& thePoint); /*! @@ -144,7 +153,7 @@ class GEOMUtils { * \param theBox rough bounding box on input; precise bounding box on output. * \retval Standard_True in case of success; Standard_False otherwise. */ - Standard_EXPORT static Standard_Boolean PreciseBoundingBox + Standard_EXPORT Standard_Boolean PreciseBoundingBox (const TopoDS_Shape &theShape, Bnd_Box &theBox); /*! @@ -157,7 +166,7 @@ class GEOMUtils { * \param Ptmp2 the output result point on the second shape * \retval negative value if it is not a singular case; actual distance for singular case. */ - Standard_EXPORT static Standard_Real GetMinDistanceSingular + Standard_EXPORT Standard_Real GetMinDistanceSingular (const TopoDS_Shape& aSh1, const TopoDS_Shape& aSh2, gp_Pnt& Ptmp1, gp_Pnt& Ptmp2); @@ -171,7 +180,7 @@ class GEOMUtils { * \param thePnt2 the output result point on the second shape * \retval negative value in case of failure; otherwise the real distance. */ - Standard_EXPORT static Standard_Real GetMinDistance + Standard_EXPORT Standard_Real GetMinDistance (const TopoDS_Shape& theShape1, const TopoDS_Shape& theShape2, gp_Pnt& thePnt1, gp_Pnt& thePnt2); @@ -184,23 +193,13 @@ class GEOMUtils { * \param theView View where the given point takes place. * \retval gp_Pnt Returns the point clicked in 3D view */ - Standard_EXPORT static gp_Pnt ConvertClickToPoint( int x, int y, Handle(V3d_View) theView ); + Standard_EXPORT gp_Pnt ConvertClickToPoint( int x, int y, Handle(V3d_View) theView ); -private: - - /** - * 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. - */ - static Standard_Boolean ModifyShape(const TopoDS_Shape &theShape, - TopoDS_Shape &theModifiedShape, - Standard_Real &theAddDist); + Standard_EXPORT void ConvertTreeToString( const TreeModel &theTree, + std::string &DependencyStr ); + Standard_EXPORT void ConvertStringToTree( const std::string &theDependencyStr, + TreeModel &tree ); }; diff --git a/src/GEOM_I/CMakeLists.txt b/src/GEOM_I/CMakeLists.txt index fb2a677a7..ca49d2aca 100755 --- a/src/GEOM_I/CMakeLists.txt +++ b/src/GEOM_I/CMakeLists.txt @@ -28,6 +28,7 @@ INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/GEOMImpl ${PROJECT_SOURCE_DIR}/src/GEOM ${PROJECT_SOURCE_DIR}/src/GEOMAlgo + ${PROJECT_SOURCE_DIR}/src/GEOMUtils ${PROJECT_SOURCE_DIR}/src/XAO ${PROJECT_BINARY_DIR}/idl ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/src/GEOM_I/GEOM_Gen_i.cc b/src/GEOM_I/GEOM_Gen_i.cc index 4732c1f5a..a764d3aeb 100755 --- a/src/GEOM_I/GEOM_Gen_i.cc +++ b/src/GEOM_I/GEOM_Gen_i.cc @@ -36,7 +36,6 @@ #include "Utils_ExceptHandlers.hxx" #include "utilities.h" -#include "GEOM_Object_i.hh" #include "GEOM_Object.hxx" #include "GEOM_Function.hxx" #include "GEOM_ISubShape.hxx" @@ -60,6 +59,9 @@ #include #include #include +#include +#include +#include #include #include @@ -3039,6 +3041,354 @@ Engines::ListOfData* GEOM_Gen_i::getModifiedData(CORBA::Long studyId) return aResult._retn(); } +//======================================================================= +// function : GetDependencyTree +// purpose : Collects dependencies of the given objects from other ones +//======================================================================= +SALOMEDS::TMPFile* GEOM_Gen_i::GetDependencyTree( SALOMEDS::Study_ptr theStudy, + const GEOM::string_array& theObjectEntries ) { + // fill in the tree structure + GEOMUtils::TreeModel tree; + + std::string entry; + for ( int i = 0; i < theObjectEntries.length(); i++ ) { + // process objects one-by-one + entry = theObjectEntries[i].in(); + GEOM::GEOM_BaseObject_var anObj = GetObject( theStudy->StudyId(), entry.c_str() ); + if ( anObj->_is_nil() ) + continue; + std::map< std::string, std::set > passedEntries; + GEOMUtils::LevelsList upLevelList; + // get objects from which current one depends on recursively + getUpwardDependency( anObj, upLevelList, passedEntries ); + GEOMUtils::LevelsList downLevelList; + // get objects that depends on current one recursively + getDownwardDependency( anObj, downLevelList, passedEntries ); + tree.insert( std::pair >(entry, std::pair( upLevelList, downLevelList ) ) ); + } + + // translation the tree into string + std::string treeStr; + GEOMUtils::ConvertTreeToString( tree, treeStr ); + + // put string into stream + char* aBuffer = (char*)CORBA::string_dup(treeStr.c_str()); + int aBufferSize = strlen((char*)aBuffer); + + CORBA::Octet* anOctetBuf = (CORBA::Octet*)aBuffer; + + SALOMEDS::TMPFile_var aStream = new SALOMEDS::TMPFile(aBufferSize, aBufferSize, anOctetBuf, 1); + + return aStream._retn(); +} + +//======================================================================= +// function : getUpwardDependency +// purpose : Collects the entries of objects on that the given one depends +//======================================================================= +void GEOM_Gen_i::getUpwardDependency( GEOM::GEOM_BaseObject_ptr gbo, + GEOMUtils::LevelsList &upLevelList, + std::map< std::string, std::set > &passedEntries, + int level ) { + std::string aGboEntry = gbo->GetEntry(); + GEOMUtils::NodeLinks anEntries; + GEOMUtils::LevelInfo aLevelMap; + if ( level > 0 ) { + if ( level-1 >= upLevelList.size() ) { + // create a new map + upLevelList.push_back( aLevelMap ); + } else { + // get the existent map + aLevelMap = upLevelList.at(level-1); + if ( aLevelMap.count( aGboEntry ) > 0 ) { + anEntries = aLevelMap[ aGboEntry ]; + } + } + } + // get objects on that the current one depends + GEOM::ListOfGBO_var depList = gbo->GetDependency(); + std::string aDepEntry; + for( int j = 0; j < depList->length(); j++ ) { + if ( depList[j]->_is_nil() ) + continue; + aDepEntry = depList[j]->GetEntry(); + if ( passedEntries.count( aGboEntry ) > 0 && + passedEntries[aGboEntry].count( aDepEntry ) > 0 ) { + //avoid checking the passed objects + continue; + } + passedEntries[aGboEntry].insert( aDepEntry ); + if ( level > 0 ) { + anEntries.push_back( aDepEntry ); + } + // get dependencies recursively + getUpwardDependency(depList[j], upLevelList, passedEntries, level+1); + } + if ( level > 0 ) { + aLevelMap.insert( std::pair(aGboEntry, anEntries) ); + upLevelList[level-1] = aLevelMap; + } +} + +//======================================================================= +// function : getDownwardDependency +// purpose : Collects the entries of objects that depends on the given one +//======================================================================= +void GEOM_Gen_i::getDownwardDependency( GEOM::GEOM_BaseObject_ptr gbo, + GEOMUtils::LevelsList &downLevelList, + std::map< std::string, std::set > &passedEntries, + int level ) { + std::string aGboEntry = gbo->GetEntry(); + Handle(TDocStd_Document) aDoc = GEOM_Engine::GetEngine()->GetDocument(gbo->GetStudyID()); + Handle(TDataStd_TreeNode) aNode, aRoot; + Handle(GEOM_Function) aFunction; + if (aDoc->Main().FindAttribute(GEOM_Function::GetFunctionTreeID(), aRoot)) { + // go through the whole OCAF tree + TDataStd_ChildNodeIterator Itr( aRoot ); + for (; Itr.More(); Itr.Next()) { + aNode = Itr.Value(); + aFunction = GEOM_Function::GetFunction(aNode->Label()); + if (aFunction.IsNull()) { + continue; + } + TDF_Label aLabel = aFunction->GetOwnerEntry(); + if(aLabel.IsNull()) continue; + TCollection_AsciiString anEntry; + TDF_Tool::Entry(aLabel, anEntry); + GEOM::GEOM_BaseObject_var geomObj = GetObject( gbo->GetStudyID(), anEntry.ToCString() ); + if( CORBA::is_nil( geomObj ) ) + continue; + // get dependencies for current object in the tree + GEOM::ListOfGBO_var depList = geomObj->GetDependency(); + if( depList->length() == 0 ) + continue; + std::string aGoEntry = geomObj->GetEntry(); + // go through dependencies of current object to check whether it depends on the given object + for( int i = 0; i < depList->length(); i++ ) { + if ( depList[i]->_is_nil() ) + continue; + if ( depList[i]->_is_equivalent( gbo ) ) { + // yes, the current object depends on the given object + if ( passedEntries.count( aGoEntry ) > 0 && + passedEntries[aGoEntry].count( aGboEntry ) > 0 ) { + //avoid checking the passed objects + continue; + } + passedEntries[aGoEntry].insert( aGboEntry ); + GEOMUtils::NodeLinks anEntries; + GEOMUtils::LevelInfo aLevelMap; + anEntries.push_back( aGboEntry ); + if ( level >= downLevelList.size() ) { + downLevelList.push_back( aLevelMap ); + } else { + aLevelMap = downLevelList.at(level); + if ( aLevelMap.count( aGoEntry ) > 0 ) { + anEntries = aLevelMap[ aGoEntry ]; + } + } + aLevelMap.insert( std::pair(aGoEntry, anEntries) ); + downLevelList[level] = aLevelMap; + // get dependencies of the current object recursively + getDownwardDependency(geomObj, downLevelList, passedEntries, level+1); + break; + } + } + } + } +} + +//============================================================================== +// function : GetEntriesToReduceStudy +// purpose : Fills 3 lists that is used to clean study of redundant objects +//============================================================================== +void GEOM_Gen_i::GetEntriesToReduceStudy(SALOMEDS::Study_ptr theStudy, + GEOM::string_array& theSelectedEntries, + GEOM::string_array& theParentEntries, + GEOM::string_array& theSubEntries, + GEOM::string_array& theOtherEntries) +{ + std::set aSelected, aParents, aChildren, anOthers; + for ( int i = 0; i < theSelectedEntries.length(); i++ ) { + aSelected.insert( CORBA::string_dup( theSelectedEntries[i] ) ); + } + + Handle(TDocStd_Document) aDoc = GEOM_Engine::GetEngine()->GetDocument(theStudy->StudyId()); + Handle(TDataStd_TreeNode) aNode, aRoot; + Handle(GEOM_Function) aFunction; + if (aDoc->Main().FindAttribute(GEOM_Function::GetFunctionTreeID(), aRoot)) { + // go through the whole OCAF tree + TDF_Label aLabel; + std::string anEntry; + TCollection_AsciiString anAsciiEntry; + TDataStd_ChildNodeIterator Itr( aRoot ); + for (; Itr.More(); Itr.Next()) { + aNode = Itr.Value(); + aFunction = GEOM_Function::GetFunction(aNode->Label()); + if (aFunction.IsNull()) { + continue; + } + aLabel = aFunction->GetOwnerEntry(); + if(aLabel.IsNull()) + continue; + TDF_Tool::Entry(aLabel, anAsciiEntry); + anEntry = anAsciiEntry.ToCString(); + GEOM::GEOM_BaseObject_var geomObj = GetObject( theStudy->StudyId(), anEntry.c_str() ); + if( CORBA::is_nil( geomObj ) ) + continue; + + if ( aSelected.count( anEntry ) > 0 && + aParents.count( anEntry ) == 0 ) { + includeParentDependencies( geomObj, aSelected, aParents, aChildren, anOthers ); + } else if ( aParents.count( anEntry ) == 0 && + aChildren.count( anEntry ) == 0 ) { + anOthers.insert( geomObj->GetEntry() ); + } + } + + std::set::iterator it; + std::set::iterator foundIt; + TCollection_AsciiString stringIOR; + GEOM::GEOM_Object_var geomObj; + + // filling list of sub-objects + for ( it = aSelected.begin(); it != aSelected.end(); ++it ) { + includeSubObjects( theStudy, *it, aSelected, aParents, aChildren, anOthers ); + } + + // if some selected object is not a main shape, + // we move it's main shapes into 'selected' list, + // because they could not be modified anyhow. + std::set aToBeInSelected; + for ( it = aSelected.begin(); it != aSelected.end(); ++it ) { + Handle(GEOM_BaseObject) handle_object = _impl->GetObject( theStudy->StudyId(), (*it).c_str(), false); + if ( handle_object.IsNull() ) + continue; + + stringIOR = handle_object->GetIOR(); + if ( !stringIOR.Length() > 1 ) + continue; + + geomObj = GetIORFromString( stringIOR.ToCString() ); + while ( !geomObj->IsMainShape() ) { + geomObj = geomObj->GetMainShape(); + anEntry = geomObj->GetEntry(); + + foundIt = aParents.find( anEntry ); + if ( foundIt != aParents.end() ) + aParents.erase( foundIt ); + + foundIt = aChildren.find( anEntry ); + if ( foundIt != aChildren.end() ) + aChildren.erase( foundIt ); + + foundIt = anOthers.find( anEntry ); + if ( foundIt != anOthers.end() ) + anOthers.erase( foundIt ); + + aToBeInSelected.insert( anEntry ); + } + } + aSelected.insert( aToBeInSelected.begin(), aToBeInSelected.end() ); + + // fill the CORBA arrays with values from sets + int i; + theSelectedEntries.length( aSelected.size() ); + for ( i = 0, it = aSelected.begin(); it != aSelected.end(); ++it, i++ ) + theSelectedEntries[i] = CORBA::string_dup( (*it).c_str() ); + theParentEntries.length( aParents.size() ); + for ( i = 0, it = aParents.begin(); it != aParents.end(); ++it, i++ ) + theParentEntries[i] = CORBA::string_dup( (*it).c_str() ); + theSubEntries.length( aChildren.size() ); + for ( i = 0, it = aChildren.begin(); it != aChildren.end(); ++it, i++ ) + theSubEntries[i] = CORBA::string_dup( (*it).c_str() ); + theOtherEntries.length( anOthers.size() ); + for ( i = 0, it = anOthers.begin(); it != anOthers.end(); ++it, i++ ) + theOtherEntries[i] = CORBA::string_dup( (*it).c_str() ); + } +} + +//============================================================================== +// function : includeParentDependencies +// purpose : +//============================================================================== +void GEOM_Gen_i::includeParentDependencies(GEOM::GEOM_BaseObject_ptr geomObj, + std::set& aSelected, + std::set& aParents, + std::set& aChildren, + std::set& anOthers) +{ + std::string anEntry = geomObj->GetEntry(); + if ( aSelected.count( anEntry ) == 0 ) { + aParents.insert( anEntry ); + std::set::iterator it; + it = aChildren.find( anEntry ); + if ( it != aChildren.end() ) + aChildren.erase( it ); + it = anOthers.find( anEntry ); + if ( it != anOthers.end() ) + anOthers.erase( it ); + } + // get dependencies for current object in the tree + GEOM::ListOfGBO_var depList = geomObj->GetDependency(); + if( depList->length() == 0 ) + return; + // go through dependencies of current object to check whether it depends on the given object + std::string aDepEntry; + for( int i = 0; i < depList->length(); i++ ) { + aDepEntry = depList[i]->GetEntry(); + if ( depList[i]->_is_nil() || + aDepEntry == anEntry || // skip self-depending + aSelected.count( aDepEntry ) > 0 || // skip selected objects + aParents.count( aDepEntry ) > 0 // skip already processed objects + ) + continue; + includeParentDependencies( depList[i], aSelected, aParents, aChildren, anOthers ); + } +} + +//============================================================================== +// function : includeSubObjects +// purpose : +//============================================================================== +void GEOM_Gen_i::includeSubObjects(SALOMEDS::Study_ptr theStudy, + const std::string& aSelectedEntry, + std::set& aSelected, + std::set& aParents, + std::set& aChildren, + std::set& anOthers) +{ + std::set::iterator foundIt; + Handle(GEOM_BaseObject) handle_object = _impl->GetObject( theStudy->StudyId(), aSelectedEntry.c_str(), false); + if ( handle_object.IsNull() ) + return; + + Handle(GEOM_Function) aShapeFun = handle_object->GetFunction(1); + if ( aShapeFun.IsNull() || !aShapeFun->HasSubShapeReferences() ) + return; + + const TDataStd_ListOfExtendedString& aListEntries = aShapeFun->GetSubShapeReferences(); + if ( aListEntries.IsEmpty() ) + return; + + TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries); + for ( ; anIt.More(); anIt.Next() ) { + TCollection_ExtendedString aSubEntry = anIt.Value(); + Standard_Integer aStrLen = aSubEntry.LengthOfCString(); + char* aSubEntryStr = new char[aStrLen+1]; + aSubEntry.ToUTF8CString( aSubEntryStr ); + foundIt = aParents.find( aSubEntryStr ); + if ( foundIt == aParents.end() ) { // add to sub-objects if it is not in parents list + foundIt = aSelected.find( aSubEntryStr ); + if ( foundIt == aSelected.end() ) { // add to sub-objects if it is not in selected list + aChildren.insert( aSubEntryStr ); + foundIt = anOthers.find( aSubEntryStr ); + if ( foundIt != anOthers.end() ) + anOthers.erase( foundIt ); + } + } + includeSubObjects( theStudy, aSubEntryStr, aSelected, aParents, aChildren, anOthers ); + } +} //===================================================================================== // EXPORTED METHODS //===================================================================================== diff --git a/src/GEOM_I/GEOM_Gen_i.hh b/src/GEOM_I/GEOM_Gen_i.hh index 81771124b..5a2c0382b 100644 --- a/src/GEOM_I/GEOM_Gen_i.hh +++ b/src/GEOM_I/GEOM_Gen_i.hh @@ -51,11 +51,13 @@ #include "GEOM_IMeasureOperations_i.hh" #include "GEOM_IGroupOperations_i.hh" #include "GEOM_IFieldOperations_i.hh" +#include "GEOMUtils.hxx" #include #include #include +#include #include //#include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC @@ -197,6 +199,10 @@ class GEOM_I_EXPORT GEOM_Gen_i: virtual public POA_GEOM::GEOM_Gen, virtual publi CORBA::Boolean theInheritFirstArg, CORBA::Boolean theAddPrefix); + //Collects dependencies of the given objects from other ones + SALOMEDS::TMPFile* GetDependencyTree(SALOMEDS::Study_ptr theStudy, + const GEOM::string_array& theObjectEntries); + //-----------------------------------------------------------------------// // Transaction methods // //-----------------------------------------------------------------------// @@ -318,6 +324,15 @@ class GEOM_I_EXPORT GEOM_Gen_i: virtual public POA_GEOM::GEOM_Gen, virtual publi // SIMAN-related functions (check out/check in) : get modified data virtual Engines::ListOfData* getModifiedData(CORBA::Long studyId); + /*! \brief Fills 3 lists that is used to clean study of redundant objects. + * To be used from GUI. + */ + void GetEntriesToReduceStudy(SALOMEDS::Study_ptr theStudy, + GEOM::string_array& theSelectedEntries, + GEOM::string_array& theParentEntries, + GEOM::string_array& theSubEntries, + GEOM::string_array& theOtherEntries); + //-----------------------------------------------------------------------// // Internal methods // //-----------------------------------------------------------------------// @@ -366,6 +381,29 @@ class GEOM_I_EXPORT GEOM_Gen_i: virtual public POA_GEOM::GEOM_Gen, virtual publi const Standard_CString& GrName, GEOM::ListOfGO_var aResList); + void getUpwardDependency( GEOM::GEOM_BaseObject_ptr gbo, + GEOMUtils::LevelsList &upLevelList, + std::map< std::string, std::set > &passedEntries, + int level = 0 ); + + void getDownwardDependency( GEOM::GEOM_BaseObject_ptr gbo, + GEOMUtils::LevelsList &downLevelList, + std::map< std::string, std::set > &passedEntries, + int level = 0 ); + + void includeParentDependencies(GEOM::GEOM_BaseObject_ptr gbo, + std::set& aSelected, + std::set& aParents, + std::set& aChildren, + std::set& anOthers); + + void includeSubObjects(SALOMEDS::Study_ptr theStudy, + const std::string& aSelectedEntry, + std::set& aSelected, + std::set& aParents, + std::set& aChildren, + std::set& anOthers); + private: ::GEOMImpl_Gen* _impl;