Salome HOME
IMP 22264: EDF 2648 GEOM: Propagate edges automatic orientation
authoreap <eap@opencascade.com>
Wed, 25 Mar 2015 09:36:47 +0000 (12:36 +0300)
committereap <eap@opencascade.com>
Wed, 25 Mar 2015 09:36:47 +0000 (12:36 +0300)
+ Optimize SMDS_VolumeTool::IsFreeFace()
+ Add icons for Evaluate and Change Sub-mesh order
+ Make "Meduim nodes on geometry" ON by default
+ Disable "Group on geometry" if mesh is not on geometry
+ SMESHGUI_MeshOp: fix switch from Sub-mesh creation to Sub-mesh edition

54 files changed:
doc/salome/examples/filters_ex01.py
doc/salome/gui/SMESH/images/a-arithmetic1d.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/a-creategroup.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/a-geometric1d.png
doc/salome/gui/SMESH/images/a-nbsegments2.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/a-startendlength.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/create_groups_from_geometry.png
doc/salome/gui/SMESH/images/distributionwithanalyticdensity.png
doc/salome/gui/SMESH/images/distributionwithtabledensity.png
doc/salome/gui/SMESH/images/groups_in_OB.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/hypo_fixedpnt_dlg.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/propagation_chain.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/rev_edges_helper_dlg.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/smesh_sort_groups.png [new file with mode: 0644]
doc/salome/gui/SMESH/input/1d_meshing_hypo.doc
doc/salome/gui/SMESH/input/about_filters.doc
doc/salome/gui/SMESH/input/about_meshes.doc
doc/salome/gui/SMESH/input/changing_orientation_of_elements.doc
doc/salome/gui/SMESH/input/constructing_meshes.doc
doc/salome/gui/SMESH/input/convert_to_from_quadratic_mesh.doc
doc/salome/gui/SMESH/input/copy_mesh.doc
doc/salome/gui/SMESH/input/create_groups_from_geometry.doc [changed mode: 0755->0644]
doc/salome/gui/SMESH/input/creating_groups.doc
doc/salome/gui/SMESH/input/define_mesh_by_script.doc
doc/salome/gui/SMESH/input/deleting_groups.doc
doc/salome/gui/SMESH/input/editing_groups.doc
doc/salome/gui/SMESH/input/grouping_elements.doc
doc/salome/gui/SMESH/input/selection_filter_library.doc
doc/salome/gui/SMESH/input/using_operations_on_groups.doc
resources/CMakeLists.txt
resources/mesh_evaluate.png [new file with mode: 0644]
resources/mesh_order.png [new file with mode: 0644]
src/OBJECT/SMESH_PreviewActorsCollection.cxx
src/OBJECT/SMESH_PreviewActorsCollection.h
src/SMDS/SMDS_VolumeTool.cxx
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx
src/SMESHGUI/SMESHGUI_GroupDlg.cxx
src/SMESHGUI/SMESHGUI_Hypotheses.cxx
src/SMESHGUI/SMESHGUI_Hypotheses.h
src/SMESHGUI/SMESHGUI_MeshOp.cxx
src/SMESHGUI/SMESH_images.ts
src/SMESHGUI/SMESH_msg_en.ts
src/StdMeshersGUI/CMakeLists.txt
src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx
src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.h
src/StdMeshersGUI/StdMeshersGUI_PropagationHelperWdg.cxx [new file with mode: 0644]
src/StdMeshersGUI/StdMeshersGUI_PropagationHelperWdg.h [new file with mode: 0644]
src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.cxx
src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx
src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.h
src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx
src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h
src/StdMeshersGUI/StdMeshers_msg_en.ts

index 03f6c74..233b699 100644 (file)
@@ -9,12 +9,12 @@ ids = mesh.GetIdsFromFilter(filter)
 print "Number of faces with aspect ratio > 1.5:", len(ids)
 
 # copy the faces with aspect ratio > 1.5 to another mesh;
-# this demostrates that a filter can be used where usually a group or submesh is acceptable
+# this demostrates that a filter can be used where usually a group or sub-mesh is acceptable
 filter.SetMesh( mesh.GetMesh() )
 mesh2 = smesh.CopyMesh( filter, "AR > 1.5" )
 print "Number of copied faces with aspect ratio > 1.5:", mesh2.NbFaces()
 
-# create a Group of faces with Aspect Ratio < 1.5
+# create a group (Group on Filter) of faces with Aspect Ratio < 1.5
 group = mesh.MakeGroup("AR < 1.5", SMESH.FACE, SMESH.FT_AspectRatio, '<', 1.5)
 print "Number of faces with aspect ratio < 1.5:", group.Size()
 
@@ -22,7 +22,6 @@ print "Number of faces with aspect ratio < 1.5:", group.Size()
 # note that contents of a GroupOnFilter is dynamically updated as the mesh changes
 crit = [ smesh.GetCriterion( SMESH.FACE, SMESH.FT_AspectRatio, '<', 1.5, BinaryOp=SMESH.FT_LogicalAND ),
          smesh.GetCriterion( SMESH.FACE, SMESH.FT_ElemGeomType,'=', SMESH.Geom_TRIANGLE ) ]
-filter = smesh.GetFilterFromCriteria( crit )
-triaGroup = mesh.GroupOnFilter( SMESH.FACE, "Tria AR < 1.5", filter )
+triaGroup = mesh.MakeGroupByCriteria( "Tria AR < 1.5", crit )
 print "Number of triangles with aspect ratio < 1.5:", triaGroup.Size()
 
old mode 100755 (executable)
new mode 100644 (file)
index aa43beb..9bc67b0
Binary files a/doc/salome/gui/SMESH/images/a-arithmetic1d.png and b/doc/salome/gui/SMESH/images/a-arithmetic1d.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 734e6c8..553fb98
Binary files a/doc/salome/gui/SMESH/images/a-creategroup.png and b/doc/salome/gui/SMESH/images/a-creategroup.png differ
index a60be94..cb5b9cc 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/a-geometric1d.png and b/doc/salome/gui/SMESH/images/a-geometric1d.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 2a7c9fc..d9f9c56
Binary files a/doc/salome/gui/SMESH/images/a-nbsegments2.png and b/doc/salome/gui/SMESH/images/a-nbsegments2.png differ
old mode 100755 (executable)
new mode 100644 (file)
index ba29d91..33293d3
Binary files a/doc/salome/gui/SMESH/images/a-startendlength.png and b/doc/salome/gui/SMESH/images/a-startendlength.png differ
index f20d4a7..7da08fc 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/create_groups_from_geometry.png and b/doc/salome/gui/SMESH/images/create_groups_from_geometry.png differ
index 170428d..53c618c 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/distributionwithanalyticdensity.png and b/doc/salome/gui/SMESH/images/distributionwithanalyticdensity.png differ
index 5fa982c..75bd698 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/distributionwithtabledensity.png and b/doc/salome/gui/SMESH/images/distributionwithtabledensity.png differ
diff --git a/doc/salome/gui/SMESH/images/groups_in_OB.png b/doc/salome/gui/SMESH/images/groups_in_OB.png
new file mode 100644 (file)
index 0000000..1ffb96a
Binary files /dev/null and b/doc/salome/gui/SMESH/images/groups_in_OB.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 74276bd..d1c131a
Binary files a/doc/salome/gui/SMESH/images/hypo_fixedpnt_dlg.png and b/doc/salome/gui/SMESH/images/hypo_fixedpnt_dlg.png differ
diff --git a/doc/salome/gui/SMESH/images/propagation_chain.png b/doc/salome/gui/SMESH/images/propagation_chain.png
new file mode 100644 (file)
index 0000000..420dee0
Binary files /dev/null and b/doc/salome/gui/SMESH/images/propagation_chain.png differ
diff --git a/doc/salome/gui/SMESH/images/rev_edges_helper_dlg.png b/doc/salome/gui/SMESH/images/rev_edges_helper_dlg.png
new file mode 100644 (file)
index 0000000..e8790a1
Binary files /dev/null and b/doc/salome/gui/SMESH/images/rev_edges_helper_dlg.png differ
diff --git a/doc/salome/gui/SMESH/images/smesh_sort_groups.png b/doc/salome/gui/SMESH/images/smesh_sort_groups.png
new file mode 100644 (file)
index 0000000..0176a30
Binary files /dev/null and b/doc/salome/gui/SMESH/images/smesh_sort_groups.png differ
index 7516952..87c20b7 100644 (file)
@@ -76,6 +76,10 @@ be reversed either directly picking them in the 3D viewer or by
 selecting the edges or groups of edges in the Object Browser. Use \b
 Add button to add the selected edges to the list.
 
+\ref reversed_edges_helper_anchor "Helper" group assists you in
+defining <b>Reversed Edges</b> parameter.
+
+
 \image html a-arithmetic1d.png
 
 \image html b-ithmetic1d.png "Arithmetic 1D hypothesis - the size of mesh elements gradually increases"
@@ -102,6 +106,9 @@ be reversed either directly picking them in the 3D viewer or by
 selecting the edges or groups of edges in the Object Browser. Use \b
 Add button to add the selected edges to the list.
 
+\ref reversed_edges_helper_anchor "Helper" group assists you in
+defining <b>Reversed Edges</b> parameter.
+
 \image html a-geometric1d.png
 
 <b>See Also</b> a sample TUI Script of a 
@@ -178,7 +185,7 @@ edges by a definite number of mesh segments with length depending on
 the selected type of distribution of nodes.
 
 The direction of the splitting is defined by the orientation of the
-underlying geometrical edge. <b>"Reverse Edges"</b> list box allows to
+underlying geometrical edge. <b>Reverse Edges</b> list box allows to
 specify the edges for which the splitting should be made in the
 direction opposing to their orientation. This list box is enabled only
 if the geometry object is selected for the meshing. In this case it is 
@@ -186,7 +193,8 @@ possible to select edges to be reversed either by directly picking them
 in the 3D viewer or by selecting the edges or groups of edges in the
 Object Browser.
 
-\image html image46.gif
+\ref reversed_edges_helper_anchor "Helper" group assists you in
+defining <b>Reversed Edges</b> parameter.
 
 You can set the type of node distribution for this hypothesis in the
 <b>Hypothesis Construction</b> dialog bog :
@@ -229,7 +237,7 @@ distribution as blue crosses. The node distribution is computed in the
 same way as for 
 \ref analyticdensity_anchor "Distribution with Analytic Density". You
 can select the <b>Conversion mode</b> from\b Exponent and <b>Cut
-negative</b>. 
+negative</b>.
 
 \image html distributionwithtabledensity.png
 
@@ -248,7 +256,7 @@ length. The length of medium segments changes with automatically chosen
 geometric progression.
 
 The direction of the splitting is defined by the orientation of the
-underlying geometrical edge. <b>"Reverse Edges"</b> list box allows to
+underlying geometrical edge. <b>Reverse Edges</b> list box allows to
 specify the edges, for which the splitting should be made in the
 direction opposing to their orientation. This list box is enabled only
 if the geometry object is selected for the meshing. In this case it is 
@@ -256,6 +264,10 @@ possible to select edges to be reversed either by directly picking them
 in the 3D viewer or by selecting the edges or groups of edges in the
 Object Browser.
 
+\ref reversed_edges_helper_anchor "Helper" group assists you in
+defining <b>Reversed Edges</b> parameter.
+
+
 \image html a-startendlength.png
 
 \image html b-art_end_length.png "The lengths of the first and the last segment are strictly defined"
@@ -290,13 +302,13 @@ minimum and maximum value of this parameter.
 set of points parametrized on the edge (from 1 to 0) and a number of
 segments for each interval limited by the points.
 
-\image html hypo_fixedpnt_dlg.png 
+\image html hypo_fixedpnt_dlg.png
 
 It is possible to check in <b>Same Nb. Segments for all intervals</b> 
 option and to define one value for all intervals.
 
 The splitting direction is defined by the orientation of the
-underlying geometrical edge. <b>"Reverse Edges"</b> list box allows to
+underlying geometrical edge. <b>Reverse Edges</b> list box allows to
 specify the edges for which the splitting should be made in the
 direction opposite to their orientation. This list box is enabled only
 if the geometrical object is selected for meshing. In this case it is
@@ -304,9 +316,38 @@ possible to select the edges to be reversed either directly picking them in
 the 3D viewer or selecting the edges or groups of edges in the
 Object Browser.
 
+\ref reversed_edges_helper_anchor "Helper" group assists you in
+defining <b>Reversed Edges</b> parameter.
+
+
 \image html mesh_fixedpnt.png "Example of a sub-mesh on the edge built using Fixed points 1D hypothesis"
 
 <b>See Also</b> a sample TUI Script of a 
 \ref tui_fixed_points "Defining Fixed Points" hypothesis operation.
 
+\anchor reversed_edges_helper_anchor
+<h2>Reversed Edges Helper</h2>
+
+\image html rev_edges_helper_dlg.png
+
+\b Helper group assists you in defining <b>Reversed Edges</b>
+parameter of the hypotheses depending on edge direction.
+
+<b>Show whole geometry</b> check-box lets you see the whole
+geometrical model in the 3D Viewer. This can help you to understand
+location within the model of a set of edges shown in the Viewer.
+
+<b>Propagation chains</b> group helps you to define 
+<b>Reversed Edges</b> so that opposite edges of quadrilateral faces
+will be split in the logically same direction. When this group is
+activated, the list is filled with propagation chains found within the
+model. When you select a chain in the list, edges of the chain are
+shown in the Viewer with arrows so that you can chose a common
+direction for all chain edges. \b Reverse button inverses the common
+direction of chain edges. If \b Add button is active, this means that some
+edges of a chain have different direction and you can click \b Add
+button to add such edges to <b>Reversed Edges</b> list.
+
+\image html propagation_chain.png "The whole geometry and a propagation chain"
+
 */
index af52b4b..d05b8f0 100644 (file)
@@ -17,7 +17,7 @@ to filter mesh nodes / elements by specific characteristic (Area, Length, etc).
 The functinality of mesh filters is available in both GUI and TUI
 modes:
 
