IMP 22264: EDF 2648 GEOM: Propagate edges automatic orientation

+ 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
This commit is contained in:
eap 2015-03-25 12:36:47 +03:00
parent 588493c920
commit bbca2cb797
54 changed files with 1181 additions and 413 deletions

View 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()

BIN
doc/salome/gui/SMESH/images/a-arithmetic1d.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 29 KiB

BIN
doc/salome/gui/SMESH/images/a-creategroup.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 24 KiB

BIN
doc/salome/gui/SMESH/images/a-nbsegments2.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 32 KiB

BIN
doc/salome/gui/SMESH/images/a-startendlength.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
doc/salome/gui/SMESH/images/hypo_fixedpnt_dlg.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View 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 :
@ -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"
@ -296,7 +308,7 @@ 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"
*/

View 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.
*/

View 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>

View 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>
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>

View 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>

View File

@ -15,8 +15,9 @@ 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
<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>
@ -33,14 +34,12 @@ 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>
</ul>

View 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>

View File

@ -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.
*/

View 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
<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> set of fields allows to select a sub-mesh or
a group of the appropriate type.</li>
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

View 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

View 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
\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.
*/

View 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>

View 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:
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.
- 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.
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.
*/

View 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>.

View 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.

View File

@ -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

BIN
resources/mesh_evaluate.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
resources/mesh_order.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1013 B

View File

@ -65,6 +65,7 @@ SMESH_PreviewActorsCollection::~SMESH_PreviewActorsCollection()
}
bool SMESH_PreviewActorsCollection::Init( const TopoDS_Shape& theShape,
const TopoDS_Shape& theMainShape,
TopAbs_ShapeEnum theType,
const QString& theEntry )
{
@ -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,6 +249,7 @@ void SMESH_PreviewActorsCollection::showCurrentChunk()
myMapOfActors.insert(index, anActor);
}
}
if ( mySelector )
mySelector->ClearIObjects();
if ( myRenderer )
AddToRender( myRenderer );

View 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
@ -48,7 +46,10 @@ public:
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 );

View File

@ -1510,30 +1510,23 @@ 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 ( vol != myVolume &&
vol->GetNodeIndex( n2 ) >= 0 &&
vol->GetNodeIndex( n3 ) >= 0 )
{
if ( otherVol ) *otherVol = vol;
return !isFree;
}
}
}
if ( otherVol ) *otherVol = 0;
return isFree;
}

View 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" );

View 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();

View 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);
}

View File

@ -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;

View 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;

View File

@ -658,7 +658,7 @@ void SMESHGUI_MeshOp::selectionDone()
{
selectionMgr()->clearFilters();
selectObject( pSubmesh );
SMESHGUI::GetSMESHGUI()->switchToOperation(704);
SMESHGUI::GetSMESHGUI()->switchToOperation( SMESHOp::OpEditMeshOrSubMesh );
return;
}
else

View File

@ -39,6 +39,14 @@
<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>

View 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>

View 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

View 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 );

View File

@ -96,6 +96,7 @@ private:
QGroupBox* myReversedEdgesBox;
StdMeshersGUI_SubShapeSelectorWdg* myDirectionWidget;
QWidget* myReversedEdgesHelper;
};
#endif // STDMESHERSGUI_NBSEGMENTSCREATOR_H

View File

@ -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();
}
}

View File

@ -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

View 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 );
}
//================================================================================

View File

@ -37,9 +37,10 @@
#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() ));
}
@ -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" )
{
@ -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;
}

View File

@ -54,22 +54,28 @@ 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();
bool initVariableName(SMESH::SMESH_Hypothesis_var theHyp, StdParam& theParams, const char* theMethod) const;
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;
template<class T>
T* widget(int i) const {
return dynamic_cast< T* >( getWidgetForParam( i ));
}
ListOfWidgets myCustomWidgets;
QWidget* myHelperWidget;
};
#endif // STDMESHERSGUI_STDHYPOTHESISCREATOR_H

View File

@ -24,28 +24,22 @@
#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>
@ -61,11 +55,9 @@
// 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
@ -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;
@ -242,7 +247,8 @@ 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() );
@ -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,7 +268,8 @@ 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);
@ -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.isEmpty() || theMainShapeEntry.isEmpty() )
{
if ( theEntry != "") {
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++) {
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;
// 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 );
}
// 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);
// 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;
// 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;
}
// return aList;
// }
void StdMeshersGUI_SubShapeSelectorWdg::updateButtons()
{

View 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"
@ -33,17 +33,14 @@
#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; }
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;

View 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>