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()
# 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()
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"
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
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
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 :
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
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
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"
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
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"
+
*/
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
- 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.
*/
<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
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 — an entity of a mesh defining a position in 3D
space with coordinates (x, y, z).</li>
\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.
<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>
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>
<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
<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
<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>
<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>
<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>
\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.
*/
\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
<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>
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
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>
<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>
<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.
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>
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
/*!
-\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
\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.
*/
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>
\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.
*/
\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>.
/*!
-\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.
<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
+*/
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
}
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();
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();
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;
myMapOfActors.insert(index, anActor);
}
}
- mySelector->ClearIObjects();
+ if ( mySelector )
+ mySelector->ClearIObjects();
if ( myRenderer )
AddToRender( myRenderer );
}
// 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
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* );
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 );
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;
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" );
SMESHGUI_SelectionOp::startOperation();
- myDlg->SetMediumNdsOnGeom( false );
+ myDlg->SetMediumNdsOnGeom( true );
myDlg->activateObject( 0 );
myDlg->ShowWarning( false );
myDlg->show();
}
}
+ 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);
}
}
else {
emit finished( QDialog::Accepted );
- delete myDlg;
+ delete myDlg;
}
}
changeWidgets().append( w );
}
}
+ if ( QWidget* w = getHelperWidget() )
+ {
+ w->setParent( fr );
+ w->move( QPoint( 0, 0 ) );
+ lay->addWidget( w );
+ }
return fr;
}
{
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;
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;
{
selectionMgr()->clearFilters();
selectObject( pSubmesh );
- SMESHGUI::GetSMESHGUI()->switchToOperation(704);
+ SMESHGUI::GetSMESHGUI()->switchToOperation( SMESHOp::OpEditMeshOrSubMesh );
return;
}
else
<source>ICON_COMPUTE</source>
<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>
<message>
<source>CURRENT_DIALOG</source>
- <translation>Current Group</translation>
+ <translation>Current Dialog</translation>
</message>
<message>
<source>EDGES_TLT</source>
StdMeshersGUI_SubShapeSelectorWdg.h
StdMeshersGUI_CartesianParamCreator.h
StdMeshersGUI_RadioButtonsGrpWdg.h
+ StdMeshersGUI_PropagationHelperWdg.h
)
# header files / no moc processing
StdMeshersGUI_SubShapeSelectorWdg.cxx
StdMeshersGUI_CartesianParamCreator.cxx
StdMeshersGUI_RadioButtonsGrpWdg.cxx
+ StdMeshersGUI_PropagationHelperWdg.cxx
)
# sources / to compile
// 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>
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() ) );
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 );
QGroupBox* myReversedEdgesBox;
StdMeshersGUI_SubShapeSelectorWdg* myDirectionWidget;
+ QWidget* myReversedEdgesHelper;
};
#endif // STDMESHERSGUI_NBSEGMENTSCREATOR_H
--- /dev/null
+// 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();
+ }
+}
--- /dev/null
+// 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
#include "SMESHGUI.h"
#include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_Utils.h"
#include "StdMeshersGUI_SubShapeSelectorWdg.h"
#include <GEOMBase.h>
QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
if ( anEntry.isEmpty() )
anEntry = h->GetObjectEntry();
- myVertexSelWdg->SetGeomShapeEntry(anEntry);
- myVertexSelWdg->SetMainShapeEntry(aMainEntry);
+ myVertexSelWdg->SetGeomShapeEntry(anEntry,aMainEntry);
if ( !isCreation())
{
void StdMeshersGUI_QuadrangleParamCreator::onTabChanged(int i)
{
- myVertexSelWdg->showPreview( i == TAB_VERTEX );
+ myVertexSelWdg->ShowPreview( i == TAB_VERTEX );
}
//================================================================================
#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>
//================================================================================
StdMeshersGUI_StdHypothesisCreator::StdMeshersGUI_StdHypothesisCreator( const QString& type )
-: SMESHGUI_GenericHypothesisCreator( type )
+ : SMESHGUI_GenericHypothesisCreator( type ), myHelperWidget( 0 )
{
}
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" )
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" )
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() ));
}
if(!initVariableName( hyp, item, "SetMaxElementArea" ))
item.myValue = h->GetMaxElementArea();
p.append( item );
-
+
}
else if( hypType()=="MaxElementVolume" )
{
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);
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" )
{
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 );
}
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 );
}
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
{
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
{
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;
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;
+}
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 {
}
ListOfWidgets myCustomWidgets;
+ QWidget* myHelperWidget;
};
#endif // STDMESHERSGUI_STDHYPOTHESISCREATOR_H
#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
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 );
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();
*/
//================================================================================
-void StdMeshersGUI_SubShapeSelectorWdg::showPreview( bool visible)
+void StdMeshersGUI_SubShapeSelectorWdg::ShowPreview( bool visible)
{
if ( !myPreviewActor )
return;
}
}
+//================================================================================
+/*!
+ * \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;
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();
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 ) )
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() ) {
}
onListSelectionChanged();
myListWidget->blockSignals( false );
- myAddButton->setEnabled( myMaxSize == -1 || myListOfIDs.size() < myMaxSize );
+
+ mySelectedIDs.clear();
+ myAddButton->setEnabled( false );
}
//=================================================================================
onListSelectionChanged();
myListWidget->blockSignals( false );
- myAddButton->setEnabled( true );
+ myAddButton->setEnabled( !mySelectedIDs.isEmpty() );
}
void StdMeshersGUI_SubShapeSelectorWdg::onPrevious()
// 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;
}
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 )) {
{
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;
}
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;
}
// 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
//=================================================================================
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()
{
#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;
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();
void onRemove();
void onPrevious();
void onNext();
- void SelectionIntoArgument();
+ void selectionIntoArgument();
void onListSelectionChanged();
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;
<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>