-- In GUI, filters are available in some dialog boxes via an additional
+- In GUI, filters are available in some dialog boxes via
 "Set Filters" button, clicking on which opens the dialog box
 allowing to specify the list of filter criteria to be applied to the
 current selection. See \subpage selection_filter_library_page page to learn more
@@ -26,6 +26,7 @@ about selection filters and their usage in GUI.
 - In Python scripts, filters can be used to choose only some mesh
   entities (nodes or elements) for the operations, which require the
   list of entities as input parameter (create/modify group, remove
-  nodes/elements, etc). The page \ref tui_filters_page provides
+  nodes/elements, etc) and for the operations, which accept objects as
+  as input parameter. The page \ref tui_filters_page provides
   examples of the filters usage in Python scripts.
 */
index ebab52e..60ad290 100644 (file)
@@ -51,6 +51,8 @@ Mesh module provides several ways to create the mesh:
   <li>The whole mesh or its part (sub-mesh or group) can be 
     \subpage copy_mesh_page "copied" into a new mesh.
   </li>
+  <li>A new mesh can be created from a transformed, e.g. \ref
+    translation_page "translated", part of the mesh.</li>
 </ul>
 
 Meshes can be edited using the MESH functions destined for 
@@ -65,7 +67,7 @@ the <a href="http://www.code-aster.org/outils/med/html/connectivites.html">
 the element basing on elements of lower dimension is NOT supported.
 
 \anchor mesh_entities
-The mesh can include the following entities (also referred as \a elements):
+The mesh can include the following entities:
 <ul>
 <li>\b Node &mdash; an entity of a mesh defining a position in 3D
   space with coordinates (x, y, z).</li>
index 416f951..e7a37ee 100644 (file)
@@ -2,11 +2,13 @@
 
 \page changing_orientation_of_elements_page Changing orientation of elements
 
-\n Orientation of an element is changed by reverting the order of its nodes.
+\n Orientation of an element is switched by changing the order of its nodes.
 
 <em>To change orientation of elements:</em>
 <ol>
-<li>Display a mesh or a submesh in the 3D viewer.</li>
+<li>Select a mesh.</li>
+<li>Display a mesh, a group or a sub-mesh if you plan to select
+  elements to reorient in the 3D viewer.</li>
 <li>In the \b Modification menu select the \b Orientation item or click
 <em>Orientation</em> button in the toolbar.
 
@@ -20,20 +22,35 @@ The following dialog box will appear:
 <center>
 \image html orientaation1.png
 </center>
+<br>
 <ul>
+<li>Select <b>Element Type</b> to reorient: either \b Face or \b
+  Volume </li>
 <li><b>The main list</b> shall contain the elements which will be
-reoriented. You can click on an element in the 3D viewer and it will
-be highlighted. After that click the \b Add button and the ID of this
-element will be added to the list. To remove a selected element or
-elements from the list click the \b Remove button. The \b Sort button
-allows to sort the list of elements IDs. The <b>Set filter</b> button
-allows to apply a definite filter to selection of elements of your
-group.</li>
+  reoriented. You can click on an element in the 3D viewer and it will
+  be highlighted. After that click the \b Add button and the ID of this
+  element will be added to the list. To remove a selected element or
+  elements from the list click the \b Remove button. The \b Sort button
+  allows to sort the list of elements IDs. <br>
+  The <b>Set filter</b> button allows to apply a definite filter to
+  selection of elements of your group. Depending on \a Source of
+  elements to filter selected in \ref filtering_elements "Filter"
+  dialog, the filter will be applied to different sets of elements.<ul>
+    <li> To all elements of the mesh - for \a Mesh source. All
+      elements satisfying the filter criteria will be highlighted in the
+      Viewer. You can adjust the selection and add the selected elements
+      to the <b>main list</b>.</li>
+    <li> To the elements selected in the Viewer - for <em>Initial
+        Selection</em> source. As a result, elements rejected by the
+        filter will be deselected.</li>
+    <li> To the elemets present in the <b>main list</b> -
+      for <em>Current Dialog</em> source.  As a result, elements rejected
+      by the filter will be remove from the list.</li> </ul>
+</li>
 <li><b>Apply to all</b> radio button allows to modify the orientation
-of all elements of the currently displayed mesh or submesh.</li>
-<li><b>Select from</b> set of fields allows to choose a submesh or an
-existing group whose elements will be automatically added to the
-list.</li>
+of all elements of the mesh.</li>
+<li><b>Select from</b> set of fields allows to choose a sub-mesh or a
+group whose elements can be added to the list.</li>
 </ul>
 
 </li>
index 4e8d606..a1711c5 100644 (file)
@@ -138,7 +138,8 @@ creation and computing) of the following steps:
 
     Now you can define 3D Algorithm and 3D Hypotheses, which will be
     applied to discretize the solids of your geometrical object using
-    3D elements. Click the <em>"Add Hypothesis"</em>  button to add a hypothesis.
+    3D elements. Click the <em>"Add Hypothesis"</em> button to create
+    and add a hypothesis.
     <center>
     \image html image121.png
     <em>"Add Hypothesis" button</em>
index ee68098..d321a2f 100644 (file)
@@ -15,9 +15,10 @@ quadratic meshes.
 <ol>
 <li>Select a mesh or a sub-mesh in the Object Browser or in the
 Viewer.</li>
-<li>From the Modification menu choose <b> Convert to/from Quadratic
-Mesh item </b>, or click <em>"Convert to/from quadratic"</em> button in the
-toolbar.
+<li>From the Modification menu or from the contextual menu in the
+  Object Browser choose <b> Convert to/from Quadratic Mesh</b> item,
+  or click <em>"Convert to/from quadratic"</em> button in the
+  toolbar.
 
 <center>
 \image html image154.png
@@ -33,16 +34,14 @@ The following dialog box will appear:
 
 <ul>
 <li>If it is necessary to convert a linear mesh to quadratic or a quadratic
-  mesh to linear. **Convert to bi-quadratic** option does the same as
-  **Convert to quadratic** except for that TRIA7, QUAD9 and HEXA27
-  elements are created instead of TRIA6, QUAD8, and HEXA20 elements
-  respectively. Note that the choice is available only if the selected
-  mesh (or sub-mesh) contains both quadratic and linear elements, else the
-  direction of conversion is selected automatically.</li>
+  mesh to linear. **Convert to bi-quadratic** creates some types of quadratic
+  elements with additional central nodes: TRIA7, QUAD9 and HEXA27
+  elements instead of TRIA6, QUAD8, and HEXA20 elements
+  respectively.</li>
 <li>If it is necessary to place **medium nodes** of the quadratic mesh **on the
-  geometry** (meshed object). This option is relevant for conversion to
+  geometry** (meshed shape). This option is relevant for conversion to
   quadratic provided that the mesh is based on a geometry (not imported
-  from file).</li> 
+  from file).</li>
 </ul>
 
 \image html image156.gif
index 15bf2d1..404359c 100644 (file)
@@ -7,8 +7,9 @@
 <em>To make a copy of a mesh:</em>
 
 \par
-From the \b Mesh menu select <b>Copy Mesh</b> or click <em>"Copy Mesh"</em>
-button in the toolbar.
+From the contextual menu in the Object Browser of from the \b Mesh
+menu select <b>Copy Mesh</b> or click <em>"Copy Mesh"</em> button in
+the toolbar.
 
 \image html copy_mesh_icon.png
 <center><em>"Copy Mesh" button</em></center>
@@ -24,7 +25,7 @@ In the dialog:
 <li>specify the part of mesh to copy:
 
 <ul>
-<li><b>Select the whole mesh, submesh or group</b> by mouse activating
+<li><b>Select whole mesh, sub-mesh or group</b> by mouse activating
 this checkbox; or</li>
 <li>choose mesh elements with the mouse in the 3D Viewer. It is
 possible to select a whole area with a mouse frame; or</li> 
@@ -41,7 +42,7 @@ selection_filter_library_page "Selection filter library" page.</li>
 <li>specify the conditions of copying:
 <ul>
 <li>activate <b>Generate groups</b> checkbox to copy the groups of
-elements of the source mesh to the newly created mesh.</li>
+  the source mesh to the newly created mesh.</li>
 </ul>
 </li>
 
old mode 100755 (executable)
new mode 100644 (file)
index a09272c..34a09a4
@@ -2,16 +2,21 @@
 
 \page create_groups_from_geometry_page Create Groups from Geometry
 
-To use this operation, select in the \b Mesh menu <b>Create Groups from Geometry</b>.
+This operation allows creating groups on geometry on all selected
+shapes. Only the main shape of the mesh and its sub-shapes can be selected.
+
+The type of each new group is defined automatically by the nature of
+the <b>Geometry</b>.
+The group names will be the same as the names of geometrical objects.
+
+To use this operation, select in the \b Mesh menu or in the contextual
+menu in the Object browser <b>Create Groups from Geometry</b> item.
 
 \image html create_groups_from_geometry.png
 
-This operation allows  creating  on a selected geometry several groups consisting of
-elements of all types.
-The group names will be the same as the names of geometrical objects.
-The Type of group of mesh elements is defined automatically by the nature of
-the <b>Geometric object</b>.
+In this dialog \b Elements group contains a list of shapes to create
+groups of elements on them; \b Nodes group contains a list of shapes
+to create groups of node on them.
 
 
 */
index 34643a7..7963535 100644 (file)
@@ -2,11 +2,11 @@
 
 \page creating_groups_page Creating groups
 
-\n In MESH you can create a group of elements of a certain type. The
-contents of the group can be defined in different ways. To create a group, in the \b
-Mesh menu select <b>Create Group</b> item (also available in the
-context menu of the mesh).<br> 
-To create a group of any type you should define the following: 
+\n In MESH you can create a \ref grouping_elements_page "group" of
+elements of a certain type. The main way to create a group, is to
+select in the \b Mesh menu <b>Create Group</b> item (also available in
+the context menu of the mesh).<br>
+To create a group you should define the following: 
 <ul>
 <li><b>Mesh</b> - the mesh whose elements will form your
 group. You can select your mesh in the Objet Browser or in the 3D
@@ -22,13 +22,10 @@ elements which will form your group:</li>
 <li><b>Volumes</b></li>
 </ul>
 <li><b>Name</b> field allows to enter the name of your new group.</li>
-<li><b>Color</b> - allows to assign to the group a certain color, for
-example, defining boundary conditions. The chosen color is used to
-display the elements of the group. The color attribute of the group is
-not persistent, it is lost if you save and then load the study from
-the file.</li>
+<li><b>Color</b> - allows to assign to the group a certain color. The
+  chosen color is used to display the elements of the group.</li>
 </ul>
-SALOME Platform distinguishes between the three Group types:
+Mesh module distinguishes between the three Group types:
 <b>Standalone Group</b>, <b>Group on Geometry</b> and <b>Group on Filter</b>.
 
 \anchor standalone_group <br><h2>"Standalone Group"</h2>
@@ -37,8 +34,8 @@ SALOME Platform distinguishes between the three Group types:
 the following ways:
 <ul>
 <li>By adding all entities of the chosen type existing in the
-  mesh. For this, turn on the <b>Select All</b> check box. In this mode
-  all controls, which allow selecting the entities in other ways, are
+  mesh. For this, turn on the <b>Select All</b> check-box. In this mode
+  all controls, which allow selecting the entities, are
   disabled.</li>
 <li>By choosing entities manually with the mouse in the 3D Viewer. For
   this, turn on the <b>Enable manual edition</b> check box. You can
@@ -49,10 +46,11 @@ the following ways:
   selection of the elements for your group. See more about filters on
   the \ref selection_filter_library_page "Selection filter library"
   page.</li> 
-<li>By adding entities from either a sub-mesh or an existing
-  group.  For this, turn on the <b>Enable manual edition</b> check
-  box. <b>Select from</b> set of fields allows to select a sub-mesh or
-  a group of the appropriate type.</li>
+<li>By adding entities from either a sub-mesh or another
+  group. For this, turn on the <b>Enable manual edition</b> check
+  box. <b>Select from</b> fields group allows to select a sub-mesh or
+  a group of the appropriate type and to \b Add their elements to the
+  group.</li>
 </ul>
 In the <b>manual edition</b> mode you can
 <ul>
@@ -70,9 +68,9 @@ existing group and some other faces selected in the viewer:
 <ul>
 <li> Select the \b Face type of entities and input the name of the new group.</li>
 <li> Check the \b Group checkbox in <b>Select From</b> group.</li>
-<li> Select the existing group of faces in the object browser or in the viewer</li>
+<li> Select the existing group of faces in the object browser or in the viewer.</li>
 <li> Click \b Add in \b Content group. <b>Id Elements</b> list will be filled
-with IDs of faces belonging to the exising group.</li>
+with IDs of faces belonging to the selected group.</li>
 <li> Select other faces in the viewer.</li>
 <li> Click \b Add in \b Content group.</li>
 <li> Click \b Apply button to create the new group.</li>
@@ -87,10 +85,6 @@ is changed, the new one is not updated accordingly.
 <center>In this picture the brown cells belong to a group defined
   manually.</center> 
 
-\image html image131.gif
-<center>In this picture the brown cells belong to the group defined by
-  the criterion <b>Taper > 0</b>.</center>
-
 <b>See Also</b> a sample TUI Script of a 
 \ref tui_create_standalone_group "Create a Standalone Group"
 operation.  
@@ -101,14 +95,24 @@ operation.
 To create a group on geometry check <b>Group on geometry</b> in the \b
 Group \b type field. The group on geometry contains the elements
 of a certain type generated on the selected geometrical object. Group
-contents are dynamically updated if the mesh is modified.<br>
-To define a group, select in the Objet Browser or in the 3D viewer a
-geometrical object from which the elements will be taken. After
-confirmation of the operation a new group of mesh elements will be
-created.
+contents are dynamically updated if the mesh is modified. The group on
+geometry can be created only if the mesh is based on geometry.
+
+To define a group, click a \a Selection button and chose
+- <em>Direct geometry selection</em> to select a shape in the Object
+  Browser or in the Viewer;
+- <em>Find geometry by mesh element selection</em> to activate a
+  dialog which retrieves a shape by a selected element generated on
+  this shape.
+
+Note that this choice is available only if the mesh elements are
+already generated.
 
 \image html a-creategroup.png
 
+After confirmation of the operation a new group of mesh elements will
+be created.
+
 \image html image132.gif
 <center>In this picture the cells which belong to a certain
   geometrical face are selected in green.</center>
@@ -123,11 +127,13 @@ operation.
 To create a group on filter check <b>Group on filter</b> in the <b>
 Group type</b> field. The group on filter contains the elements
 of a certain type satisfying the defined filter. Group contents are
-dynamically updated if the mesh is modified.<br> To define a group,
-click the <b>Set filter</b> button and define criteria of the
-filter in the opened dialog. After confirmation of the operation a
-new group of mesh elements will be created. See more about filters on
-the \ref selection_filter_library_page "Selection filter library" page.
+dynamically updated if the mesh is modified.
+
+To define a group, click the <b>Set filter</b> button and define
+criteria of the filter in the opened dialog. After confirmation of the
+operation a new group of mesh elements will be created. See more about
+filters on the 
+\ref selection_filter_library_page "Selection filter library" page. 
 
 \image html creategroup_on_filter.png
 
index beb9d8e..4b97824 100644 (file)
@@ -1,8 +1,12 @@
 /*!
 
-\page  use_existing_page Use Edges/Faces to be Created Manually"
+\page  use_existing_page Use Edges/Faces to be Created Manually
 
-The algorithms <b>Use Edges to be Created Manually</b> and <b>Use Faces to be Created Manually</b> allow  creating a 1D or a 2D mesh in a python script (using <em>AddNode, AddEdge</em> and <em>AddFace</em> commands) and then using such sub-meshes in the construction of a 2D or a 3D mesh. 
+The algorithms <b>Use Edges to be Created Manually</b> and 
+<b>Use Faces to be Created Manually</b> allow  creating a 1D or a 2D mesh
+in a python script (using <em>AddNode, AddEdge</em>
+and <em>AddFace</em> commands) and then using such sub-meshes in the
+construction of a 2D or a 3D mesh. 
 
 For example, you want to use standard algorithms to generate 1D and 3D
 meshes and to create 2D mesh by your python code. For this, you
index 86addcf..521b552 100644 (file)
@@ -2,18 +2,21 @@
 
 \page deleting_groups_page Deleting groups with content
 
-\n To delete groups and their content in the <b>Main Menu</b> select <b>Modification -> Remove -> Delete groups with Contents</b> and
-select one or several groups you wish to delete in the 3D viewer or in
-the Object Browser.
-\n The selected groups will be listed in <b>Delete groups with contents</b>
-menu. Then click <b>Apply and Close</b> button to remove the selected groups and close the
-menu or \b Apply button to remove them and proceed with the selection.
+To delete groups and their content, in the menu select
+<b>Modification -> Remove -> Delete groups with Contents</b>
+and select one or several groups you wish to delete in the 3D viewer
+or in the Object Browser.
+
+The selected groups will be listed in <b>Delete groups with contents</b> menu. 
+Then click <b>Apply and Close</b> button to remove the selected groups
+and close the menu or \b Apply button to remove them and proceed with
+the selection.
 
 \image html deletegroups.png
-\n Please, note that this operation <b>removes groups with their
-elements</b>. To delete a group and leave its elements intact, right-click
+
+\n Please, note that this operation removes groups <b>with their
+  elements</b>. To delete a group and leave its elements intact, right-click
 on the group in the Object Browser and select \b Delete in the pop-up
-menu or select the group and choose <b>Edit -> Delete</b> in the <b>Main Menu</b>.
+menu or select the group and choose <b>Edit -> Delete</b> in the main menu.
 
 */
index 18b8ef6..a880b1c 100644 (file)
@@ -25,11 +25,12 @@ a <em>group on filter</em>. For more information see
 modification of the group.</li>
 </ol>
 
+<br>
 \anchor convert_to_standalone
 <em>To convert an existing group on geometry or a group on filer into
-a standalone group of elements and modify:</em>
+a standalone group and modify its contents:</em>
 <ol>
-<li>Select your group on geometry (or on filter) in the
+<li>Select your group on geometry or on filter in the
 Object Browser and in the \b Mesh menu click the <b>Edit Group as
 Standalone</b> item.</li>
 
index c6905cd..b0b4ab0 100644 (file)
@@ -2,45 +2,81 @@
 
 \page grouping_elements_page Grouping elements
 
-In Mesh module it is possible to create groups of mesh elements:
+In Mesh module it is possible to create groups of mesh entities:
 nodes, edges, faces, volumes, 0D elements or balls. One group contains
-elements of only one type. The following ways of creation are
-possible:
-
-- by selecting the elements using filters and/or directly on the 
-  presentation in the VTK viewer, and/or by using elements of other
-  mesh objects - \ref standalone_group "Standalone group"
-  tab of \ref creating_groups_page "Create group" dialog.
-- by creating a group of elements generated on the chosen geometrical
-  object - \ref group_on_geom "Group on geometry" tab of
-  \subpage creating_groups_page "Create group" dialog and
-  \subpage create_groups_from_geometry_page "Create Groups from Geometry"
-  dialog.
-- by creating a group of elements satisfying to certain criteria -
-  \ref group_on_filter "Group on filter" tab of
-  \subpage creating_groups_page "Create group" dialog.
-- by creating groups of nodes and elements from the chosen submesh
-  (type of elements depends on dimension of submesh geometry) -
-  using <b>Mesh -> Construct Group</b> menu item (available in context
-  menu as well).
-- by creating groups of entities from existing groups of superior
-  dimensions - using \subpage group_of_underlying_elements_page
-  "Create Group of Underlying Elements" dialog.
+elements of only one type. Groups, unlike sub-meshes, are exported
+along with mesh entities into the files of following formats: MED, UNV,
+and CGNS. The group has a color attribute which is used for
+visualization only and is not exported.
+
+There are three types of groups different by their internal
+organization:<ol>
+<li><b>Standalone group</b> is a static set of mesh entities. Its
+  contents can be explicitely controlled by the user. Upon removal of
+  the entities included into the group, the group becomes empty and
+  the user is to pay efforts to restore its contents. Hence it is
+  resonable to create standalone groups when the mesh generation is
+  finished and mesh quality is verified.
+  \warning Creation and edition of large standalone groups in
+  \ref creating_groups_page "Create group" dialog using manual edition
+  is problematic due to poor performance of the dialog.</li>
+<li><b>Group on geomerty</b> is associated to one or a group of
+  sub-shapes of the main shape and includes mesh entities generated on
+  this geometrical entities. The association to geometry is
+  established at group construction and can't be changed. The group
+  contents is always up-to-date without user's efforts, hence the
+  group can be created even before mesh elements generation.</li>
+<li><b>Group on filter</b> encapsulates a filter which is used to
+  select mesh entities composing the group from the whole
+  mesh. Criteria of the filter can be changed at any time. The
+  group contents is always up-to-date without user's efforts, hence
+  the group can be created even before mesh elements generation.</li>
+</ol>
+The group on geometry and group on filter can be converted to
+the standalone group.
+
+\image html groups_in_OB.png "Groups of different types look differently in the Object Browser"
+
+The following ways of group creation are possible:
+
+- \subpage creating_groups_page "Create group" dialog allows creation of
+  a group of any of all the three types:
+  \ref standalone_group "Standalone group",
+  \ref group_on_geom "Group on geometry" and
+  \ref group_on_filter "Group on filter" using dedicated tabs.
+- \subpage create_groups_from_geometry_page "Create Groups from Geometry"
+  dialog allows creation of several groups on geometry at once.
+- Standalone groups of all nodes and elements of the chosen sub-mesh
+  (type of elements depends on dimension of sub-mesh geometry) can
+  be created using <b>Mesh -> Construct Group</b> menu item (available
+  in context menu as well).
+- Standalone groups of any element type can be created basing on nodes
+  of other groups - using \subpage group_of_underlying_elements_page
+  "Group based on nodes of other groups" dialog.
+- Standalone groups can be created by applying 
+  \subpage using_operations_on_groups_page "Boolean operations" to
+  other groups.
+- Creation of standalone groups is an option of many 
+  \ref modifying_meshes_page "mesh modification" operations.
 
 The created groups can be later:
 
 - \subpage editing_groups_page "Edited"
-- \subpage using_operations_on_groups_page "Subjected to Boolean operations"
-- \subpage deleting_groups_page "Deleted"
+- \subpage deleting_groups_page "Deleted", either as an object or
+  together with contained elements.
+- The group on geometry and group on filter can be 
+  \ref convert_to_standalone "converted into the standalone" group.
+- \ref importing_exporting_meshes_page "Exported" into a file as a
+  whole mesh.
 
-In the Object Browser, if groups or sub-meshes container item has more
-than one child sub-object, it is possible to sort the children in
-ascending order. For this, select the parent object in the Object
+In the Object Browser, if groups container item includes more
+than one group, it is possible to sort the groups by name in
+ascending order. For this, select the groups container in the Object
 Browser and choose <b>Sort children</b> context menu item. 
 
-\image html smesh_sort.png "Sorting of sub-objects"
+\image html smesh_sort_groups.png "Sorting groups"
 
-An important tool, providing filters for creation of \b Standalone
-groups and groups <b>On Filter</b> is \ref selection_filter_library_page.
+An important tool, providing filters for creation of standalone
+groups and groups on filter is \ref selection_filter_library_page.
 
 */
index 02d39a5..a0e85ab 100644 (file)
@@ -16,12 +16,12 @@ the current study. You can \b Add or \b Delete filters.
 \n In <b>Filter name</b> box you can specify the name for your
 filter. By default it is prefixed with the corresponding entity type.
 
-\anchor filtering_elements
-
 When we use filters during a group creation or another operation (by 
 clicking <b>Set Filters</b> button in the corresponding dialog), the
 menu for setting filters looks a bit differently (see the image below).
 
+\anchor filtering_elements
+
 Each filter can be applicable to \b Nodes, \b Edges, \b Faces or \b
 Volumes. You can combine many criteria in one filter, but they all
 must be of the same <b>Entity type</b>.
index 9160617..a380581 100644 (file)
@@ -1,6 +1,6 @@
 /*!
 
-\page using_operations_on_groups_page Using operations on groups
+\page using_operations_on_groups_page Boolean operations on groups
 
 \n In MESH you can perform some Boolean operations on groups, which
 belong to one and the same mesh.
@@ -120,4 +120,4 @@ group.</li>
 <b>See Also</b> a sample TUI Script of a 
 \ref tui_cut_of_groups "Cut of Groups" operation.  
 
-*/
\ No newline at end of file
+*/
index 5dbf7d0..24a83d0 100755 (executable)
@@ -38,6 +38,8 @@ SET(SMESH_RESOURCES_FILES
   mesh_choose_all.png
   mesh_clear.png
   mesh_compute.png
+  mesh_evaluate.png
+  mesh_order.png
   mesh_diagonal.png
   mesh_edit.png
   mesh_hexa.png
diff --git a/resources/mesh_evaluate.png b/resources/mesh_evaluate.png
new file mode 100644 (file)
index 0000000..eddace2
Binary files /dev/null and b/resources/mesh_evaluate.png differ
diff --git a/resources/mesh_order.png b/resources/mesh_order.png
new file mode 100644 (file)
index 0000000..d8cea67
Binary files /dev/null and b/resources/mesh_order.png differ
index 493c160..aee863d 100644 (file)
@@ -65,8 +65,9 @@ SMESH_PreviewActorsCollection::~SMESH_PreviewActorsCollection()
 }
 
 bool SMESH_PreviewActorsCollection::Init( const TopoDS_Shape& theShape,
-                                          TopAbs_ShapeEnum theType,
-                                          const QString& theEntry )
+                                          const TopoDS_Shape& theMainShape,
+                                          TopAbs_ShapeEnum    theType,
+                                          const QString&      theEntry )
 {
   SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
 
@@ -82,17 +83,17 @@ bool SMESH_PreviewActorsCollection::Init( const TopoDS_Shape& theShape,
   if ( theShape.IsNull() )
     return false;
 
-  Handle( SALOME_InteractiveObject ) anIO = new SALOME_InteractiveObject();
-  anIO->setEntry( theEntry.toLatin1().constData() );
+  // Handle( SALOME_InteractiveObject ) anIO = new SALOME_InteractiveObject();
+  // anIO->setEntry( theEntry.toLatin1().constData() );
   
   // get indexes of seleted elements
-  TopExp::MapShapes( theShape, myMapOfShapes );
+  TopExp::MapShapes( theMainShape, myMapOfShapes );
   TopExp_Explorer exp( theShape, theType );
   QSet<int> indices;
   for ( ; exp.More(); exp.Next() )
     indices << myMapOfShapes.FindIndex( exp.Current() );
   myIndices = indices.toList();
-  qSort(myIndices);
+  //qSort(myIndices);
 
   // show current chunk
   showCurrentChunk();
@@ -112,11 +113,30 @@ GEOM_Actor* SMESH_PreviewActorsCollection::GetActorByIndex(int index)
   return myMapOfActors.value( index );
 }
 
+bool SMESH_PreviewActorsCollection::IsValidIndex( int index )
+{
+  return 0 < index && index <= myMapOfShapes.Extent();
+}
+
 int SMESH_PreviewActorsCollection::GetIndexByShape( const TopoDS_Shape& theShape )
 {
   return myMapOfShapes.FindIndex( theShape );
 }
 
+TopoDS_Shape SMESH_PreviewActorsCollection::GetShapeByIndex( int index )
+{
+  return IsValidIndex( index ) ? myMapOfShapes.FindKey( index ) : TopoDS_Shape();
+}
+
+void SMESH_PreviewActorsCollection::SetIndices( const QList<int>& indices)
+{
+  if ( myIndices != indices )
+  {
+    myIndices = indices;
+    showCurrentChunk();
+  }
+}
+
 void SMESH_PreviewActorsCollection::AddToRender(vtkRenderer* theRenderer)
 {
   myRenderer = theRenderer;
@@ -229,7 +249,8 @@ void SMESH_PreviewActorsCollection::showCurrentChunk()
       myMapOfActors.insert(index, anActor);
     }
   }
-  mySelector->ClearIObjects();
+  if ( mySelector )
+    mySelector->ClearIObjects();
   if ( myRenderer )
     AddToRender( myRenderer );
 }
index d5fd49b..3b3cb12 100644 (file)
@@ -19,9 +19,7 @@
 
 //  SMESH OBJECT : interactive object for SMESH visualization
 //  File   : SMESH_PreviewActorsCollection.h
-//  Author : OCN
 //  Module : SMESH
-//  $Header: /home/server/cvs/SMESH/SMESH_SRC/src/OBJECT/SMESH_PreviewActorsCollection.h,v 1
 //
 #ifndef SMESH_PREVIEW_ACTOR_COLLECTION_H
 #define SMESH_PREVIEW_ACTOR_COLLECTION_H
@@ -45,10 +43,13 @@ public:
   SMESH_PreviewActorsCollection();
   ~SMESH_PreviewActorsCollection();
 
-  virtual void    AddToRender(vtkRenderer* theRenderer);
+  virtual void    AddToRender     (vtkRenderer* theRenderer);
   virtual void    RemoveFromRender(vtkRenderer* theRenderer);
 
-  bool            Init( const TopoDS_Shape& theShape, TopAbs_ShapeEnum subShapeType = TopAbs_EDGE, const QString& = QString("") );
+  bool            Init( const TopoDS_Shape& theShape,
+                        const TopoDS_Shape& theMainShape,
+                        TopAbs_ShapeEnum    subShapeType = TopAbs_EDGE,
+                        const QString& = QString("") );
 
   void            SetSelector( SVTK_Selector* );
 
@@ -56,8 +57,13 @@ public:
   void            HighlightID( int );
 
   GEOM_Actor*     GetActorByIndex( int );
+  bool            IsValidIndex( int );
 
   int             GetIndexByShape( const TopoDS_Shape& );
+  TopoDS_Shape    GetShapeByIndex( int i );
+
+  void            SetIndices( const QList<int>& indices);
+  const QList<int>& GetIndices() const { return myIndices; }
 
   void            SetShown( bool );
 
index 1dc3dda..001387c 100644 (file)
@@ -1510,28 +1510,21 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherV
 
   const SMDS_MeshNode** nodes = GetFaceNodes( faceIndex );
 
-  // a set of facet nodes w/o medium ones and w/o nodes[0]
-  set< const SMDS_MeshElement* > nodeSet;
   const int di = myVolume->IsQuadratic() ? 2 : 1;
-  for ( int i = di; i < myFaceNbNodes; i += di )
-    nodeSet.insert( nodes[i] );
+  const SMDS_MeshNode* n1 = nodes[di*0];
+  const SMDS_MeshNode* n2 = nodes[di*1];
+  const SMDS_MeshNode* n3 = nodes[di*2];
 
-  SMDS_ElemIteratorPtr eIt = nodes[0]->GetInverseElementIterator( SMDSAbs_Volume );
+  SMDS_ElemIteratorPtr eIt = n1->GetInverseElementIterator( SMDSAbs_Volume );
   SMDS_ElemIteratorPtr nIt;
   while ( eIt->more() ) {
     const SMDS_MeshElement* vol = eIt->next();
-    if ( vol != myVolume ) {
-      size_t nbShared = 0;
-      if ( const SMDS_VtkVolume* v = dynamic_cast< const SMDS_VtkVolume* >( vol ))
-        nIt = v->uniqueNodesIterator();
-      else
-        nIt = vol->nodesIterator();
-      while ( nIt->more() )
-        if (( nbShared += nodeSet.count( nIt->next() )) == nodeSet.size() )
-        {
-          if ( otherVol ) *otherVol = vol;
-          return !isFree;
-        }
+    if ( vol != myVolume &&
+         vol->GetNodeIndex( n2 ) >= 0 &&
+         vol->GetNodeIndex( n3 ) >= 0 )
+    {
+      if ( otherVol ) *otherVol = vol;
+      return !isFree;
     }
   }
   if ( otherVol ) *otherVol = 0;
index 8fe8bae..c504b35 100644 (file)
@@ -3803,8 +3803,8 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( SMESHOp::OpCopyMesh,             "COPY_MESH",               "ICON_COPY_MESH" );
   createSMESHAction( SMESHOp::OpCompute,              "COMPUTE",                 "ICON_COMPUTE" );
   createSMESHAction( SMESHOp::OpPreCompute,           "PRECOMPUTE",              "ICON_PRECOMPUTE" );
-  createSMESHAction( SMESHOp::OpEvaluate,             "EVALUATE",                "ICON_COMPUTE" );
-  createSMESHAction( SMESHOp::OpMeshOrder,            "MESH_ORDER",              "ICON_COMPUTE" );
+  createSMESHAction( SMESHOp::OpEvaluate,             "EVALUATE",                "ICON_EVALUATE" );
+  createSMESHAction( SMESHOp::OpMeshOrder,            "MESH_ORDER",              "ICON_MESH_ORDER");
   createSMESHAction( SMESHOp::OpCreateGroup,          "CREATE_GROUP",            "ICON_CREATE_GROUP" );
   createSMESHAction( SMESHOp::OpCreateGeometryGroup,  "CREATE_GEO_GROUP",        "ICON_CREATE_GEO_GROUP" );
   createSMESHAction( SMESHOp::OpConstructGroup,       "CONSTRUCT_GROUP",         "ICON_CONSTRUCT_GROUP" );
index b654b3c..bc2629a 100644 (file)
@@ -105,7 +105,7 @@ void SMESHGUI_ConvToQuadOp::startOperation()
 
   SMESHGUI_SelectionOp::startOperation();
 
-  myDlg->SetMediumNdsOnGeom( false );
+  myDlg->SetMediumNdsOnGeom( true );
   myDlg->activateObject( 0 );
   myDlg->ShowWarning( false );
   myDlg->show();
index fdae2f5..9445167 100644 (file)
@@ -730,6 +730,17 @@ void SMESHGUI_GroupDlg::updateButtons()
     }
   }
 
+  bool meshHasGeom = ( myMesh->_is_nil() || myMesh->HasShapeToMesh() );
+  if ( myGrpTypeId != 1 )
+  {
+    myGrpTypeGroup->button(1)->setEnabled( meshHasGeom );
+  }
+  else
+  {
+    myGeomGroupBtn->setEnabled( meshHasGeom );
+    myGeomGroupLine->setEnabled( meshHasGeom );
+  }
+
   myOKBtn->setEnabled(enable);
   myApplyBtn->setEnabled(enable);
 }
index ee55c50..36b29d8 100644 (file)
@@ -151,7 +151,7 @@ void SMESHGUI_GenericHypothesisCreator::editHypothesis( SMESH::SMESH_Hypothesis_
   }
   else {
     emit finished( QDialog::Accepted );
-        delete myDlg;
+    delete myDlg;
   }
 }
 
@@ -247,6 +247,12 @@ QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame()
       changeWidgets().append( w );
     }
   }
+  if ( QWidget* w = getHelperWidget() )
+  {
+    w->setParent( fr );
+    w->move( QPoint( 0, 0 ) );
+    lay->addWidget( w );
+  }
 
   return fr;
 }
@@ -514,6 +520,17 @@ QWidget* SMESHGUI_GenericHypothesisCreator::getCustomWidget( const StdParam & /*
 {
   return 0;
 }
+//================================================================================
+/*!
+ * \brief Returns a widget representing not a hypothesis parameter but some helper widget
+ */
+//================================================================================
+
+QWidget* SMESHGUI_GenericHypothesisCreator::getHelperWidget() const
+{
+  return 0;
+}
+
 bool SMESHGUI_GenericHypothesisCreator::getParamFromCustomWidget( StdParam&, QWidget* ) const
 {
   return false;
index 6d6d275..c431014 100644 (file)
@@ -114,6 +114,7 @@ protected:
   virtual void                 attuneStdWidget( QWidget*, const int ) const;
   virtual QWidget*             getCustomWidget( const StdParam&, 
                                                 QWidget*, const int ) const;
+  virtual QWidget*             getHelperWidget() const;
   virtual bool                 getParamFromCustomWidget( StdParam&, QWidget* ) const;
   virtual void                 valueChanged( QWidget* );
   virtual QString              caption() const;
index dac19af..c98495e 100644 (file)
@@ -658,7 +658,7 @@ void SMESHGUI_MeshOp::selectionDone()
           {
             selectionMgr()->clearFilters();
             selectObject( pSubmesh );
-            SMESHGUI::GetSMESHGUI()->switchToOperation(704);
+            SMESHGUI::GetSMESHGUI()->switchToOperation( SMESHOp::OpEditMeshOrSubMesh );
             return;
           }
           else
index 7da6cad..ead04a8 100644 (file)
             <translation>mesh_compute.png</translation>
         </message>
         <message>
+            <source>ICON_EVALUATE</source>
+            <translation>mesh_evaluate.png</translation>
+        </message>
+        <message>
+            <source>ICON_MESH_ORDER</source>
+            <translation>mesh_order.png</translation>
+        </message>
+        <message>
             <source>ICON_PRECOMPUTE</source>
             <translation>mesh_precompute.png</translation>
         </message>
index baf5fb8..ee06a2e 100644 (file)
@@ -5167,7 +5167,7 @@ Please select valid object and try again</translation>
     </message>
     <message>
         <source>CURRENT_DIALOG</source>
-        <translation>Current Group</translation>
+        <translation>Current Dialog</translation>
     </message>
     <message>
         <source>EDGES_TLT</source>
index f01a226..be0c2a4 100644 (file)
@@ -82,6 +82,7 @@ SET(_moc_HEADERS
   StdMeshersGUI_SubShapeSelectorWdg.h
   StdMeshersGUI_CartesianParamCreator.h
   StdMeshersGUI_RadioButtonsGrpWdg.h
+  StdMeshersGUI_PropagationHelperWdg.h
 )
 
 # header files / no moc processing
@@ -111,6 +112,7 @@ SET(_other_SOURCES
   StdMeshersGUI_SubShapeSelectorWdg.cxx
   StdMeshersGUI_CartesianParamCreator.cxx
   StdMeshersGUI_RadioButtonsGrpWdg.cxx
+  StdMeshersGUI_PropagationHelperWdg.cxx
 )
 
 # sources / to compile
index be7c99d..ec15db3 100644 (file)
@@ -25,8 +25,9 @@
 // SMESH includes
 //
 #include "StdMeshersGUI_NbSegmentsCreator.h"
-#include "StdMeshersGUI_DistrTable.h"
 #include "StdMeshersGUI_DistrPreview.h"
+#include "StdMeshersGUI_DistrTable.h"
+#include "StdMeshersGUI_PropagationHelperWdg.h"
 #include "StdMeshersGUI_SubShapeSelectorWdg.h"
 
 #include <SMESHGUI.h>
@@ -214,15 +215,21 @@ QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame()
   QString aMainEntry = getMainShapeEntry();
   if ( aGeomEntry == "" )
     aGeomEntry = h->GetObjectEntry();
-  myDirectionWidget->SetGeomShapeEntry( aGeomEntry );
-  myDirectionWidget->SetMainShapeEntry( aMainEntry );
+  myDirectionWidget->SetGeomShapeEntry( aGeomEntry, aMainEntry );
   myDirectionWidget->SetListOfIDs( h->GetReversedEdges() );
   edgeLay->addWidget( myDirectionWidget );
 
   lay->addWidget( myReversedEdgesBox );
-  lay->setStretchFactor( GroupC1, 2);
+  lay->setStretchFactor( GroupC1, 1);
   lay->setStretchFactor( myReversedEdgesBox, 1);
-  
+
+  if ( !aGeomEntry.isEmpty() || !aMainEntry.isEmpty() )
+  {
+    myReversedEdgesHelper = new StdMeshersGUI_PropagationHelperWdg( myDirectionWidget, fr );
+    lay->addWidget( myReversedEdgesHelper );
+    lay->setStretchFactor( myReversedEdgesHelper, 1 );
+  }
+
   connect( myNbSeg, SIGNAL( valueChanged( const QString& ) ), this, SLOT( onValueChanged() ) );
   connect( myDistr, SIGNAL( activated( int ) ), this, SLOT( onValueChanged() ) );
   connect( myTable, SIGNAL( valueChanged( int, int ) ), this, SLOT( onValueChanged() ) );
@@ -432,7 +439,9 @@ void StdMeshersGUI_NbSegmentsCreator::onValueChanged()
   myScale->setShown( distr==1 );
   myLScale->setShown( distr==1 );
   myReversedEdgesBox->setShown( !distr==0 );
-  myDirectionWidget->showPreview( !distr==0 );
+  myDirectionWidget->ShowPreview( !distr==0 );
+  if ( myReversedEdgesHelper )
+    myReversedEdgesHelper->setShown( !distr==0 );
 
   bool isFunc = distr==2 || distr==3;
   myPreview->setShown( isFunc );
index f88a0cd..61dc604 100644 (file)
@@ -96,6 +96,7 @@ private:
   QGroupBox*       myReversedEdgesBox;
 
   StdMeshersGUI_SubShapeSelectorWdg*    myDirectionWidget;
+  QWidget*                              myReversedEdgesHelper;
 };
 
 #endif // STDMESHERSGUI_NBSEGMENTSCREATOR_H
diff --git a/src/StdMeshersGUI/StdMeshersGUI_PropagationHelperWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_PropagationHelperWdg.cxx
new file mode 100644 (file)
index 0000000..1105299
--- /dev/null
@@ -0,0 +1,485 @@
+// Copyright (C) 2007-2015  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
+//
+// File      : StdMeshersGUI_PropagationHelperWdg.cxx
+// Created   : Thu Mar 19 18:46:24 2015
+// Author    : Edward AGAPOV (eap)
+
+#include "StdMeshersGUI_PropagationHelperWdg.h"
+
+#include "StdMeshersGUI_SubShapeSelectorWdg.h"
+#include "SMESH_PreviewActorsCollection.h"
+#include "SMESHGUI_VTKUtils.h"
+
+#include <GEOM_Actor.h>
+
+#include <LightApp_SelectionMgr.h>
+#include <SUIT_OverrideCursor.h>
+#include <SVTK_ViewWindow.h>
+#include <vtkRenderer.h>
+
+#include <QCheckBox>
+#include <QGridLayout>
+#include <QGroupBox>
+#include <QLabel>
+#include <QList>
+#include <QListWidget>
+#include <QListWidgetItem>
+#include <QPushButton>
+
+#include <BRepTools_WireExplorer.hxx>
+#include <BRep_Builder.hxx>
+#include <NCollection_DataMap.hxx>
+#include <TColStd_IndexedMapOfInteger.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Iterator.hxx>
+
+#include <set>
+
+#define SPACING 6
+#define MARGIN 11
+
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+StdMeshersGUI_PropagationHelperWdg::
+StdMeshersGUI_PropagationHelperWdg( StdMeshersGUI_SubShapeSelectorWdg* subSelectWdg,
+                                    QWidget*                           parent ):
+  QWidget( parent ), mySubSelectWdg( subSelectWdg ), myActor( 0 ), myModelActor( 0 )
+{
+  QGroupBox* helperBox      = new QGroupBox( tr("HELPER"), this );
+  QCheckBox* showGeomChkBox = new QCheckBox( tr("SHOW_GEOMETRY"), helperBox );
+  QGroupBox* chainBox       = new QGroupBox( tr("PROPAGATION_CHAINS"), helperBox );
+  chainBox->setCheckable( true );
+  chainBox->setChecked( false );
+  myListWidget              = new QListWidget( helperBox );
+  myListWidget->setSelectionMode( QAbstractItemView::SingleSelection );
+  myAddButton               = new QPushButton( tr("ADD"), helperBox );
+  myReverseButton           = new QPushButton( tr("REVERSE"), helperBox );
+
+  QGridLayout* chainsLayout = new QGridLayout( chainBox );
+  chainsLayout->setMargin( MARGIN );
+  chainsLayout->setSpacing( SPACING );
+  chainsLayout->addWidget(myListWidget,    0, 0, 3, 3);
+  chainsLayout->addWidget(myAddButton,     0, 3);
+  chainsLayout->addWidget(myReverseButton, 1, 3);
+
+  QVBoxLayout* helperLayout = new QVBoxLayout( helperBox );
+  helperLayout->setMargin( MARGIN );
+  helperLayout->setSpacing( SPACING );
+  helperLayout->addWidget( showGeomChkBox );
+  helperLayout->addWidget( chainBox );
+
+  QVBoxLayout* lay = new QVBoxLayout( this );
+  lay->setMargin( 0 );
+  lay->setSpacing( SPACING );
+  lay->addWidget( helperBox );
+
+  connect( showGeomChkBox,  SIGNAL( toggled(bool)), SLOT( onShowGeometry(bool)));
+  connect( chainBox,        SIGNAL( toggled(bool)), SLOT( updateList(bool)));
+  connect( myListWidget,    SIGNAL( itemSelectionChanged()), SLOT( onListSelectionChanged() ));
+  connect( myAddButton,     SIGNAL( clicked(bool)), SLOT( onAdd() ));
+  connect( myReverseButton, SIGNAL( clicked(bool)), SLOT( onReverse() ));
+
+  onListSelectionChanged();
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+StdMeshersGUI_PropagationHelperWdg::~StdMeshersGUI_PropagationHelperWdg()
+{
+  if ( myActor )
+  {
+    myActor->RemoveFromRender( myRenderer );
+    myActor->Delete();
+    myActor = 0;
+  }
+  if ( myModelActor )
+  {
+    myModelActor->RemoveFromRender( myRenderer );
+    myModelActor->Delete();
+    myModelActor = 0;
+  }
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when 'Show Geometry' is checked
+ */
+//================================================================================
+
+void StdMeshersGUI_PropagationHelperWdg::onShowGeometry(bool toShow)
+{
+  if ( ! myModelActor )
+  {
+    TopoDS_Shape shape     = mySubSelectWdg->GetGeomShape();
+    TopoDS_Shape mainShape = mySubSelectWdg->GetMainShape();
+    if ( shape.IsNull() && mainShape.IsNull() ) return;
+    if ( mainShape.IsNull() ) mainShape = shape;
+
+    SUIT_OverrideCursor wc;
+
+    TopoDS_Compound aCompound;
+    BRep_Builder aBuilder;
+    aBuilder.MakeCompound( aCompound );
+    
+    SMESH_PreviewActorsCollection* previewActor = mySubSelectWdg->GetActorCollection();
+    if ( !previewActor ) return;
+    const QList<int>& egdeIDs = previewActor->GetIndices();
+    for ( QList<int>::const_iterator ieIt = egdeIDs.begin(); ieIt != egdeIDs.end(); ++ieIt )
+    {
+      TopoDS_Shape E = previewActor->GetShapeByIndex( *ieIt );
+      if ( !E.IsNull() && E.ShapeType() == TopAbs_EDGE )
+        aBuilder.Add( aCompound, E );
+    }
+
+    myModelActor = GEOM_Actor::New();
+    myModelActor->SetShape( aCompound, 0, 0 );
+    myModelActor->SetPickable( false );
+    myModelActor->SetIsolatedEdgeColor( 0.5, 0.5, 0.5 );
+
+    if (( myRenderer = mySubSelectWdg->GetRenderer() ))
+      myModelActor->AddToRender( myRenderer );
+  }
+
+  if ( myModelActor )
+    myModelActor->SetVisibility( toShow );
+
+  SMESH::RepaintCurrentView();
+}
+
+//================================================================================
+/*!
+ * \brief Build propagation chains. Return false if no chains found
+ */
+//================================================================================
+
+bool StdMeshersGUI_PropagationHelperWdg::buildChains()
+{
+  if ( !myChains.empty() ) return false;
+
+  if ( !mySubSelectWdg ) return false;
+
+  TopoDS_Shape shape     = mySubSelectWdg->GetGeomShape();
+  TopoDS_Shape mainShape = mySubSelectWdg->GetMainShape();
+  if ( shape.IsNull() && mainShape.IsNull() ) return false;
+
+  if ( shape.IsNull() )     shape = mainShape;
+  if ( mainShape.IsNull() ) mainShape = shape;
+
+  SUIT_OverrideCursor wc;
+
+  // aPreviewActor holds a map od all sub-shapes of mainShape
+  SMESH_PreviewActorsCollection* previewActor = mySubSelectWdg->GetActorCollection();
+  if ( !previewActor ) return false;
+  const QList<int>& egdeIDs = previewActor->GetIndices();
+
+  // Make a 'map' of WIREs of EDGE with quadrilateral WIREs only
+
+  typedef int                        TGeomID; // index in the mainShape
+  typedef std::vector< TGeomID >     TWire; // signed IDs of EDGEs, sign means orientation
+  typedef std::pair< int, TWire* >   TEdgeInWire; // index in TWire + TWire*
+  typedef std::vector< TEdgeInWire > TWiresOfEdge;// WIREs including an EDGE
+
+  std::vector< TWire > quadWires;
+  quadWires.reserve( egdeIDs.count() );
+  NCollection_DataMap< TGeomID, TWiresOfEdge > wiresOfEdge( egdeIDs.count() );
+
+  TopExp_Explorer wire;
+  for ( TopExp_Explorer face( shape, TopAbs_FACE ); face.More(); face.Next() )
+  {
+    wire.Init( face.Current(), TopAbs_WIRE );
+    TopoDS_Shape W = wire.Current().Oriented( TopAbs_FORWARD );
+
+    wire.Next();
+    if ( wire.More() ) continue;
+
+    // count EDGEs
+    int nbE = 0;
+    for ( TopoDS_Iterator edge( W, false, false ); edge.More() && nbE < 5; ++nbE )
+      edge.Next();
+    if ( nbE != 4 ) continue;
+
+    // fill a TWire and TWiresOfEdge
+    quadWires.push_back( TWire() );
+    TWire& wire = quadWires.back();
+    wire.reserve( 4 );
+    for ( BRepTools_WireExplorer edge( TopoDS::Wire( W )); edge.More(); edge.Next() )
+    {
+      const TopoDS_Shape& E = edge.Current();
+      int iE = previewActor->GetIndexByShape( E );
+      if ( iE < 1 )
+        continue;
+      if ( !wiresOfEdge.IsBound( iE ))
+        wiresOfEdge.Bind( iE, TWiresOfEdge() );
+      wiresOfEdge( iE ).push_back( TEdgeInWire( wire.size(), & wire ));
+
+      wire.push_back( E.Orientation() == TopAbs_REVERSED ? -iE : iE );
+    }
+  }
+  if ( quadWires.empty() )
+    return false;
+
+  // Find chains
+
+  TColStd_IndexedMapOfInteger chain, chainedEdges;
+
+  // loop on all EDGEs in mainShape
+  for ( QList<TGeomID>::const_iterator ieIt = egdeIDs.begin(); ieIt != egdeIDs.end(); ++ieIt )
+  {
+    if ( chainedEdges.Contains( *ieIt ))
+      continue;
+    // start a new chain
+    chain.Clear();
+    chain.Add( *ieIt );
+    chainedEdges.Add( *ieIt );
+    for ( int iC = 1; iC <= chain.Extent(); ++iC ) // loop on EDGE's in chain
+    {
+      TGeomID iE = chain( iC ), iEAbs = Abs( iE );
+      if ( !wiresOfEdge.IsBound( iEAbs ))
+        continue;
+      const TWiresOfEdge& wires = wiresOfEdge( iEAbs );
+      for (size_t i = 0; i < wires.size(); ++i ) // loop on WIREs sharing iE
+      {
+        const TEdgeInWire& eInW = wires[i];
+        const TWire&    W = *eInW.second;
+        if ( W.size() != 4 ) continue;
+        const int    iInW = eInW.first;
+        const int iInWOpp = ( iInW + 2 ) % 4; // an opposite edge index
+        TGeomID  iEOppAbs = Abs( W[ iInWOpp ] );
+
+        int prevNbChained = chainedEdges.Extent();
+        if ( prevNbChained < chainedEdges.Add( iEOppAbs ))
+        {
+          int dir = iE / iEAbs;
+          bool isSameDir = ( W[ iInW ] * W[ iInWOpp ] < 0 );
+          if ( !isSameDir )
+            dir *= -1;
+          chain.Add( dir * iEOppAbs );
+        }
+      }
+    }
+    // store a chain
+    if ( chain.Extent() > 1 )
+    {
+      myChains.push_back( std::vector< TGeomID >() );
+      std::vector< TGeomID > & ch = myChains.back();
+      for ( int iC = 1; iC <= chain.Extent(); ++iC )
+        ch.push_back( chain( iC ) );
+    }
+  }
+  return !myChains.empty();
+}
+
+//================================================================================
+/*!
+ * \brief Fills myListWidget
+ */
+//================================================================================
+
+void StdMeshersGUI_PropagationHelperWdg::updateList(bool enable)
+{
+  buildChains();
+
+  myListWidget->clear();
+
+  if ( enable )
+  {
+    QListWidgetItem* item;
+    if ( myChains.empty() || !enable )
+    {
+      item = new QListWidgetItem(tr("NO_CHAINS"), myListWidget );
+      item->setData( Qt::UserRole, -1 );
+    }
+    else
+      for ( size_t i = 0; i < myChains.size(); ++i )
+      {
+        QString text = tr( "CHAIN_NUM_NB_EDGES" ).arg( i+1 ).arg( myChains[i].size() );
+        item = new QListWidgetItem( text, myListWidget );
+        item->setData( Qt::UserRole, (int) i );
+      }
+  }
+  else
+  {
+    onListSelectionChanged();
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Returns ids of a selected chain
+ */
+//================================================================================
+
+std::vector< int > * StdMeshersGUI_PropagationHelperWdg::getSelectedChain()
+{
+  std::vector< int > * chain = 0;
+  if ( QListWidgetItem * item = myListWidget->currentItem() )
+  {
+    int i = item->data( Qt::UserRole ).toInt();
+    if ( 0 <= i && i < myChains.size() )
+      chain = & myChains[i];
+  }
+  return chain;
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when a selected chain changes
+ */
+//================================================================================
+
+void StdMeshersGUI_PropagationHelperWdg::onListSelectionChanged()
+{
+  if ( !mySubSelectWdg ) return;
+  SMESH_PreviewActorsCollection* previewActor = mySubSelectWdg->GetActorCollection();
+  if ( !previewActor ) return;
+
+  bool hasReversedEdges = false;
+  const std::vector< int > * chain = getSelectedChain();
+  if ( chain )
+  {
+    SUIT_OverrideCursor wc;
+
+    TopoDS_Compound aCompound;
+    BRep_Builder aBuilder;
+    aBuilder.MakeCompound( aCompound );
+
+    for ( size_t i = 0; i < chain->size(); ++i )
+    {
+      int iE = Abs( (*chain)[ i ]);
+      TopoDS_Shape E = previewActor->GetShapeByIndex( iE );
+      if ( !E.IsNull() && E.ShapeType() == TopAbs_EDGE )
+      {
+        E.Orientation( (*chain)[ i ] < 0 ? TopAbs_REVERSED : TopAbs_FORWARD );
+        aBuilder.Add( aCompound, E );
+        if ( (*chain)[ i ] < 0 )
+          hasReversedEdges = true;
+      }
+    }
+    if ( myActor )
+    {
+      // SetShape() to an existing actor leads to a wrong FitAll
+      myActor->RemoveFromRender( myRenderer );
+      myActor->Delete();
+    }
+    myActor = GEOM_Actor::New();
+    myActor->SetShape( aCompound, 0, true );
+    myActor->SetIsolatedEdgeColor( 1, 0, 1 );
+    myActor->SetWidth( 2 );
+    myActor->SetVectorMode( true );
+    myActor->SetPickable( false );
+
+    if (( myRenderer = mySubSelectWdg->GetRenderer() ))
+      myActor->AddToRender( myRenderer );
+
+    if ( LightApp_SelectionMgr* selMrg = SMESHGUI::selectionMgr())
+    {
+      selMrg->clearSelected();
+      mySubSelectWdg->ClearSelected(); /* call this because the above call does not
+                                          lead to currentSelectionChanged signal (bug?)*/
+    }
+  }
+  bool enableButtons = chain;
+  if ( chain )
+    enableButtons = myListWidget->currentItem()->data( Qt::UserRole+1 ).isNull();
+
+  myAddButton->setEnabled( enableButtons && hasReversedEdges );
+  myReverseButton->setEnabled( enableButtons );
+
+
+  bool toShowChain = chain;
+
+  if ( myActor )
+    myActor->SetVisibility( toShowChain );
+
+  previewActor->SetShown( !toShowChain );
+
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow())
+    aViewWindow->Repaint();
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when 'Add' button is clicked
+ */
+//================================================================================
+
+void StdMeshersGUI_PropagationHelperWdg::onAdd()
+{
+  const std::vector< int > * chain = getSelectedChain();
+  if ( !chain || !mySubSelectWdg ) return;
+
+  // join current and new IDs
+
+  SMESH::long_array_var ids = mySubSelectWdg->GetListOfIDs();
+
+  std::set< int > idSet;
+  for ( int i = 0, nb = ids->length(); i < nb; ++i )
+    idSet.insert( idSet.end(), ids[i] );
+
+  for ( size_t i = 0; i < chain->size(); ++i )
+    if ( (*chain)[ i ] < 0 )
+      idSet.insert( -1 * (*chain)[ i ]);
+
+  if ( ids->length() != idSet.size() )
+  {
+    ids->length( idSet.size() );
+    std::set< int >::iterator id = idSet.begin();
+    for ( int i = 0, nb = ids->length(); i < nb; ++i, ++id )
+      ids[ i ] = *id;
+
+    mySubSelectWdg->SetListOfIDs( ids );
+  }
+  mySubSelectWdg->ClearSelected();
+
+  if ( QListWidgetItem * item = myListWidget->currentItem() )
+  {
+    //delete item;
+    item->setForeground( QBrush( QColor( 100, 100, 100 )));
+    item->setData( Qt::UserRole+1, 1 );
+  }
+  myAddButton->setEnabled( false );
+  myReverseButton->setEnabled( false );
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when 'Reverse' button is clicked
+ */
+//================================================================================
+
+void StdMeshersGUI_PropagationHelperWdg::onReverse()
+{
+  if ( std::vector< int > * chain = getSelectedChain())
+  {
+    for ( size_t i = 0; i < chain->size(); ++i )
+      (*chain)[ i ] *= -1;
+
+    onListSelectionChanged();
+  }
+}
diff --git a/src/StdMeshersGUI/StdMeshersGUI_PropagationHelperWdg.h b/src/StdMeshersGUI/StdMeshersGUI_PropagationHelperWdg.h
new file mode 100644 (file)
index 0000000..b0b5ad9
--- /dev/null
@@ -0,0 +1,74 @@
+// Copyright (C) 2007-2015  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 STDMESHERSGUI_PropagationHelperWdg_H
+#define STDMESHERSGUI_PropagationHelperWdg_H
+
+#include "SMESH_StdMeshersGUI.hxx"
+
+#include <QWidget>
+#include <vector>
+
+class QPushButton;
+class QListWidget;
+class StdMeshersGUI_SubShapeSelectorWdg;
+class vtkRenderer;
+class GEOM_Actor;
+
+/*!
+ * \brief A widget showing a list of propagation chains of EDGEs.
+ * Selecting a chain shows its EDGEs in a viewer with all EDGEs equally oriented,
+ * 'Reverse' button reverses the EDGEs of a selected chain. 'Add' button adds
+ *  EDGEs to a list of reversed EDGEs of StdMeshersGUI_SubShapeSelectorWdg
+ */
+class STDMESHERSGUI_EXPORT StdMeshersGUI_PropagationHelperWdg : public QWidget
+{
+  Q_OBJECT
+
+ public:
+  StdMeshersGUI_PropagationHelperWdg( StdMeshersGUI_SubShapeSelectorWdg* subSelectWdg,
+                                      QWidget* parent = 0 );
+  ~StdMeshersGUI_PropagationHelperWdg();
+
+ private slots:
+
+  void                           onShowGeometry(bool toShow);
+  void                           onListSelectionChanged();
+  void                           onAdd(); 
+  void                           onReverse(); 
+  void                           updateList(bool enable);
+
+ private:
+
+  bool                           buildChains();
+  std::vector< int > *           getSelectedChain();
+
+  StdMeshersGUI_SubShapeSelectorWdg* mySubSelectWdg;
+  vtkRenderer*                       myRenderer;
+  GEOM_Actor*                        myActor;
+  GEOM_Actor*                        myModelActor;
+
+  QListWidget*                   myListWidget;
+  QPushButton*                   myAddButton;
+  QPushButton*                   myReverseButton;
+
+  std::vector< std::vector<int> >    myChains;
+};
+
+#endif
index 0823ba2..c52f360 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "SMESHGUI.h"
 #include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_Utils.h"
 #include "StdMeshersGUI_SubShapeSelectorWdg.h"
 
 #include <GEOMBase.h>
@@ -194,8 +195,7 @@ void StdMeshersGUI_QuadrangleParamCreator::retrieveParams() const
   QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
   if ( anEntry.isEmpty() )
     anEntry = h->GetObjectEntry();
-  myVertexSelWdg->SetGeomShapeEntry(anEntry);
-  myVertexSelWdg->SetMainShapeEntry(aMainEntry);
+  myVertexSelWdg->SetGeomShapeEntry(anEntry,aMainEntry);
 
   if ( !isCreation())
   {
@@ -407,7 +407,7 @@ void StdMeshersGUI_QuadrangleParamCreator::onSelectionChanged()
 
 void StdMeshersGUI_QuadrangleParamCreator::onTabChanged(int i)
 {
-  myVertexSelWdg->showPreview( i == TAB_VERTEX );
+  myVertexSelWdg->ShowPreview( i == TAB_VERTEX );
 }
 
 //================================================================================
index a3b94c0..5f38e7f 100644 (file)
 #include "StdMeshersGUI_FixedPointsParamWdg.h"
 #include "StdMeshersGUI_LayerDistributionParamWdg.h"
 #include "StdMeshersGUI_ObjectReferenceParamWdg.h"
+#include "StdMeshersGUI_PropagationHelperWdg.h"
 #include "StdMeshersGUI_QuadrangleParamWdg.h"
-#include "StdMeshersGUI_SubShapeSelectorWdg.h"
 #include "StdMeshersGUI_RadioButtonsGrpWdg.h"
+#include "StdMeshersGUI_SubShapeSelectorWdg.h"
 
 #include <SALOMEDSClient_Study.hxx>
 
@@ -77,7 +78,7 @@ const double VALUE_MAX = 1.0e+15, // COORD_MAX
 //================================================================================
 
 StdMeshersGUI_StdHypothesisCreator::StdMeshersGUI_StdHypothesisCreator( const QString& type )
-: SMESHGUI_GenericHypothesisCreator( type )
+  : SMESHGUI_GenericHypothesisCreator( type ), myHelperWidget( 0 )
 {
 }
 
@@ -883,18 +884,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     item.myName = tr( "SMESH_REVERSED_EDGES" );
     p.append( item );
 
-    StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget =
-      new StdMeshersGUI_SubShapeSelectorWdg();
-    QString aGeomEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry();
-    QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
-    if ( aGeomEntry == "" )
-      aGeomEntry = h->GetObjectEntry();
-
-    aDirectionWidget->SetGeomShapeEntry( aGeomEntry );
-    aDirectionWidget->SetMainShapeEntry( aMainEntry );
-    aDirectionWidget->SetListOfIDs( h->GetReversedEdges() );
-    aDirectionWidget->showPreview( true );
-    customWidgets()->append ( aDirectionWidget );
+    customWidgets()->append ( makeReverseEdgesWdg( h->GetReversedEdges(), h->GetObjectEntry() ));
   }
 
   else if( hypType()=="GeometricProgression" )
@@ -919,18 +909,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     item.myName = tr( "SMESH_REVERSED_EDGES" );
     p.append( item );
 
-    StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget =
-      new StdMeshersGUI_SubShapeSelectorWdg();
-    QString aGeomEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry();
-    QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
-    if ( aGeomEntry == "" )
-      aGeomEntry = h->GetObjectEntry();
-
-    aDirectionWidget->SetGeomShapeEntry( aGeomEntry );
-    aDirectionWidget->SetMainShapeEntry( aMainEntry );
-    aDirectionWidget->SetListOfIDs( h->GetReversedEdges() );
-    aDirectionWidget->showPreview( true );
-    customWidgets()->append ( aDirectionWidget );
+    customWidgets()->append ( makeReverseEdgesWdg( h->GetReversedEdges(), h->GetObjectEntry() ));
   }
 
   else if( hypType()=="FixedPoints1D" )
@@ -953,17 +932,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     item.myName = tr( "SMESH_REVERSED_EDGES" );
     p.append( item );
 
-    StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget =
-      new StdMeshersGUI_SubShapeSelectorWdg();
-    QString anEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry();
-    QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
-    if ( anEntry == "" )
-      anEntry = h->GetObjectEntry();
-    aDirectionWidget->SetGeomShapeEntry( anEntry );
-    aDirectionWidget->SetMainShapeEntry( aMainEntry );
-    aDirectionWidget->SetListOfIDs( h->GetReversedEdges() );
-    aDirectionWidget->showPreview( true );
-    customWidgets()->append ( aDirectionWidget );
+    customWidgets()->append ( makeReverseEdgesWdg( h->GetReversedEdges(), h->GetObjectEntry() ));
   }
 
 
@@ -976,7 +945,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     if(!initVariableName( hyp, item, "SetMaxElementArea" ))
       item.myValue = h->GetMaxElementArea();
     p.append( item );
-    
+
   }
   else if( hypType()=="MaxElementVolume" )
   {
@@ -995,13 +964,13 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
 
     item.myName = tr( "SMESH_START_LENGTH_PARAM" );
 
-    if(!initVariableName( hyp, item, "SetStartLength" )) 
+    if(!initVariableName( hyp, item, "SetStartLength" ))
       item.myValue = h->GetLength( true );
     p.append( item );
     customWidgets()->append(0);
 
     item.myName = tr( "SMESH_END_LENGTH_PARAM" );
-    if(!initVariableName( hyp, item, "SetEndLength" )) 
+    if(!initVariableName( hyp, item, "SetEndLength" ))
       item.myValue = h->GetLength( false );
     p.append( item );
     customWidgets()->append(0);
@@ -1009,17 +978,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     item.myName = tr( "SMESH_REVERSED_EDGES" );
     p.append( item );
 
-    StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget =
-      new StdMeshersGUI_SubShapeSelectorWdg();
-    QString anEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry();
-    QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
-    if ( anEntry == "" )
-      anEntry = h->GetObjectEntry();
-    aDirectionWidget->SetGeomShapeEntry( anEntry );
-    aDirectionWidget->SetMainShapeEntry( aMainEntry );
-    aDirectionWidget->SetListOfIDs( h->GetReversedEdges() );
-    aDirectionWidget->showPreview( true );
-    customWidgets()->append ( aDirectionWidget );
+    customWidgets()->append ( makeReverseEdgesWdg( h->GetReversedEdges(), h->GetObjectEntry() ));
   }
   else if( hypType()=="Deflection1D" )
   {
@@ -1027,7 +986,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
       StdMeshers::StdMeshers_Deflection1D::_narrow( hyp );
 
     item.myName = tr( "SMESH_DEFLECTION1D_PARAM" );
-    if(!initVariableName( hyp, item, "SetDeflection" )) 
+    if(!initVariableName( hyp, item, "SetDeflection" ))
       item.myValue = h->GetDeflection();
     p.append( item );
   }
@@ -1037,17 +996,17 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
       StdMeshers::StdMeshers_Adaptive1D::_narrow( hyp );
 
     item.myName = tr( "SMESH_MIN_SIZE" );
-    if(!initVariableName( hyp, item, "SetMinSize" )) 
+    if(!initVariableName( hyp, item, "SetMinSize" ))
       item.myValue = h->GetMinSize();
     p.append( item );
 
     item.myName = tr( "SMESH_MAX_SIZE" );
-    if(!initVariableName( hyp, item, "SetMaxSize" )) 
+    if(!initVariableName( hyp, item, "SetMaxSize" ))
       item.myValue = h->GetMaxSize();
     p.append( item );
 
     item.myName = tr( "SMESH_DEFLECTION1D_PARAM" );
-    if(!initVariableName( hyp, item, "SetDeflection" )) 
+    if(!initVariableName( hyp, item, "SetDeflection" ))
       item.myValue = h->GetDeflection();
     p.append( item );
   }
@@ -1279,11 +1238,10 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
       StdMeshersGUI_SubShapeSelectorWdg* idsWg =
         new StdMeshersGUI_SubShapeSelectorWdg(0,TopAbs_FACE);
 
-      idsWg->SetMainShapeEntry( aMainEntry );
-      idsWg->SetGeomShapeEntry( aSubEntry.isEmpty() ? aMainEntry : aSubEntry );
+      idsWg->SetGeomShapeEntry( aSubEntry, aMainEntry );
       if ( idsWg->SetListOfIDs( h->GetFaces() ))
       {
-        idsWg->showPreview( true );
+        idsWg->ShowPreview( true );
       }
       else
       {
@@ -1338,11 +1296,10 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
       StdMeshersGUI_SubShapeSelectorWdg* idsWg =
         new StdMeshersGUI_SubShapeSelectorWdg(0,TopAbs_EDGE);
 
-      idsWg->SetMainShapeEntry( aMainEntry );
-      idsWg->SetGeomShapeEntry( aSubEntry.isEmpty() ? aMainEntry : aSubEntry );
+      idsWg->SetGeomShapeEntry( aSubEntry, aMainEntry );
       if ( idsWg->SetListOfIDs( h->GetEdges() ))
       {
-        idsWg->showPreview( true );
+        idsWg->ShowPreview( true );
       }
       else
       {
@@ -1352,46 +1309,6 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
       customWidgets()->append ( idsWg );
     }
   }
-  // else if (hypType() == "QuadrangleParams")
-  // {
-  //   StdMeshers::StdMeshers_QuadrangleParams_var h =
-  //     StdMeshers::StdMeshers_QuadrangleParams::_narrow(hyp);
-
-  //   item.myName = tr("SMESH_BASE_VERTEX");
-  //   p.append(item);
-
-  //   StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget =
-  //     new StdMeshersGUI_SubShapeSelectorWdg(0, TopAbs_VERTEX);
-  //   aDirectionWidget->SetMaxSize(1);
-  //   QString anEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry();
-  //   QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
-  //   if (anEntry == "")
-  //     anEntry = h->GetObjectEntry();
-  //   aDirectionWidget->SetGeomShapeEntry(anEntry);
-  //   aDirectionWidget->SetMainShapeEntry(aMainEntry);
-  //   if (!isCreation()) {
-  //     SMESH::long_array_var aVec = new SMESH::long_array;
-  //     int vertID = h->GetTriaVertex();
-  //     if (vertID > 0) {
-  //       aVec->length(1);
-  //       aVec[0] = vertID;
-  //       aDirectionWidget->SetListOfIDs(aVec);
-  //     }
-  //   }
-  //   aDirectionWidget->showPreview(true);
-
-  //   item.myName = tr("SMESH_QUAD_TYPE");
-  //   p.append(item);
-
-  //   StdMeshersGUI_QuadrangleParamWdg* aTypeWidget =
-  //     new StdMeshersGUI_QuadrangleParamWdg();
-  //   if (!isCreation()) {
-  //     aTypeWidget->SetType(int(h->GetQuadType()));
-  //   }
-
-  //   customWidgets()->append(aDirectionWidget);
-  //   customWidgets()->append(aTypeWidget);
-  // }
   else
     res = false;
   return res;
@@ -1728,3 +1645,34 @@ bool StdMeshersGUI_StdHypothesisCreator::initVariableName(SMESH::SMESH_Hypothesi
 
   return theParams.isVariable;
 }
+
+//================================================================================
+/*!
+ * \brief Creates two widgets used to define reversed edges for some 1D hypotheses
+ *  \param [in] edgeIDs - ids of reversed edges to set to the widgets
+ *  \param [in] shapeEntry - entry of a sub-shape of a sub-mesh if any
+ *  \return QWidget* - new StdMeshersGUI_SubShapeSelectorWdg; 
+ *          new StdMeshersGUI_PropagationHelperWdg is stored in \a myHelperWidget field.
+ */
+//================================================================================
+
+QWidget*
+StdMeshersGUI_StdHypothesisCreator::makeReverseEdgesWdg( SMESH::long_array_var edgeIDs,
+                                                         CORBA::String_var     shapeEntry) const
+{
+  QString aGeomEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry();
+  QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
+  if ( aGeomEntry.isEmpty() && shapeEntry.in() )
+    aGeomEntry = shapeEntry.in();
+
+  StdMeshersGUI_SubShapeSelectorWdg* wdg = new StdMeshersGUI_SubShapeSelectorWdg();
+  wdg->SetGeomShapeEntry( aGeomEntry, aMainEntry );
+  wdg->SetListOfIDs( edgeIDs );
+  wdg->ShowPreview( true );
+
+  if ( !aGeomEntry.isEmpty() || !aMainEntry.isEmpty() )
+    const_cast<StdMeshersGUI_StdHypothesisCreator*>( this )->
+      myHelperWidget = new StdMeshersGUI_PropagationHelperWdg( wdg );
+
+  return wdg;
+}
index d9e82ec..b9e22ae 100644 (file)
@@ -54,15 +54,20 @@ protected:
   virtual QPixmap  icon() const;
   virtual QString  type() const;
   virtual QWidget* getCustomWidget( const StdParam&, QWidget*, const int ) const;
+  virtual QWidget* getHelperWidget() const { return myHelperWidget; }
   virtual bool     getParamFromCustomWidget( StdParam& , QWidget* ) const;
 
   virtual QString  hypTypeName( const QString& ) const;
   virtual QWidget* getWidgetForParam( int paramIndex ) const;
   virtual ListOfWidgets* customWidgets() const;
   virtual void     onReject();
+  virtual void     valueChanged( QWidget* );
+
   bool             initVariableName(SMESH::SMESH_Hypothesis_var theHyp, StdParam& theParams, const char* theMethod) const;
+  QWidget*         makeReverseEdgesWdg( SMESH::long_array_var edgeIDs,
+                                        CORBA::String_var     shapeEntry) const;
+  
 
-  virtual void     valueChanged( QWidget* );
 
   template<class T>
     T* widget(int i) const {
@@ -70,6 +75,7 @@ protected:
   }
 
   ListOfWidgets    myCustomWidgets;
+  QWidget*         myHelperWidget;
 };
 
 #endif // STDMESHERSGUI_STDHYPOTHESISCREATOR_H
index 551fe76..af60f62 100644 (file)
 #include "StdMeshersGUI_SubShapeSelectorWdg.h"
 
 // SMESH Includes
-#include "SMESH_Type.h"
-#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
 #include "SMESH_Actor.h"
-#include "SMESH_PreviewActorsCollection.h"
-#include "SMESH_ActorUtils.h"
-#include "SMESHGUI_GroupUtils.h"
 #include "SMESH_Gen_i.hxx"
-#include "SMESHGUI_GEOMGenUtils.h"
 #include "SMESH_LogicalFilter.hxx"
-
-// SVTK Includes
-#include <SVTK_ViewWindow.h>
-#include <SVTK_ViewModel.h>
-#include <SVTK_ViewWindow.h>
-#include <SVTK_Selector.h>
+#include "SMESH_PreviewActorsCollection.h"
+#include "SMESH_Type.h"
 
 // SALOME GUI includes
-#include <SALOME_ListIO.hxx>
 #include <LightApp_SelectionMgr.h>
-
-// SUIT Includes
+#include <SALOME_ListIO.hxx>
+#include <SUIT_OverrideCursor.h>
 #include <SUIT_ResourceMgr.h>
+#include <SVTK_Selector.h>
+#include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
 
 // GEOM Includes
 #include <GEOMBase.h>
 
 // OCCT includes
 #include <TColStd_MapOfInteger.hxx>
-#include <TColStd_IndexedMapOfInteger.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
-#include <StdSelect_TypeOfEdge.hxx>
 
 
 #define SPACING 6
@@ -91,7 +83,7 @@ StdMeshersGUI_SubShapeSelectorWdg
   
   myListWidget   = new QListWidget( this );
   myAddButton    = new QPushButton( tr( "SMESH_BUT_ADD" ),    this );
-  myRemoveButton = new QPushButton( tr( "SMESH_BUT_REMOVE" ), this );      
+  myRemoveButton = new QPushButton( tr( "SMESH_BUT_REMOVE" ), this );
   myInfoLabel    = new QLabel( this );
   myPrevButton   = new QPushButton( "<<", this );
   myNextButton   = new QPushButton( ">>", this );
@@ -178,7 +170,7 @@ void StdMeshersGUI_SubShapeSelectorWdg::init()
   connect( myPrevButton,   SIGNAL(clicked()), SLOT(onPrevious()));
   connect( myNextButton,   SIGNAL(clicked()), SLOT(onNext()));
   
-  connect( mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+  connect( mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(selectionIntoArgument()));
   connect( myListWidget,   SIGNAL(itemSelectionChanged()),    this, SLOT(onListSelectionChanged()));
 
   updateState();
@@ -208,7 +200,7 @@ void StdMeshersGUI_SubShapeSelectorWdg::setFilter()
  */
 //================================================================================
 
-void StdMeshersGUI_SubShapeSelectorWdg::showPreview( bool visible)
+void StdMeshersGUI_SubShapeSelectorWdg::ShowPreview( bool visible)
 {
   if ( !myPreviewActor )
     return;
@@ -223,11 +215,24 @@ void StdMeshersGUI_SubShapeSelectorWdg::showPreview( bool visible)
   }
 }
 
+//================================================================================
+/*!
+ * \brief Clears selected IDs. This is a workaround of a bug that
+ *        SUIT_SelectionMgr::clearSelected() does not emit currentSelectionChanged
+ */
+//================================================================================
+
+void StdMeshersGUI_SubShapeSelectorWdg::ClearSelected()
+{
+  mySelectedIDs.clear();
+  selectionIntoArgument();
+}
+
 //=================================================================================
-// function : SelectionIntoArgument()
+// function : selectionIntoArgument()
 // purpose  : Called when selection as changed or other case
 //=================================================================================
-void StdMeshersGUI_SubShapeSelectorWdg::SelectionIntoArgument()
+void StdMeshersGUI_SubShapeSelectorWdg::selectionIntoArgument()
 {
   if ( !myPreviewActor )
     return;
@@ -241,10 +246,11 @@ void StdMeshersGUI_SubShapeSelectorWdg::SelectionIntoArgument()
 
   if (nbSel > 0) {
     SALOME_ListIteratorOfListIO anIt (aList);
-    
-    for ( ; anIt.More(); anIt.Next()) { // Loop on selected objects
+
+    for ( ; anIt.More(); anIt.Next()) // Loop on selected objects
+    {
       Handle(SALOME_InteractiveObject) IO = anIt.Value();
-      
+
       GEOM::GEOM_Object_var aGeomObj = GetGeomObjectByEntry( IO->getEntry() );
       if ( !CORBA::is_nil( aGeomObj ) ) { // Selected Object From Study
         GEOM::GEOM_Object_var aGeomFatherObj = aGeomObj->GetMainShape();
@@ -253,7 +259,7 @@ void StdMeshersGUI_SubShapeSelectorWdg::SelectionIntoArgument()
         TopoDS_Shape shape;
         if ( !CORBA::is_nil( aGeomFatherObj ) ) {
           // Get Main Shape
-          GEOM::GEOM_Object_var aGeomMain = GetGeomObjectByEntry( myEntry );
+          GEOM::GEOM_Object_var aGeomMain = GetGeomObjectByEntry( myEntry.c_str() );
           if ( !CORBA::is_nil( aGeomMain ) && aGeomMain->GetType() == 37 ) {  // Main Shape is a Group
             GEOM::GEOM_Object_var aMainFatherObj = aGeomMain->GetMainShape();
             if ( !CORBA::is_nil( aMainFatherObj ) )
@@ -262,10 +268,11 @@ void StdMeshersGUI_SubShapeSelectorWdg::SelectionIntoArgument()
           aFatherEntry = aGeomFatherObj->GetStudyEntry();
         }
 
-        if ( aFatherEntry != "" && ( aFatherEntry == myEntry || aFatherEntry == aMainFatherEntry ) )
+        if (( ! aFatherEntry.isEmpty() ) &&
+            ( aFatherEntry == myEntry.c_str() || aFatherEntry == aMainFatherEntry ) )
         {
           if ( aGeomObj->GetType() == 37 /*GEOM_GROUP*/ ) { // Selected Group that belongs the main object
-            GEOMBase::GetShape(aGeomObj, shape); 
+            GEOMBase::GetShape(aGeomObj, shape);
             if ( !shape.IsNull() ) {
               TopExp_Explorer exp( shape, mySubShType );
               for ( ; exp.More(); exp.Next() ) {
@@ -340,7 +347,9 @@ void StdMeshersGUI_SubShapeSelectorWdg::onAdd()
   }
   onListSelectionChanged();
   myListWidget->blockSignals( false );
-  myAddButton->setEnabled( myMaxSize == -1 || myListOfIDs.size() < myMaxSize );
+
+  mySelectedIDs.clear();
+  myAddButton->setEnabled( false );
 }
          
 //=================================================================================
@@ -367,7 +376,7 @@ void StdMeshersGUI_SubShapeSelectorWdg::onRemove()
   onListSelectionChanged();
   myListWidget->blockSignals( false );
   
-  myAddButton->setEnabled( true );
+  myAddButton->setEnabled( !mySelectedIDs.isEmpty() );
 }
 
 void StdMeshersGUI_SubShapeSelectorWdg::onPrevious()
@@ -416,12 +425,26 @@ void StdMeshersGUI_SubShapeSelectorWdg::onListSelectionChanged()
 // function : setGeomShape
 // purpose  : Called to set geometry whose sub-shapes are selected
 //================================================================================
-void StdMeshersGUI_SubShapeSelectorWdg::SetGeomShapeEntry( const QString& theEntry )
+void StdMeshersGUI_SubShapeSelectorWdg::SetGeomShapeEntry( const QString& theEntry,
+                                                           const QString& theMainShapeEntry )
 {
-  if ( theEntry != "") {
+  if ( !theEntry.isEmpty() || theMainShapeEntry.isEmpty() )
+  {
     myParamValue = theEntry;
-    myEntry = theEntry;
-    myGeomShape = GetTopoDSByEntry( theEntry );
+    myEntry      = theEntry.toStdString();
+    myMainEntry  = theMainShapeEntry.toStdString();
+
+    if ( myMainEntry.empty() ) myMainEntry = myEntry;
+    if ( myEntry.empty() )     myEntry     = myMainEntry;
+    if ( myMainEntry.length() > myEntry.length() &&
+         theMainShapeEntry.startsWith( theEntry ))
+      std::swap( myMainEntry, myEntry );
+
+    myGeomShape = GetTopoDSByEntry( myEntry.c_str() );
+    if ( myEntry == myMainEntry )
+      myMainShape = myGeomShape;
+    else
+      myMainShape = GetTopoDSByEntry( myMainEntry.c_str() );
     updateState();
     myIsNotCorrected = true;
   }
@@ -444,9 +467,10 @@ void StdMeshersGUI_SubShapeSelectorWdg::updateState()
   myAddButton->setEnabled( mySelectedIDs.size() > 0 );
   
   if (state) {
+    SUIT_OverrideCursor wc;
     myPreviewActor = new SMESH_PreviewActorsCollection();
     myPreviewActor->SetSelector( mySelector );
-    myPreviewActor->Init( myGeomShape, mySubShType, myEntry );
+    myPreviewActor->Init( myGeomShape, myMainShape, mySubShType, myEntry.c_str() );
     myPreviewActor->SetShown( false );
     myIsShown = false;
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) {
@@ -499,16 +523,14 @@ SMESH::long_array_var StdMeshersGUI_SubShapeSelectorWdg::GetListOfIDs()
 {
   SMESH::long_array_var anArray = new SMESH::long_array;
 
-  if ( myMainEntry != "" && myIsNotCorrected )
-    myListOfIDs = GetCorrectedListOfIDs( true );
+  // if ( myMainEntry != "" && myIsNotCorrected )
+  //   myListOfIDs = GetCorrectedListOfIDs( true );
 
   int size = myListOfIDs.size();
   anArray->length( size );
-  if ( size ) {
-    for (int i = 0; i < size; i++) {
-        anArray[i] = myListOfIDs.at(i);
-    }
-  }
+  for (int i = 0; i < size; i++)
+    anArray[i] = myListOfIDs.at(i);
+
   return anArray;
 }
 
@@ -524,8 +546,24 @@ bool StdMeshersGUI_SubShapeSelectorWdg::SetListOfIDs( SMESH::long_array_var theI
   for ( int i = 0; i < size; i++ )
     mySelectedIDs.append( theIds[ i ] );
 
-  bool isOk;
-  mySelectedIDs = GetCorrectedListOfIDs( false, &isOk );
+  myListWidget->blockSignals( true );
+  myListWidget->clear();
+  myListWidget->blockSignals( false );
+
+  bool isOk = true;
+  if ( myPreviewActor )
+  {
+    for ( int i = 0; i < size && isOk; i++ )
+      isOk = myPreviewActor->IsValidIndex( theIds[ i ] );
+  }
+  else if ( !myMainShape.IsNull() )
+  {
+    TopTools_IndexedMapOfShape aMainMap;
+    TopExp::MapShapes(myMainShape, aMainMap);
+    for ( int i = 0; i < size && isOk; i++ )
+      isOk = ( theIds[ i ] > 0 && theIds[ i ] <= aMainMap.Extent() );
+  }
+  // mySelectedIDs = GetCorrectedListOfIDs( false, &isOk );
   onAdd();
   return isOk;
 }
@@ -534,12 +572,12 @@ bool StdMeshersGUI_SubShapeSelectorWdg::SetListOfIDs( SMESH::long_array_var theI
 // function : SetMainShapeEntry
 // purpose  : Called to set the Entry of main shape of the mesh
 //=================================================================================
-void StdMeshersGUI_SubShapeSelectorWdg::SetMainShapeEntry( const QString& theEntry )
-{
-  myMainEntry = theEntry;
-  myMainShape = GetTopoDSByEntry( theEntry );
-  myIsNotCorrected = true;
-}
+// void StdMeshersGUI_SubShapeSelectorWdg::SetMainShapeEntry( const QString& theEntry )
+// {
+//   myMainEntry = theEntry;
+//   myMainShape = GetTopoDSByEntry( theEntry );
+//   myIsNotCorrected = true;
+// }
 
 //=================================================================================
 // function : GetMainShapeEntry
@@ -547,87 +585,85 @@ void StdMeshersGUI_SubShapeSelectorWdg::SetMainShapeEntry( const QString& theEnt
 //=================================================================================
 const char* StdMeshersGUI_SubShapeSelectorWdg::GetMainShapeEntry()
 {
-  if ( myMainEntry == "")
-    return myEntry.toLatin1().data();
-
-  return myMainEntry.toLatin1().data();
+  if ( myMainEntry.empty() ) myMainEntry = "";
+  return myMainEntry.c_str();
 }
 
 //=================================================================================
 // function : GetCorrectedListOfIds
 // purpose  : Called to convert the list of IDs from sub-shape IDs to main shape IDs
 //=================================================================================
-QList<int>
-StdMeshersGUI_SubShapeSelectorWdg::GetCorrectedListOfIDs( bool fromSubshapeToMainshape,
-                                                          bool* isOK )
-{
-  if (( myMainShape.IsNull() || myGeomShape.IsNull() ) &&  fromSubshapeToMainshape )
-    return myListOfIDs;
-  else if (( myMainShape.IsNull() /*||*/&& myGeomShape.IsNull() ) &&  !fromSubshapeToMainshape )
-    return mySelectedIDs;
-
-  if ( !fromSubshapeToMainshape ) // called from SetListOfIDs
-  {
-    if ( myMainShape.IsNull() )
-      std::swap( myMainShape, myGeomShape );
-  }
-
-  QList<int> aList;
-  TopTools_IndexedMapOfShape aGeomMap, aMainMap;
-  TopExp::MapShapes(myMainShape, aMainMap);
-  if ( !myGeomShape.IsNull() )
-    TopExp::MapShapes(myGeomShape, aGeomMap);
-
-  bool ok = true;
-  if ( fromSubshapeToMainshape ) // convert indexes from sub-shape to mainshape
-  {
-    int size = myListOfIDs.size();
-    for (int i = 0; i < size; i++) {
-      int index = myListOfIDs.at(i);
-      if ( aGeomMap.Extent() < index )
-      {
-        ok = false;
-      }
-      else
-      {
-        TopoDS_Shape aSubShape = aGeomMap.FindKey( index );
-        if ( mySubShType != aSubShape.ShapeType() )
-          ok = false;
-        if ( !aMainMap.Contains( aSubShape ))
-          ok = false;
-        else
-          index = aMainMap.FindIndex( aSubShape );
-      }
-      aList.append( index );
-    }
-    myIsNotCorrected = false;
-  }
-  else // convert indexes from main shape to sub-shape, or just check indices
-  {
-    int size = mySelectedIDs.size();
-    for (int i = 0; i < size; i++) {
-      int index = mySelectedIDs.at(i);
-      if ( aMainMap.Extent() < index )
-      {
-        ok = false;
-      }
-      else
-      {
-        TopoDS_Shape aSubShape = aMainMap.FindKey( index );
-        if ( mySubShType != aSubShape.ShapeType() )
-          ok = false;
-        if ( !aGeomMap.Contains( aSubShape ) && !aGeomMap.IsEmpty() )
-          ok = false;
-        else
-          index = aGeomMap.FindIndex( aSubShape );
-      }
-      aList.append( index );
-    }
-  }
-  if ( isOK ) *isOK = ok;
-
-  return aList;
-}
+// QList<int>
+// StdMeshersGUI_SubShapeSelectorWdg::GetCorrectedListOfIDs( bool fromSubshapeToMainshape,
+//                                                           bool* isOK )
+// {
+//   if (( myMainShape.IsNull() || myGeomShape.IsNull() ) &&  fromSubshapeToMainshape )
+//     return myListOfIDs;
+//   else if (( myMainShape.IsNull() /*||*/&& myGeomShape.IsNull() ) &&  !fromSubshapeToMainshape )
+//     return mySelectedIDs;
+
+//   if ( !fromSubshapeToMainshape ) // called from SetListOfIDs
+//   {
+//     if ( myMainShape.IsNull() )
+//       std::swap( myMainShape, myGeomShape );
+//   }
+
+//   QList<int> aList;
+//   TopTools_IndexedMapOfShape aGeomMap, aMainMap;
+//   TopExp::MapShapes(myMainShape, aMainMap);
+//   if ( !myGeomShape.IsNull() )
+//     TopExp::MapShapes(myGeomShape, aGeomMap);
+
+//   bool ok = true;
+//   if ( fromSubshapeToMainshape ) // convert indexes from sub-shape to mainshape
+//   {
+//     int size = myListOfIDs.size();
+//     for (int i = 0; i < size; i++) {
+//       int index = myListOfIDs.at(i);
+//       if ( aGeomMap.Extent() < index )
+//       {
+//         ok = false;
+//       }
+//       else
+//       {
+//         TopoDS_Shape aSubShape = aGeomMap.FindKey( index );
+//         if ( mySubShType != aSubShape.ShapeType() )
+//           ok = false;
+//         if ( !aMainMap.Contains( aSubShape ))
+//           ok = false;
+//         else
+//           index = aMainMap.FindIndex( aSubShape );
+//       }
+//       aList.append( index );
+//     }
+//     myIsNotCorrected = false;
+//   }
+//   else // convert indexes from main shape to sub-shape, or just check indices
+//   {
+//     int size = mySelectedIDs.size();
+//     for (int i = 0; i < size; i++) {
+//       int index = mySelectedIDs.at(i);
+//       if ( aMainMap.Extent() < index )
+//       {
+//         ok = false;
+//       }
+//       else
+//       {
+//         TopoDS_Shape aSubShape = aMainMap.FindKey( index );
+//         if ( mySubShType != aSubShape.ShapeType() )
+//           ok = false;
+//         if ( !aGeomMap.Contains( aSubShape ) && !aGeomMap.IsEmpty() )
+//           ok = false;
+//         else
+//           index = aGeomMap.FindIndex( aSubShape );
+//       }
+//       aList.append( index );
+//     }
+//   }
+//   if ( isOK ) *isOK = ok;
+
+//   return aList;
+// }
 
 void StdMeshersGUI_SubShapeSelectorWdg::updateButtons()
 {
index c6b9d95..7d0a5bd 100644 (file)
@@ -24,7 +24,7 @@
 #define STDMESHERSGUI_SUBSHAPESELECTORWDG_H
 
 // SMESH includes
-#include <SMESHGUI.h>
+#include "SMESHGUI.h"
 #include "SMESH_StdMeshersGUI.hxx"
 #include "SMESH_SMESHGUI.hxx"
 
 #include <QStringList>
 #include <TopoDS_Shape.hxx>
 
-#include <SMESHGUI_VTKUtils.h>
+#include <string>
 
 class SMESHGUI;
 class LightApp_SelectionMgr;
 class SVTK_Selector;
 class QPushButton;
 class QLabel;
-class QLineEdit;
-class QCheckBox;
 class QListWidget;
-class SMESH_Actor;
 class SMESH_PreviewActorsCollection;
 class vtkRenderer;
 class SUIT_SelectionFilter;
@@ -60,29 +57,33 @@ public:
   SMESH::long_array_var          GetListOfIDs();
   bool                           SetListOfIDs( SMESH::long_array_var );
 
-  void                           SetGeomShapeEntry( const QString& theEntry );
-  const char*                    GetGeomShapeEntry() { return myEntry.toLatin1().data();}
+  void                           SetGeomShapeEntry( const QString& theEntry,
+                                                    const QString& theMainShapeEntry);
+  //QString                        GetGeomShapeEntry() { return myEntry; }
 
-  void                           SetMainShapeEntry( const QString& theEntry );
+  // void                           SetMainShapeEntry( const QString& theEntry );
   const char*                    GetMainShapeEntry();
 
   TopoDS_Shape                   GetGeomShape() { return myGeomShape; }
   TopoDS_Shape                   GetMainShape() { return myMainShape; }
 
-  QList<int>                     GetCorrectedListOfIDs( bool fromSubshapeToMainshape,
-                                                        bool* isOK=0);
+  // QList<int>                     GetCorrectedListOfIDs( bool fromSubshapeToMainshape,
+  //                                                       bool* isOK=0);
 
   static GEOM::GEOM_Object_var   GetGeomObjectByEntry( const QString& );
   static TopoDS_Shape            GetTopoDSByEntry( const QString& );
 
   QString                        GetValue() const { return myParamValue; }
 
-  void                           showPreview ( bool );
+  void                           ShowPreview( bool );
 
   int                            GetListSize() { return myListOfIDs.size(); }
 
-  void SetMaxSize(int aMaxSize) { myMaxSize = aMaxSize; }
-  //void SetSubShType(TopAbs_ShapeEnum aSubShType) { mySubShType = aSubShType; }
+  void                           SetMaxSize(int aMaxSize) { myMaxSize = aMaxSize; }
+
+  vtkRenderer*                   GetRenderer() { return myRenderer; }
+  SMESH_PreviewActorsCollection* GetActorCollection() { return myPreviewActor; }
+  void                           ClearSelected();
 
 private:
   void                           updateState();
@@ -94,7 +95,7 @@ private slots:
   void                           onRemove(); 
   void                           onPrevious(); 
   void                           onNext(); 
-  void                           SelectionIntoArgument();
+  void                           selectionIntoArgument();
   void                           onListSelectionChanged();
 
 private:
@@ -107,8 +108,8 @@ private:
   SMESH::SMESH_Mesh_var          myMesh;
   TopoDS_Shape                   myGeomShape; // shape whose sub-shapes are selected
   TopoDS_Shape                   myMainShape; // main shape of the mesh
-  QString                        myEntry;
-  QString                        myMainEntry;
+  std::string                    myEntry;
+  std::string                    myMainEntry;
   vtkRenderer*                   myRenderer;
   
   QListWidget*                   myListWidget;
index faabbbb..53c2127 100644 (file)
@@ -628,4 +628,35 @@ this one for this mesh/sub-mesh.</translation>
         <translation>Step</translation>
     </message>
 </context>
+<context>
+    <name>StdMeshersGUI_PropagationHelperWdg</name>
+    <message>
+        <source>HELPER</source>
+        <translation>Helper</translation>
+    </message>
+    <message>
+        <source>SHOW_GEOMETRY</source>
+        <translation>Show whole geometry</translation>
+    </message>
+    <message>
+        <source>PROPAGATION_CHAINS</source>
+        <translation>Propagation chains</translation>
+    </message>
+    <message>
+        <source>ADD</source>
+        <translation>Add</translation>
+    </message>
+    <message>
+        <source>REVERSE</source>
+        <translation>Reverse</translation>
+    </message>
+    <message>
+        <source>NO_CHAINS</source>
+        <translation>(no chains)</translation>
+    </message>
+    <message>
+        <source>CHAIN_NUM_NB_EDGES</source>
+        <translation>Chain %1 (%2 edges)</translation>
+    </message>
+</context>
 </TS>