diff --git a/doc/salome/gui/SMESH/images/a-maxsize1d.png b/doc/salome/gui/SMESH/images/a-maxsize1d.png
new file mode 100644
index 000000000..c2ddd0c37
Binary files /dev/null and b/doc/salome/gui/SMESH/images/a-maxsize1d.png differ
diff --git a/doc/salome/gui/SMESH/images/cutgroups.png b/doc/salome/gui/SMESH/images/cutgroups.png
index 65dd2a00e..213a52a97 100755
Binary files a/doc/salome/gui/SMESH/images/cutgroups.png and b/doc/salome/gui/SMESH/images/cutgroups.png differ
diff --git a/doc/salome/gui/SMESH/images/dimgroup_0d.png b/doc/salome/gui/SMESH/images/dimgroup_0d.png
new file mode 100644
index 000000000..caabdc4f3
Binary files /dev/null and b/doc/salome/gui/SMESH/images/dimgroup_0d.png differ
diff --git a/doc/salome/gui/SMESH/images/dimgroup_1d.png b/doc/salome/gui/SMESH/images/dimgroup_1d.png
new file mode 100644
index 000000000..23af4a75d
Binary files /dev/null and b/doc/salome/gui/SMESH/images/dimgroup_1d.png differ
diff --git a/doc/salome/gui/SMESH/images/dimgroup_2d.png b/doc/salome/gui/SMESH/images/dimgroup_2d.png
new file mode 100644
index 000000000..6ca49a6a9
Binary files /dev/null and b/doc/salome/gui/SMESH/images/dimgroup_2d.png differ
diff --git a/doc/salome/gui/SMESH/images/dimgroup_dlg.png b/doc/salome/gui/SMESH/images/dimgroup_dlg.png
new file mode 100644
index 000000000..21cdb058a
Binary files /dev/null and b/doc/salome/gui/SMESH/images/dimgroup_dlg.png differ
diff --git a/doc/salome/gui/SMESH/images/dimgroup_src.png b/doc/salome/gui/SMESH/images/dimgroup_src.png
new file mode 100644
index 000000000..93606a8e2
Binary files /dev/null and b/doc/salome/gui/SMESH/images/dimgroup_src.png differ
diff --git a/doc/salome/gui/SMESH/images/dimgroup_tui1.png b/doc/salome/gui/SMESH/images/dimgroup_tui1.png
new file mode 100644
index 000000000..a2faf39b5
Binary files /dev/null and b/doc/salome/gui/SMESH/images/dimgroup_tui1.png differ
diff --git a/doc/salome/gui/SMESH/images/dimgroup_tui2.png b/doc/salome/gui/SMESH/images/dimgroup_tui2.png
new file mode 100644
index 000000000..cb040a974
Binary files /dev/null and b/doc/salome/gui/SMESH/images/dimgroup_tui2.png differ
diff --git a/doc/salome/gui/SMESH/images/extrusion1.png b/doc/salome/gui/SMESH/images/extrusion1.png
index 24781c1a7..9f34a0feb 100644
Binary files a/doc/salome/gui/SMESH/images/extrusion1.png and b/doc/salome/gui/SMESH/images/extrusion1.png differ
diff --git a/doc/salome/gui/SMESH/images/extrusion2.png b/doc/salome/gui/SMESH/images/extrusion2.png
index 8b7a404a3..527b67a17 100755
Binary files a/doc/salome/gui/SMESH/images/extrusion2.png and b/doc/salome/gui/SMESH/images/extrusion2.png differ
diff --git a/doc/salome/gui/SMESH/images/extrusionalongaline1.png b/doc/salome/gui/SMESH/images/extrusionalongaline1.png
index a0330bf2d..76a60bd34 100755
Binary files a/doc/salome/gui/SMESH/images/extrusionalongaline1.png and b/doc/salome/gui/SMESH/images/extrusionalongaline1.png differ
diff --git a/doc/salome/gui/SMESH/images/extrusionalongaline2.png b/doc/salome/gui/SMESH/images/extrusionalongaline2.png
index b67d3096a..fb0456250 100755
Binary files a/doc/salome/gui/SMESH/images/extrusionalongaline2.png and b/doc/salome/gui/SMESH/images/extrusionalongaline2.png differ
diff --git a/doc/salome/gui/SMESH/images/free_faces.png b/doc/salome/gui/SMESH/images/free_faces.png
new file mode 100644
index 000000000..8b5bee40d
Binary files /dev/null and b/doc/salome/gui/SMESH/images/free_faces.png differ
diff --git a/doc/salome/gui/SMESH/images/free_nodes.png b/doc/salome/gui/SMESH/images/free_nodes.png
new file mode 100644
index 000000000..c1d23c1d3
Binary files /dev/null and b/doc/salome/gui/SMESH/images/free_nodes.png differ
diff --git a/doc/salome/gui/SMESH/images/intersectgroups.png b/doc/salome/gui/SMESH/images/intersectgroups.png
index 24a696fee..8114b1097 100755
Binary files a/doc/salome/gui/SMESH/images/intersectgroups.png and b/doc/salome/gui/SMESH/images/intersectgroups.png differ
diff --git a/doc/salome/gui/SMESH/images/mesh_precompute.png b/doc/salome/gui/SMESH/images/mesh_precompute.png
new file mode 100644
index 000000000..dd90498cf
Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_precompute.png differ
diff --git a/doc/salome/gui/SMESH/images/preview_mesh_1D.png b/doc/salome/gui/SMESH/images/preview_mesh_1D.png
new file mode 100644
index 000000000..3922a19f5
Binary files /dev/null and b/doc/salome/gui/SMESH/images/preview_mesh_1D.png differ
diff --git a/doc/salome/gui/SMESH/images/preview_mesh_2D.png b/doc/salome/gui/SMESH/images/preview_mesh_2D.png
new file mode 100644
index 000000000..55ec7b8fb
Binary files /dev/null and b/doc/salome/gui/SMESH/images/preview_mesh_2D.png differ
diff --git a/doc/salome/gui/SMESH/images/preview_tmp_data.png b/doc/salome/gui/SMESH/images/preview_tmp_data.png
new file mode 100644
index 000000000..be1a12515
Binary files /dev/null and b/doc/salome/gui/SMESH/images/preview_tmp_data.png differ
diff --git a/doc/salome/gui/SMESH/images/removeelements.png b/doc/salome/gui/SMESH/images/removeelements.png
index 8e9e14d42..78e495946 100755
Binary files a/doc/salome/gui/SMESH/images/removeelements.png and b/doc/salome/gui/SMESH/images/removeelements.png differ
diff --git a/doc/salome/gui/SMESH/images/removenodes.png b/doc/salome/gui/SMESH/images/removenodes.png
index aea406789..52a5ac6b0 100755
Binary files a/doc/salome/gui/SMESH/images/removenodes.png and b/doc/salome/gui/SMESH/images/removenodes.png differ
diff --git a/doc/salome/gui/SMESH/images/revolution1.png b/doc/salome/gui/SMESH/images/revolution1.png
index 25406a317..c4a4c1748 100755
Binary files a/doc/salome/gui/SMESH/images/revolution1.png and b/doc/salome/gui/SMESH/images/revolution1.png differ
diff --git a/doc/salome/gui/SMESH/images/revolution2.png b/doc/salome/gui/SMESH/images/revolution2.png
index 2953c78e8..7d5777c9e 100755
Binary files a/doc/salome/gui/SMESH/images/revolution2.png and b/doc/salome/gui/SMESH/images/revolution2.png differ
diff --git a/doc/salome/gui/SMESH/images/rotation.png b/doc/salome/gui/SMESH/images/rotation.png
index 0be10394e..ae6df4b9f 100755
Binary files a/doc/salome/gui/SMESH/images/rotation.png and b/doc/salome/gui/SMESH/images/rotation.png differ
diff --git a/doc/salome/gui/SMESH/images/smoothing.png b/doc/salome/gui/SMESH/images/smoothing.png
index 0841ed113..26a427eb6 100755
Binary files a/doc/salome/gui/SMESH/images/smoothing.png and b/doc/salome/gui/SMESH/images/smoothing.png differ
diff --git a/doc/salome/gui/SMESH/images/symmetry1.png b/doc/salome/gui/SMESH/images/symmetry1.png
index 059d4caf7..b37fb0ab1 100755
Binary files a/doc/salome/gui/SMESH/images/symmetry1.png and b/doc/salome/gui/SMESH/images/symmetry1.png differ
diff --git a/doc/salome/gui/SMESH/images/symmetry2.png b/doc/salome/gui/SMESH/images/symmetry2.png
index 5c50c8063..9304d6734 100755
Binary files a/doc/salome/gui/SMESH/images/symmetry2.png and b/doc/salome/gui/SMESH/images/symmetry2.png differ
diff --git a/doc/salome/gui/SMESH/images/symmetry3.png b/doc/salome/gui/SMESH/images/symmetry3.png
index c0a80fc71..f15c5fcaa 100755
Binary files a/doc/salome/gui/SMESH/images/symmetry3.png and b/doc/salome/gui/SMESH/images/symmetry3.png differ
diff --git a/doc/salome/gui/SMESH/images/translation1.png b/doc/salome/gui/SMESH/images/translation1.png
index 64ff2ea71..b7e811645 100755
Binary files a/doc/salome/gui/SMESH/images/translation1.png and b/doc/salome/gui/SMESH/images/translation1.png differ
diff --git a/doc/salome/gui/SMESH/images/translation2.png b/doc/salome/gui/SMESH/images/translation2.png
index b9efa1c6b..c0bbad0a5 100755
Binary files a/doc/salome/gui/SMESH/images/translation2.png and b/doc/salome/gui/SMESH/images/translation2.png differ
diff --git a/doc/salome/gui/SMESH/images/uniongroups.png b/doc/salome/gui/SMESH/images/uniongroups.png
index 9225b848d..831f3cf33 100755
Binary files a/doc/salome/gui/SMESH/images/uniongroups.png and b/doc/salome/gui/SMESH/images/uniongroups.png differ
diff --git a/doc/salome/gui/SMESH/input/1d_meshing_hypo.doc b/doc/salome/gui/SMESH/input/1d_meshing_hypo.doc
index 30838a332..0f7920172 100644
--- a/doc/salome/gui/SMESH/input/1d_meshing_hypo.doc
+++ b/doc/salome/gui/SMESH/input/1d_meshing_hypo.doc
@@ -6,6 +6,7 @@
\ref arithmetic_1d_anchor "Arithmetic 1D"
\ref average_length_anchor "Average Length"
+\ref max_length_anchor "Max Size"
\ref deflection_1d_anchor "Deflection 1D"
\ref number_of_segments_anchor "Number of segments"
\ref start_and_end_length_anchor "Start and end length"
@@ -77,6 +78,21 @@ integer. Default value is 1e-07.
\ref tui_average_length "Defining Average Length" hypothesis
operation.
+ \anchor max_length_anchor
+Max Size
+Max Size hypothesis allows splitting geometrical edges into
+segments not longer than the given length. Definition of this hypothesis
+consists of setting the maximal allowed \b length of segments.
+Use preestimated length check box lets you specify \b length
+automatically calculated basing on size of your geometrical object,
+namely as diagonal of bounding box divided by ten. The divider can be
+changed via "Segmentation of diagonal of boundary box of geometry"
+preference parameter.
+Use preestimated length check box is enabled only if the
+geometrical object has been selected before hypothesis definition.
+
+\image html a-maxsize1d.png
+
\anchor number_of_segments_anchor
Number of segments hypothesis
diff --git a/doc/salome/gui/SMESH/input/about_hypo.doc b/doc/salome/gui/SMESH/input/about_hypo.doc
index 86081743f..113953ce5 100644
--- a/doc/salome/gui/SMESH/input/about_hypo.doc
+++ b/doc/salome/gui/SMESH/input/about_hypo.doc
@@ -18,6 +18,7 @@ them, you operate numerical values):
\ref arithmetic_1d_anchor "Arithmetic 1D"
\ref average_length_anchor "Average Length"
+\ref max_length_anchor "Max Size"
\ref deflection_1d_anchor "Deflection 1D"
\ref number_of_segments_anchor "Number of segments"
\ref start_and_end_length_anchor "Start and end length"
diff --git a/doc/salome/gui/SMESH/input/about_quality_controls.doc b/doc/salome/gui/SMESH/input/about_quality_controls.doc
index 79a332b7b..7f7fa95db 100644
--- a/doc/salome/gui/SMESH/input/about_quality_controls.doc
+++ b/doc/salome/gui/SMESH/input/about_quality_controls.doc
@@ -13,7 +13,12 @@ the meshing elements and these calculated values is shown with the
help of a scalar bar, which is displayed near the presentation of your
mesh.
-There are 1D, 2D and 3D quality controls.
+There are 0D, 1D, 2D and 3D quality controls.
+
+0D mesh quality controls:
+
+\ref free_nodes_page "Free nodes"
+
1D mesh quality controls:
@@ -39,6 +44,7 @@ There are 1D, 2D and 3D quality controls.
\subpage aspect_ratio_3d_page "Aspect ratio 3D"
\subpage volume_page "Volume"
+\subpage free_faces_page "Free faces"
-*/
\ No newline at end of file
+*/
diff --git a/doc/salome/gui/SMESH/input/creating_groups.doc b/doc/salome/gui/SMESH/input/creating_groups.doc
index b153970c6..0e89b980d 100644
--- a/doc/salome/gui/SMESH/input/creating_groups.doc
+++ b/doc/salome/gui/SMESH/input/creating_groups.doc
@@ -92,4 +92,58 @@ selected in green.
\ref tui_create_group_on_geometry "Create a Group on Geometry"
operation.
+Creation of groups using existing groups and sub-meshes.
+
+Application provides possibility to create new standalone groups using existing standalone groups, groups on geometry and sub-meshes. This functionality is implemented using "Select from" group box of "Create group" dialog box described above.
+
+This functionality is described on the example of creating new group from existing standalone groups and groups on geometry.
+
+Imagine there are group G1. It can be standalone group or group on geometry.
+
+To create group G2 containing all entities of group G1 and a faces graphically selected in 3D view following steps can be performed:
+
+User opens "Create group" dialog box.
+The user specifies "Face" type of entities and "G2" name of group.
+The user checks "Group" check-box of "Select From" group box.
+The user selects G1 group in object browser or 3D view.
+The user presses "Add" push button of "Content" group box. "Id Elements" list-box is filled with identifiers of faces belonging to group G1.
+The user selects other faces in 3D view.
+The user presses "Apply" button. System creates group G2.
+
+
+Please note that group G2 does not have a references to source group G1. It contains list of faces identifiers only. So if G1 group will be changed group G2 will remain unmodified.
+
+
+\anchor gui_create_dim_group
+Creating groups of entities from existing groups of superior dimensions
+
+Application provides possibility for creating groups of entities from existing groups of superior dimensions. For example, it is possible to create group of nodes using list of existing groups of faces.
+
+To create groups of entities from existing groups of superior dimensions, in the \b Mesh menu select Group of underlying entities .
+
+The following dialog box will appear:
+
+\image html dimgroup_dlg.png
+
+In this dialog box you should specify the name of the resulting group, types of entities and set of source groups.
+
+For example, we have two source Volume groups illustrated on the figure below
+
+\image html dimgroup_src.png
+Source groups
+
+In this case we obtain following results for Faces, Edges and Nodes.
+
+\image html dimgroup_2d.png
+Faces
+
+\image html dimgroup_1d.png
+Edges
+
+\image html dimgroup_0d.png
+Nodes
+
+See Also a sample TUI Script of a
+\ref tui_create_dim_group "Creating groups of entities from existing groups of superior dimensions"
+operation.
*/
\ No newline at end of file
diff --git a/doc/salome/gui/SMESH/input/editing_groups.doc b/doc/salome/gui/SMESH/input/editing_groups.doc
index 3a69e757a..b5031468a 100644
--- a/doc/salome/gui/SMESH/input/editing_groups.doc
+++ b/doc/salome/gui/SMESH/input/editing_groups.doc
@@ -21,7 +21,21 @@ remove the elements forming it. For more information see
group.
+\n To convert an existing group on geometry into standalone group
+of elements and modify:
+
+Select your group on geometry in the Object Browser and in the \b Mesh menu click
+the Edit Group as Standalone item.
+
+\image html image74.gif
+"Edit Group as Standalone" button
+
+The group on geometry will be converted into standalone group and can
+be modified as group of elements
+Click the \b Apply or Apply and Close button to confirm modification of the
+group.
+
See Also a sample TUI Script of an
\ref tui_edit_group "Edit Group" operation.
-*/
\ No newline at end of file
+*/
diff --git a/doc/salome/gui/SMESH/input/extrusion.doc b/doc/salome/gui/SMESH/input/extrusion.doc
index 8151f8f36..7ceb1dca0 100644
--- a/doc/salome/gui/SMESH/input/extrusion.doc
+++ b/doc/salome/gui/SMESH/input/extrusion.doc
@@ -29,6 +29,7 @@ The following dialog box will appear:
specify the IDs of the elements which will be extruded by
selecting them in the 3D viewer or select the whole mesh or
submesh,
+specify the distance at which the elements will be extruded,
specify the vector along which the elements will be extruded,
number of steps.
diff --git a/doc/salome/gui/SMESH/input/free_faces.doc b/doc/salome/gui/SMESH/input/free_faces.doc
new file mode 100644
index 000000000..4a87b992a
--- /dev/null
+++ b/doc/salome/gui/SMESH/input/free_faces.doc
@@ -0,0 +1,17 @@
+/*!
+
+\page free_faces_page Free faces
+
+\n This mesh quality control highlights faces which are connected
+less than to two mesh volume elements. Free faces are shown with a color differs from
+the color of shared faces.
+
+\image html free_faces.png
+In this picture some volume mesh element are removed as
+a result some faces become connected only to one
+volume. i.e. become free.
+
+See Also a sample TUI Script of a
+\ref tui_free_faces "Free Faces quality control" operation.
+
+*/
diff --git a/doc/salome/gui/SMESH/input/free_nodes.doc b/doc/salome/gui/SMESH/input/free_nodes.doc
new file mode 100644
index 000000000..13f314309
--- /dev/null
+++ b/doc/salome/gui/SMESH/input/free_nodes.doc
@@ -0,0 +1,16 @@
+/*!
+
+\page free_nodes_page Free nodes
+
+\n This mesh quality control highlights nodes which are not connected
+to any mesh element. Free nodes are shown with a color differs from
+the color of nodes.
+
+\image html free_nodes.png
+In this picture some nodes don't connected to a mesh element as
+a result of deleting elements and adding several isolated nodes.
+
+See Also a sample TUI Script of a
+\ref tui_free_nodes "Free Nodes quality control" operation.
+
+*/
diff --git a/doc/salome/gui/SMESH/input/index.doc b/doc/salome/gui/SMESH/input/index.doc
index 7e40add11..cea4b5462 100644
--- a/doc/salome/gui/SMESH/input/index.doc
+++ b/doc/salome/gui/SMESH/input/index.doc
@@ -23,4 +23,4 @@ Almost all mesh module functionalities are accessible via
\image html image7.jpg "Example of MESH module usage for engineering tasks"
-*/
\ No newline at end of file
+*/
diff --git a/doc/salome/gui/SMESH/input/preview_meshes.doc b/doc/salome/gui/SMESH/input/preview_meshes.doc
new file mode 100644
index 000000000..92a4cca27
--- /dev/null
+++ b/doc/salome/gui/SMESH/input/preview_meshes.doc
@@ -0,0 +1,36 @@
+/*!
+
+\page preview_meshes_page Preview and Compute meshes
+
+Before whole mesh computation it is allowed to see the mesh preview.
+When mesh object is already created and all hypotheses assigned,
+select your mesh in the Object Browser . From the
+\b Mesh menu select \b Preview or click "Preview" button of the
+toolbar or activate "Preview" item from pop-up menu.
+
+\image html mesh_precompute.png
+"Preview" button
+
+The Mesh Preview dialog box appears. In this dialog box you can select
+preview mode 1D mesh or 2D mesh depending on assigned
+hypotheses to mesh.
+
+The 1D mesh preview shows as nodes computed on geometry edges
+
+\image html preview_mesh_1D.png
+
+The 2D mesh preview shows edge mesh elements, computed on geometry faces
+
+\image html preview_mesh_2D.png
+
+Pressing Compute button leads to whole mesh computation
+process.
+During exit from Preview dialog box, the question about storage temporary
+created mesh elements appers:
+
+\image html preview_tmp_data.png
+
+Note, that computed temporary mesh elements can be reused during next
+mesh computation process.
+
+*/
diff --git a/doc/salome/gui/SMESH/input/tui_grouping_elements.doc b/doc/salome/gui/SMESH/input/tui_grouping_elements.doc
index 8b9f6391c..e03433f1c 100644
--- a/doc/salome/gui/SMESH/input/tui_grouping_elements.doc
+++ b/doc/salome/gui/SMESH/input/tui_grouping_elements.doc
@@ -123,8 +123,8 @@ salome.sg.updateObjBrowser(1)
\image html editing_groups2.png
-\anchor tui_union_of_two_groups
-Union of two groups
+\anchor tui_union_of_groups
+Union of groups
\code
import SMESH_mechanic
@@ -141,7 +141,7 @@ anIds = mesh.GetIdsFromFilter(aFilter)
print "Criterion: Area > 20, Nb = ", len( anIds )
# create a group by adding elements with area > 20
-aGroup1 = mesh.CreateEmptyGroup(SMESH.FACE, "Area > 20")
+aGroup1 = mesh.CreateEmptyGroup(smesh.FACE, "Area > 20")
aGroup1.Add(anIds)
# Criterion : AREA = 20
@@ -157,8 +157,9 @@ aGroup2 = mesh.CreateEmptyGroup( smesh.FACE, "Area = 20" )
aGroup2.Add(anIds)
# create union group : area >= 20
-aGroup3 = mesh.UnionGroups(aGroup1, aGroup2, "Area >= 20")
+aGroup3 = mesh.UnionListOfGroups([aGroup1, aGroup2], "Area >= 20")
print "Criterion: Area >= 20, Nb = ", len(aGroup3.GetListOfID())
+# Please note that also there is UnionGroups() method which works with two groups only
# Criterion : AREA < 20
aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_Area, smesh.FT_LessThan, 20.)
@@ -172,7 +173,7 @@ aGroup4 = mesh.CreateEmptyGroup(smesh.FACE, "Area < 20")
aGroup4.Add(anIds)
# create union group : area >= 20 and area < 20
-aGroup5 = mesh.UnionGroups(aGroup3, aGroup4, "Any Area")
+aGroup5 = mesh.UnionListOfGroups([aGroup3, aGroup4], "Any Area")
print "Criterion: Any Area, Nb = ", len(aGroup5.GetListOfID())
salome.sg.updateObjBrowser(1)
@@ -185,8 +186,8 @@ salome.sg.updateObjBrowser(1)
\image html union_groups3.png
-\anchor tui_intersection_of_two_groups
-Intersection of two groups
+\anchor tui_intersection_of_groups
+Intersection of groups
\code
import SMESH_mechanic
@@ -203,7 +204,7 @@ anIds = mesh.GetIdsFromFilter(aFilter)
print "Criterion: Area > 20, Nb = ", len(anIds)
# create a group by adding elements with area > 20
-aGroup1 = mesh.CreateEmptyGroup(SMESH.FACE, "Area > 20")
+aGroup1 = mesh.CreateEmptyGroup(smesh.FACE, "Area > 20")
aGroup1.Add(anIds)
# Criterion : AREA < 60
@@ -214,12 +215,13 @@ anIds = mesh.GetIdsFromFilter(aFilter)
print "Criterion: Area < 60, Nb = ", len(anIds)
# create a group by adding elements with area < 60
-aGroup2 = mesh.CreateEmptyGroup(SMESH.FACE, "Area < 60")
+aGroup2 = mesh.CreateEmptyGroup(smesh.FACE, "Area < 60")
aGroup2.Add(anIds)
# create an intersection of groups : 20 < area < 60
-aGroup3 = mesh.IntersectGroups(aGroup1, aGroup2, "20 < Area < 60")
+aGroup3 = mesh.IntersectListOfGroups([aGroup1, aGroup2], "20 < Area < 60")
print "Criterion: 20 < Area < 60, Nb = ", len(aGroup3.GetListOfID())
+# Please note that also there is IntersectGroups() method which works with two groups only
salome.sg.updateObjBrowser(1)
\endcode
@@ -231,8 +233,8 @@ salome.sg.updateObjBrowser(1)
\image html intersect_groups3.png
-\anchor tui_cut_of_two_groups
-Cut of two groups
+\anchor tui_cut_of_groups
+Cut of groups
\code
import SMESH_mechanic
@@ -264,6 +266,7 @@ aGroupTool = mesh.MakeGroupByIds("Area < 60", smesh.FACE, anIds)
# create a cut of groups : area >= 60
aGroupRes = mesh.CutGroups(aGroupMain, aGroupTool, "Area >= 60")
print "Criterion: Area >= 60, Nb = ", len(aGroupRes.GetListOfID())
+# Please note that also there is CutListOfGroups() method which works with lists of groups of any lengths
salome.sg.updateObjBrowser(1)
\endcode
@@ -274,4 +277,54 @@ salome.sg.updateObjBrowser(1)
\image html cut_groups3.png
+
+\anchor tui_create_dim_group
+Creating groups of entities from existing groups of superior dimensions
+
+\code
+import SMESH_mechanic
+
+smesh = SMESH_mechanic.smesh
+mesh = SMESH_mechanic.mesh
+salome = SMESH_mechanic.salome
+
+# Criterion : AREA > 100
+aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_Area, smesh.FT_MoreThan, 100.)
+
+anIds = mesh.GetIdsFromFilter(aFilter)
+
+print "Criterion: Area > 100, Nb = ", len(anIds)
+
+# create a group by adding elements with area > 100
+aSrcGroup1 = mesh.MakeGroupByIds("Area > 100", smesh.FACE, anIds)
+
+# Criterion : AREA < 30
+aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_Area, smesh.FT_LessThan, 30.)
+
+anIds = mesh.GetIdsFromFilter(aFilter)
+
+print "Criterion: Area < 30, Nb = ", len(anIds)
+
+# create a group by adding elements with area < 30
+aSrcGroup2 = mesh.MakeGroupByIds("Area < 30", smesh.FACE, anIds)
+
+# Create group of edges using source groups of faces
+aGrp = mesh.CreateDimGroup( [aSrcGroup1, aSrcGroup2], smesh.EDGE, "Edges" )
+
+# Create group of nodes using source groups of faces
+aGrp = mesh.CreateDimGroup( [aSrcGroup1, aSrcGroup2], smesh.NODE, "Nodes" )
+
+salome.sg.updateObjBrowser(1)
+\endcode
+
+\image html dimgroup_tui1.png
+Source groups of faces<\center>
+
+\image html dimgroup_tui2.png
+Result groups of edges and nodes<\center>
+
+
+
+
+
*/
\ No newline at end of file
diff --git a/doc/salome/gui/SMESH/input/tui_quality_controls.doc b/doc/salome/gui/SMESH/input/tui_quality_controls.doc
index e1b8b700e..57d52c69e 100644
--- a/doc/salome/gui/SMESH/input/tui_quality_controls.doc
+++ b/doc/salome/gui/SMESH/input/tui_quality_controls.doc
@@ -189,6 +189,140 @@ for i in range(len(aBorders)):
salome.sg.updateObjBrowser(1)
\endcode
+
+\anchor tui_free_nodes
+Free Nodes
+
+\code
+import salome
+import geompy
+
+import smesh
+
+# create box
+box = geompy.MakeBox(0., 0., 0., 100., 200., 300.)
+idbox = geompy.addToStudy(box, "box")
+
+# create a mesh
+mesh = smesh.Mesh(box, "Mesh_free_nodes")
+algo = mesh.Segment()
+algo.NumberOfSegments(10)
+algo = mesh.Triangle(smesh.MEFISTO)
+algo.MaxElementArea(150.)
+mesh.Compute()
+
+# Remove some elements to obtain free nodes
+# Criterion : AREA < 80.
+area_margin = 80.
+
+aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_Area, smesh.FT_LessThan, area_margin)
+
+anIds = mesh.GetIdsFromFilter(aFilter)
+
+mesh.RemoveElements(anIds)
+
+# criterion : free nodes
+aFilter = smesh.GetFilter(smesh.NODE, smesh.FT_FreeNodes)
+anNodeIds = mesh.GetIdsFromFilter(aFilter)
+
+# create a group
+aGroup = mesh.CreateEmptyGroup(smesh.NODE, "Free_nodes")
+aGroup.Add(anNodeIds)
+
+# print the result
+print "Criterion: Free nodes Nb = ", len(anNodeIds)
+j = 1
+for i in range(len(anNodeIds)):
+ if j > 20: j = 1; print ""
+ print anNodeIds[i],
+ j = j + 1
+ pass
+print ""
+
+salome.sg.updateObjBrowser(1)
+\endcode
+
+
+
+\anchor tui_free_faces
+Free Faces
+
+\code
+import salome
+import geompy
+
+####### GEOM part ########
+
+Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
+Box_1_vertex_6 = geompy.GetSubShape(Box_1, [6])
+Box_1 = geompy.GetMainShape(Box_1_vertex_6)
+Box_1_vertex_16 = geompy.GetSubShape(Box_1, [16])
+Box_1 = geompy.GetMainShape(Box_1_vertex_16)
+Box_1_vertex_11 = geompy.GetSubShape(Box_1, [11])
+Box_1 = geompy.GetMainShape(Box_1_vertex_11)
+Plane_1 = geompy.MakePlaneThreePnt(Box_1_vertex_6, Box_1_vertex_16, Box_1_vertex_11, 2000)
+Partition_1 = geompy.MakePartition([Box_1], [Plane_1], [], [], geompy.ShapeType["SOLID"], 0, [], 0)
+
+Box_1_vertex_19 = geompy.GetSubShape(Box_1, [19])
+Box_1_vertex_21 = geompy.GetSubShape(Box_1, [21])
+Plane_2 = geompy.MakePlaneThreePnt(Box_1_vertex_16, Box_1_vertex_19, Box_1_vertex_21, 2000)
+
+geompy.addToStudy( Box_1, "Box_1" )
+geompy.addToStudyInFather( Box_1, Box_1_vertex_6, "Box_1:vertex_6" )
+geompy.addToStudyInFather( Box_1, Box_1_vertex_16, "Box_1:vertex_16" )
+geompy.addToStudyInFather( Box_1, Box_1_vertex_11, "Box_1:vertex_11" )
+geompy.addToStudy( Plane_1, "Plane_1" )
+geompy.addToStudy( Partition_1, "Partition_1" )
+geompy.addToStudyInFather( Box_1, Box_1_vertex_19, "Box_1:vertex_19" )
+geompy.addToStudyInFather( Box_1, Box_1_vertex_21, "Box_1:vertex_21" )
+geompy.addToStudy( Plane_2, "Plane_2" )
+
+###### SMESH part ######
+import smesh
+
+import StdMeshers
+import NETGENPlugin
+
+Mesh_1 = smesh.Mesh(Partition_1)
+Regular_1D = Mesh_1.Segment()
+Max_Size_1 = Regular_1D.MaxSize(34.641)
+MEFISTO_2D = Mesh_1.Triangle()
+Tetrahedron_Netgen = Mesh_1.Tetrahedron(algo=smesh.NETGEN)
+isDone = Mesh_1.Compute()
+
+# create a group of free faces
+aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_FreeFaces )
+aFaceIds = Mesh_1.GetIdsFromFilter(aFilter)
+
+aGroup = Mesh_1.CreateEmptyGroup(smesh.FACE, "Free_faces")
+aGroup.Add(aFaceIds)
+
+# print the result
+print "Criterion: Free nodes Nb = ", len(anNodeIds)
+j = 1
+for i in range(len(aFaceIds)):
+ if j > 20: j = 1; print ""
+ print anNodeIds[i],
+ j = j + 1
+ pass
+print ""
+
+#filter faces from plane 2
+aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_BelongToPlane, Plane_2)
+aFaceIds = Mesh_1.GetIdsFromFilter(aFilter)
+aGroup.Remove(aFaceIds)
+
+# create a group of shared faces (located on partition boundary inside box)
+aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_BelongToPlane, Plane_1)
+aFaceIds = Mesh_1.GetIdsFromFilter(aFilter)
+
+aGroup = Mesh_1.CreateEmptyGroup(smesh.FACE, "Shared_faces")
+aGroup.Add(aFaceIds)
+
+salome.sg.updateObjBrowser(1)
+\endcode
+
+
\anchor tui_length_2d
Length 2D
@@ -572,4 +706,4 @@ aGroup.Add(anIds)
salome.sg.updateObjBrowser(1)
\endcode
-*/
\ No newline at end of file
+*/
diff --git a/doc/salome/gui/SMESH/input/using_operations_on_groups.doc b/doc/salome/gui/SMESH/input/using_operations_on_groups.doc
index 12267df2b..916061733 100644
--- a/doc/salome/gui/SMESH/input/using_operations_on_groups.doc
+++ b/doc/salome/gui/SMESH/input/using_operations_on_groups.doc
@@ -13,13 +13,13 @@ belong to one and the same mesh.
\anchor union_anchor
-Union of two groups
+Union of groups
This operation allows to create a new group in such a way that all
mesh elements that are present in the initial groups will be added to
the new one.
-To union two groups:
+To union groups:
In the \b Mesh menu select the Union Groups item. The following
dialog box will appear:
@@ -27,7 +27,7 @@ dialog box will appear:
\image html uniongroups.png
In this dialog box you should specify the name of the resulting group
-and two groups which will be united.
+and set of groups which will be united.
For example, we have two groups Group1 and Group2.
\n The result of their \b Union will be Group12:
@@ -45,17 +45,17 @@ For example, we have two groups Group1 and Group2.
See Also a sample TUI Script of a
-\ref tui_union_of_two_groups "Union of two Groups" operation.
+\ref tui_union_of_groups "Union of Groups" operation.
\anchor intersection_anchor
-Intersection of two groups
+Intersection of groups
This operation allows to create a new group in such a way that all
-mesh elements that are present in both initial groups are added to the
+mesh elements that are present in all initial groups together are added to the
new one.
-To intersect two groups:
+To intersect groups:
In the \b Mesh menu select the Intersect Groups item. The
following dialog box will appear:
@@ -63,7 +63,7 @@ following dialog box will appear:
\image html intersectgroups.png
In this dialog box you should specify the name of the resulting group
-and two groups which will be intersected.
+and set of groups which will be intersected.
For example, we have two groups Group1 and Group2.
\n The result of their \b Intersection will be Group12a:
@@ -81,17 +81,17 @@ For example, we have two groups Group1 and Group2.
See Also a sample TUI Script of an
-\ref tui_intersection_of_two_groups "Intersection of two Groups" operation.
+\ref tui_intersection_of_groups "Intersection of Groups" operation.
\anchor cut_anchor
-Cut of two groups
+Cut of groups
This operation allows to create a new group in such a way that all
-mesh elements that are present in the main group but are absent in the
-tool group are added to the new one.
+mesh elements that are present in the main groups but are absent in the
+tool groups are added to the new one.
-To cut two groups:
+To cut groups:
In the \b Mesh menu select the Cut Groups item. The
following dialog box will appear:
@@ -99,7 +99,7 @@ following dialog box will appear:
\image html cutgroups.png
In this dialog box you should specify the name of the resulting group
-and two groups which will be cut.
+and groups which will be cut.
For example, we have two groups Group1 and Group2.
\n The result of their \b Cut will be Group12b:
@@ -118,6 +118,6 @@ group.
See Also a sample TUI Script of a
-\ref tui_cut_of_two_groups "Cut of two Groups" operation.
+\ref tui_cut_of_groups "Cut of Groups" operation.
*/
\ No newline at end of file
diff --git a/idl/Makefile.am b/idl/Makefile.am
index d1048dbef..a1d468cb5 100644
--- a/idl/Makefile.am
+++ b/idl/Makefile.am
@@ -66,7 +66,8 @@ libSalomeIDLSMESH_la_LDFLAGS = -no-undefined -version-info=0:0:0
libSalomeIDLSMESH_la_LIBADD = \
@CORBA_LIBS@ \
$(MED_LDFLAGS) -lSalomeIDLMED \
- $(GEOM_LDFLAGS) -lSalomeIDLGEOM
+ $(GEOM_LDFLAGS) -lSalomeIDLGEOM \
+ $(KERNEL_LDFLAGS) -lSalomeIDLKernel
# These variables defines the building process of CORBA files
OMNIORB_IDL = @OMNIORB_IDL@
diff --git a/idl/SMESH_BasicHypothesis.idl b/idl/SMESH_BasicHypothesis.idl
index 832a07208..9c428ba14 100644
--- a/idl/SMESH_BasicHypothesis.idl
+++ b/idl/SMESH_BasicHypothesis.idl
@@ -72,6 +72,44 @@ module StdMeshers
double GetPrecision();
};
+ /*!
+ * StdMeshers_MaxLength: interface of "Max length" hypothesis
+ */
+ interface StdMeshers_MaxLength : SMESH::SMESH_Hypothesis
+ {
+ /*!
+ * Sets parameter value
+ */
+ void SetLength(in double length)
+ raises (SALOME::SALOME_Exception);
+ /*!
+ * Returns parameter value
+ */
+ double GetLength();
+ /*!
+ * Returns true if preestemated length is defined
+ */
+ boolean HavePreestimatedLength();
+ /*!
+ * Returns preestemated length
+ */
+ double GetPreestimatedLength();
+ /*!
+ * Sets preestemated length
+ */
+ void SetPreestimatedLength(in double length);
+ /*!
+ * Sets boolean parameter enabling/desabling usage of length computed
+ * basing on size of bounding box of shape to mesh
+ */
+ void SetUsePreestimatedLength(in boolean toUse);
+ /*!
+ * Returns value of boolean parameter enabling/desabling usage of length computed
+ * basing on size of bounding box of shape to mesh
+ */
+ boolean GetUsePreestimatedLength();
+ };
+
/*!
* StdMeshers_AutomaticLength: interface of "Automatic length" hypothesis
*/
diff --git a/idl/SMESH_Filter.idl b/idl/SMESH_Filter.idl
index 5e1694021..83c1d43d2 100644
--- a/idl/SMESH_Filter.idl
+++ b/idl/SMESH_Filter.idl
@@ -48,6 +48,8 @@ module SMESH
FT_Volume3D,
FT_FreeBorders,
FT_FreeEdges,
+ FT_FreeNodes,
+ FT_FreeFaces,
FT_MultiConnection,
FT_MultiConnection2D,
FT_Length,
@@ -59,6 +61,9 @@ module SMESH
FT_LyingOnGeom,
FT_RangeOfIds,
FT_BadOrientedVolume,
+ FT_LinearOrQuadratic,
+ FT_GroupColor,
+ FT_ElemGeomType,
FT_LessThan,
FT_MoreThan,
FT_EqualTo,
@@ -125,7 +130,7 @@ module SMESH
typedef sequence Values;
Values GetValues();
};
-
+
/*!
* Predicates are intended for verification of criteria,
* must return bool value by mesh id
@@ -241,7 +246,6 @@ module SMESH
* Verify whether 2D mesh element has free edges( i.e. edges connected to one face only )
*/
interface FreeEdges: Predicate
-
{
struct Border
{
@@ -252,6 +256,17 @@ module SMESH
Borders GetBorders();
};
+ /*!
+ * Logical functor (predicate) "Free nodes".
+ * Verify whether mesh has free nodes( i.e. nodes are not connected to any element )
+ */
+ interface FreeNodes: Predicate{};
+
+ /*!
+ * Logical functor (predicate) "Free faces".
+ * Verify whether 2D mesh element is free ( i.e. connected to one volume only )
+ */
+ interface FreeFaces: Predicate{};
/*!
* Abstract logical functor (predicate) "RangeOfIds".
@@ -303,6 +318,33 @@ module SMESH
interface LogicalAND: LogicalBinary{};
interface LogicalOR : LogicalBinary{};
+ /*!
+ * Logical functor (predicate) "Is element Linear or Quadratic".
+ * Verify whether a mesh element is linear
+ */
+ interface LinearOrQuadratic: Predicate {
+ void SetElementType( in ElementType theType );
+ };
+
+ /*!
+ * Functor "Group Color"
+ * Returns color of group to which mesh element belongs to
+ */
+ interface GroupColor : Predicate{
+ void SetElementType( in ElementType theType );
+ void SetColorStr( in string theColor );
+ string GetColorStr();
+ };
+
+ /*!
+ * Functor "Element geometry type"
+ * Returns is element has indicated geometry type
+ */
+ interface ElemGeomType : Predicate{
+ void SetElementType ( in ElementType theType );
+ void SetGeometryType( in GeometryType theType );
+ };
+
/*!
* Filter
*/
@@ -319,6 +361,7 @@ module SMESH
* ThresholdStr - Threshold value defined as string. Used for:
* 1. Diaposon of identifiers. Example: "1,2,3,5-10,12,27-29"
* 2. BelongToGeom predicate for storing name of shape
+ * 3. GroupColor predicate for storing group color "0.2;0;0.5"
* ThresholdID - One more threshold value defined as string. Used for:
* 1. BelongToGeom predicate for storing id of shape
* Tolerance - Tolerance is used for comparators (EqualTo comparision) and for
@@ -423,10 +466,16 @@ module SMESH
FreeBorders CreateFreeBorders();
FreeEdges CreateFreeEdges();
+ FreeNodes CreateFreeNodes();
+ FreeFaces CreateFreeFaces();
RangeOfIds CreateRangeOfIds();
BadOrientedVolume CreateBadOrientedVolume();
+ LinearOrQuadratic CreateLinearOrQuadratic();
+
+ GroupColor CreateGroupColor();
+ ElemGeomType CreateElemGeomType();
/*!
* Create comparators ( predicates )
diff --git a/idl/SMESH_Gen.idl b/idl/SMESH_Gen.idl
index 584522f4f..e28b3a163 100644
--- a/idl/SMESH_Gen.idl
+++ b/idl/SMESH_Gen.idl
@@ -21,8 +21,7 @@
//
// File : SMESH_Gen.idl
// Author : Paul RASCLE, EDF
-// $Header$
-//
+
#ifndef _SMESH_GEN_IDL_
#define _SMESH_GEN_IDL_
@@ -151,16 +150,30 @@ module SMESH
raises ( SALOME::SALOME_Exception );
/*!
- * Return a hypothesis holding parameter values corresponding to the mesh
- * existing on the given geometry.
+ * Return a hypothesis holding parameter values corresponding either to the mesh
+ * existing on the given geometry or to size of the geometry.
* The returned hypothesis may be the one existing in a study and used
* to compute the mesh, or a temporary one created just to pass parameter
- * values
+ * values.
*/
SMESH_Hypothesis GetHypothesisParameterValues( in string theHypName,
in string theLibName,
in SMESH_Mesh theMesh,
- in GEOM::GEOM_Object theGeom)
+ in GEOM::GEOM_Object theGeom,
+ in boolean byMesh)
+ raises ( SALOME::SALOME_Exception );
+
+ /*!
+ * Sets number of segments per diagonal of boundary box of geometry by which
+ * default segment length of appropriate 1D hypotheses is defined
+ */
+ void SetBoundaryBoxSegmentation( in long theNbSegments );
+
+ /*!
+ * Set the object name
+ */
+ void SetName( in string theObjectIOR,
+ in string theObjectName )
raises ( SALOME::SALOME_Exception );
/*!
@@ -174,7 +187,7 @@ module SMESH
raises ( SALOME::SALOME_Exception );
/*!
- * Create a empty mesh object
+ * Create an empty mesh object
*/
SMESH_Mesh CreateEmptyMesh()
raises ( SALOME::SALOME_Exception );
@@ -221,6 +234,17 @@ module SMESH
in GEOM::GEOM_Object theSubObject )
raises ( SALOME::SALOME_Exception );
+ /*!
+ * Calculate Mesh as preview till indicated dimension
+ * First, verify list of hypothesis associated with the subShape.
+ * Return mesh preview structure
+ */
+ MeshPreviewStruct Precompute( in SMESH_Mesh theMesh,
+ in GEOM::GEOM_Object theSubObject,
+ in Dimension theDimension,
+ inout long_array theShapesId )
+ raises ( SALOME::SALOME_Exception );
+
/*!
* Return errors of hypotheses definintion
* algo_error_array is empty if everything is OK
diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl
index e41154e2c..9b5b3477e 100644
--- a/idl/SMESH_Mesh.idl
+++ b/idl/SMESH_Mesh.idl
@@ -21,8 +21,8 @@
//
// File : SMESH_Mesh.idl
// Author : Paul RASCLE, EDF
-// $Header$
//
+
#ifndef _SMESH_MESH_IDL_
#define _SMESH_MESH_IDL_
@@ -114,6 +114,23 @@ module SMESH
FACE,
VOLUME
};
+
+ /*!
+ * Enumeration for element geometry type, like in SMDS
+ */
+ enum GeometryType
+ {
+ Geom_POINT,
+ Geom_EDGE,
+ Geom_TRIANGLE,
+ Geom_QUADRANGLE,
+ Geom_POLYGON,
+ Geom_TETRA,
+ Geom_PYRAMID,
+ Geom_HEXA,
+ Geom_PENTA,
+ Geom_POLYHEDRA
+ };
/*!
* ElementOrder points out entities of what order are requested
@@ -228,6 +245,12 @@ module SMESH
void Clear()
raises (SALOME::SALOME_Exception);
+ /*!
+ * Remove all nodes and elements of submesh
+ */
+ void ClearSubMesh(in long ShapeID)
+ raises (SALOME::SALOME_Exception);
+
/*!
* Get the subMesh object associated to a subShape. The subMesh object
* gives access to nodes and elements IDs.
@@ -292,6 +315,15 @@ module SMESH
in SMESH_GroupBase aGroup2,
in string name )
raises (SALOME::SALOME_Exception);
+
+ /*!
+ * Union of list of groups
+ * New group is created. All mesh elements that are
+ * present in initial groups are added to the new one
+ */
+ SMESH_Group UnionListOfGroups (in ListOfGroups aListOfGroups,
+ in string name )
+ raises (SALOME::SALOME_Exception);
/*!
* Intersection of two groups
@@ -302,6 +334,15 @@ module SMESH
in SMESH_GroupBase aGroup2,
in string name )
raises (SALOME::SALOME_Exception);
+
+ /*!
+ * Intersection of list of groups
+ * New group is created. All mesh elements that are
+ * present in all initial groups simultaneously are added to the new one.
+ */
+ SMESH_Group IntersectListOfGroups (in ListOfGroups aListOfGroups,
+ in string name)
+ raises (SALOME::SALOME_Exception);
/*!
* Cut of two groups
@@ -309,8 +350,35 @@ module SMESH
* main group but do not present in tool group are added to the new one
*/
SMESH_Group CutGroups (in SMESH_GroupBase aMainGroup,
- in SMESH_GroupBase aToolGroup,
- in string name )
+ in SMESH_GroupBase aToolGroup,
+ in string name )
+ raises (SALOME::SALOME_Exception);
+
+ /*!
+ * Cut of lists of groups
+ * New group is created. All mesh elements that are present in
+ * main groups but do not present in tool groups are added to the new one
+ */
+ SMESH_Group CutListOfGroups (in ListOfGroups aMainGroups,
+ in ListOfGroups aToolGroups,
+ in string name)
+ raises (SALOME::SALOME_Exception);
+
+ /*!
+ * Create groups of entities from existing groups of superior dimensions
+ * New group is created. System
+ * 1) extracts all nodes from each group,
+ * 2) combines all elements of specified dimension laying on these nodes.
+ */
+ SMESH_Group CreateDimGroup( in ListOfGroups aListOfGroups,
+ in ElementType anElemType,
+ in string name )
+ raises (SALOME::SALOME_Exception);
+
+ /*!
+ * Convert group on geometry into standalone group
+ */
+ SMESH_Group ConvertToStandalone( in SMESH_GroupOnGeom theGeomGroup )
raises (SALOME::SALOME_Exception);
/*!
diff --git a/idl/SMESH_MeshEditor.idl b/idl/SMESH_MeshEditor.idl
index 5da298ac4..bba45665b 100644
--- a/idl/SMESH_MeshEditor.idl
+++ b/idl/SMESH_MeshEditor.idl
@@ -20,8 +20,8 @@
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File : SMESH_MeshEditor.idl
-// $Header$
//
+
#ifndef _SMESH_MESHEDITOR_IDL_
#define _SMESH_MESHEDITOR_IDL_
@@ -576,6 +576,49 @@ module SMESH
* not creared - returns empty list
*/
long_array GetLastCreatedElems();
+
+ /*!
+ * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+ * \param theNodes - identifiers of nodes to be doubled
+ * \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
+ * nodes. If list of element identifiers is empty then nodes are doubled but
+ * they not assigned to elements
+ * \return TRUE if operation has been completed successfully, FALSE otherwise
+ * \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
+ */
+ boolean DoubleNodes( in long_array theNodes, in long_array theModifiedElems );
+
+ /*!
+ * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+ * This method provided for convenience works as DoubleNodes() described above.
+ * \param theNodeId - identifier of node to be doubled.
+ * \param theModifiedElems - identifiers of elements to be updated.
+ * \return TRUE if operation has been completed successfully, FALSE otherwise
+ * \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
+ */
+ boolean DoubleNode( in long theNodeId, in long_array theModifiedElems );
+
+ /*!
+ * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+ * This method provided for convenience works as DoubleNodes() described above.
+ * \param theNodes - group of nodes to be doubled.
+ * \param theModifiedElems - group of elements to be updated.
+ * \return TRUE if operation has been completed successfully, FALSE otherwise
+ * \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
+ */
+ boolean DoubleNodeGroup( in SMESH_GroupBase theNodes,
+ in SMESH_GroupBase theModifiedElems );
+
+ /*!
+ \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+ This method provided for convenience works as DoubleNodes() described above.
+ \param theNodes - list of groups of nodes to be doubled
+ \param theModifiedElems - list of groups of elements to be updated.
+ \return TRUE if operation has been completed successfully, FALSE otherwise
+ \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
+ */
+ boolean DoubleNodeGroups( in ListOfGroups theNodes,
+ in ListOfGroups theModifiedElems );
};
};
diff --git a/resources/Makefile.am b/resources/Makefile.am
index 5c804268b..2ebd83edf 100644
--- a/resources/Makefile.am
+++ b/resources/Makefile.am
@@ -23,7 +23,6 @@
# Author : Patrick GOLDBRONN (CEA)
# Date : 28/06/2001
# Modified by : Alexander BORODIN (OCN) - autotools usage
-# $Header$
#
include $(top_srcdir)/adm_local/unix/make_common_starter.am
@@ -58,6 +57,7 @@ dist_salomeres_DATA = \
mesh_length_2d.png \
mesh_free_edges.png \
mesh_free_edges_2d.png \
+ mesh_free_nodes.png \
mesh_multi_edges.png \
mesh_multi_edges_2d.png \
mesh_line_n.png \
@@ -162,7 +162,10 @@ dist_salomeres_DATA = \
mesh_tree_hypo_projection_2d.png \
mesh_build_compound.png \
mesh_node_to_point.png \
- mesh_tree_mesh_partial.png
+ mesh_tree_mesh_partial.png \
+ mesh_extractGroup.png \
+ mesh_precompute.png \
+ mesh_free_faces.png
# VSR: little trick to avoid putting if SMESHCatalog.xml to the distribution archive
nodist_salomeres_SCRIPTS = SMESHCatalog.xml
diff --git a/resources/SalomeApp.xml b/resources/SalomeApp.xml
index 0390e89a7..6a8d6d34d 100644
--- a/resources/SalomeApp.xml
+++ b/resources/SalomeApp.xml
@@ -46,9 +46,9 @@
-
-
-
+
+
+
@@ -57,15 +57,16 @@
-
-
+
+
-
+
+
diff --git a/resources/StdMeshers.xml b/resources/StdMeshers.xml
index 54fb82fe8..4adf93e83 100644
--- a/resources/StdMeshers.xml
+++ b/resources/StdMeshers.xml
@@ -44,6 +44,11 @@
icon-id="mesh_hypo_length.png"
dim="1"/>
+
+
diff --git a/resources/mesh_extractGroup.png b/resources/mesh_extractGroup.png
new file mode 100755
index 000000000..39ad76395
Binary files /dev/null and b/resources/mesh_extractGroup.png differ
diff --git a/resources/mesh_free_faces.png b/resources/mesh_free_faces.png
new file mode 100644
index 000000000..91adc31d6
Binary files /dev/null and b/resources/mesh_free_faces.png differ
diff --git a/resources/mesh_free_nodes.png b/resources/mesh_free_nodes.png
new file mode 100644
index 000000000..b1b3190d1
Binary files /dev/null and b/resources/mesh_free_nodes.png differ
diff --git a/resources/mesh_precompute.png b/resources/mesh_precompute.png
new file mode 100644
index 000000000..dd90498cf
Binary files /dev/null and b/resources/mesh_precompute.png differ
diff --git a/src/Controls/Makefile.am b/src/Controls/Makefile.am
index 18ea3d9c5..0dd516e94 100644
--- a/src/Controls/Makefile.am
+++ b/src/Controls/Makefile.am
@@ -47,11 +47,12 @@ libSMESHControls_la_CPPFLAGS = \
$(CAS_CPPFLAGS) \
$(BOOST_CPPFLAGS) \
$(KERNEL_CXXFLAGS) \
- -I$(srcdir)/../SMDS
+ -I$(srcdir)/../SMDS \
+ -I$(srcdir)/../SMESHDS
libSMESHControls_la_LDFLAGS = \
../SMDS/libSMDS.la \
- $(KERNEL_LDFLAGS) -lOpUtil\
+ ../SMESHDS/libSMESHDS.la \
$(CAS_LDPATH) -lTKernel -lTKBRep -lTKG3d
SMESHControls_CPPFLAGS = \
@@ -60,6 +61,7 @@ SMESHControls_CPPFLAGS = \
SMESHControls_LDADD = \
../SMDS/libSMDS.la \
+ ../SMESHDS/libSMESHDS.la \
libSMESHControls.la \
$(KERNEL_LDFLAGS) -lOpUtil -lSALOMELocalTrace -lSALOMEBasics \
$(GEOM_LDFLAGS) -lGEOMAlgo \
diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx
index e44d45b7e..45e9f79ea 100644
--- a/src/Controls/SMESH_Controls.cxx
+++ b/src/Controls/SMESH_Controls.cxx
@@ -61,6 +61,9 @@
#include "SMDS_QuadraticFaceOfNodes.hxx"
#include "SMDS_QuadraticEdge.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESHDS_GroupBase.hxx"
+
/*
AUXILIARY METHODS
*/
@@ -1693,6 +1696,306 @@ void FreeEdges::GetBoreders(TBorders& theBorders)
//std::cout<<"theBorders.size() = "<FindNode( theNodeId );
+ if (!aNode)
+ return false;
+
+ return (aNode->NbInverseElements() < 1);
+}
+
+SMDSAbs_ElementType FreeNodes::GetType() const
+{
+ return SMDSAbs_Node;
+}
+
+
+/*
+ Class : FreeFaces
+ Description : Predicate for free faces
+*/
+
+FreeFaces::FreeFaces()
+{
+ myMesh = 0;
+}
+
+void FreeFaces::SetMesh( const SMDS_Mesh* theMesh )
+{
+ myMesh = theMesh;
+}
+
+bool FreeFaces::IsSatisfy( long theId )
+{
+ if (!myMesh) return false;
+ // check that faces nodes refers to less than two common volumes
+ const SMDS_MeshElement* aFace = myMesh->FindElement( theId );
+ if ( !aFace || aFace->GetType() != SMDSAbs_Face )
+ return false;
+
+ int nbNode = aFace->NbNodes();
+
+ // collect volumes check that number of volumss with count equal nbNode not less than 2
+ typedef map< SMDS_MeshElement*, int > TMapOfVolume; // map of volume counters
+ typedef map< SMDS_MeshElement*, int >::iterator TItrMapOfVolume; // iterator
+ TMapOfVolume mapOfVol;
+
+ SMDS_ElemIteratorPtr nodeItr = aFace->nodesIterator();
+ while ( nodeItr->more() ) {
+ const SMDS_MeshNode* aNode = static_cast(nodeItr->next());
+ if ( !aNode ) continue;
+ SMDS_ElemIteratorPtr volItr = aNode->GetInverseElementIterator(SMDSAbs_Volume);
+ while ( volItr->more() ) {
+ SMDS_MeshElement* aVol = (SMDS_MeshElement*)volItr->next();
+ TItrMapOfVolume itr = mapOfVol.insert(make_pair(aVol, 0)).first;
+ (*itr).second++;
+ }
+ }
+ int nbVol = 0;
+ TItrMapOfVolume volItr = mapOfVol.begin();
+ TItrMapOfVolume volEnd = mapOfVol.end();
+ for ( ; volItr != volEnd; ++volItr )
+ if ( (*volItr).second >= nbNode )
+ nbVol++;
+ // face is not free if number of volumes constructed on thier nodes more than one
+ return (nbVol < 2);
+}
+
+SMDSAbs_ElementType FreeFaces::GetType() const
+{
+ return SMDSAbs_Face;
+}
+
+/*
+ Class : LinearOrQuadratic
+ Description : Predicate to verify whether a mesh element is linear
+*/
+
+LinearOrQuadratic::LinearOrQuadratic()
+{
+ myMesh = 0;
+}
+
+void LinearOrQuadratic::SetMesh( const SMDS_Mesh* theMesh )
+{
+ myMesh = theMesh;
+}
+
+bool LinearOrQuadratic::IsSatisfy( long theId )
+{
+ if (!myMesh) return false;
+ const SMDS_MeshElement* anElem = myMesh->FindElement( theId );
+ if ( !anElem || (myType != SMDSAbs_All && anElem->GetType() != myType) )
+ return false;
+ return (!anElem->IsQuadratic());
+}
+
+void LinearOrQuadratic::SetType( SMDSAbs_ElementType theType )
+{
+ myType = theType;
+}
+
+SMDSAbs_ElementType LinearOrQuadratic::GetType() const
+{
+ return myType;
+}
+
+/*
+ Class : GroupColor
+ Description : Functor for check color of group to whic mesh element belongs to
+*/
+
+GroupColor::GroupColor()
+{
+}
+
+bool GroupColor::IsSatisfy( long theId )
+{
+ return (myIDs.find( theId ) != myIDs.end());
+}
+
+void GroupColor::SetType( SMDSAbs_ElementType theType )
+{
+ myType = theType;
+}
+
+SMDSAbs_ElementType GroupColor::GetType() const
+{
+ return myType;
+}
+
+static bool isEqual( const Quantity_Color& theColor1,
+ const Quantity_Color& theColor2 )
+{
+ // tolerance to compare colors
+ const double tol = 5*1e-3;
+ return ( fabs( theColor1.Red() - theColor2.Red() ) < tol &&
+ fabs( theColor1.Green() - theColor2.Green() ) < tol &&
+ fabs( theColor1.Blue() - theColor2.Blue() ) < tol );
+}
+
+
+void GroupColor::SetMesh( const SMDS_Mesh* theMesh )
+{
+ myIDs.clear();
+
+ const SMESHDS_Mesh* aMesh = dynamic_cast(theMesh);
+ if ( !aMesh )
+ return;
+
+ int nbGrp = aMesh->GetNbGroups();
+ if ( !nbGrp )
+ return;
+
+ // iterates on groups and find necessary elements ids
+ const std::set& aGroups = aMesh->GetGroups();
+ set::const_iterator GrIt = aGroups.begin();
+ for (; GrIt != aGroups.end(); GrIt++) {
+ SMESHDS_GroupBase* aGrp = (*GrIt);
+ if ( !aGrp )
+ continue;
+ // check type and color of group
+ if ( !isEqual( myColor, aGrp->GetColor() ) )
+ continue;
+ if ( myType != SMDSAbs_All && myType != (SMDSAbs_ElementType)aGrp->GetType() )
+ continue;
+
+ // add elements IDS into control
+ int aSize = aGrp->Extent();
+ for (int i = 0; i < aSize; i++)
+ myIDs.insert( aGrp->GetID(i+1) );
+ }
+}
+
+void GroupColor::SetColorStr( const TCollection_AsciiString& theStr )
+{
+ TCollection_AsciiString aStr = theStr;
+ aStr.RemoveAll( ' ' );
+ aStr.RemoveAll( '\t' );
+ for ( int aPos = aStr.Search( ";;" ); aPos != -1; aPos = aStr.Search( ";;" ) )
+ aStr.Remove( aPos, 2 );
+ Standard_Real clr[3];
+ clr[0] = clr[1] = clr[2] = 0.;
+ for ( int i = 0; i < 3; i++ ) {
+ TCollection_AsciiString tmpStr = aStr.Token( ";", i+1 );
+ if ( !tmpStr.IsEmpty() && tmpStr.IsRealValue() )
+ clr[i] = tmpStr.RealValue();
+ }
+ myColor = Quantity_Color( clr[0], clr[1], clr[2], Quantity_TOC_RGB );
+}
+
+//=======================================================================
+// name : GetRangeStr
+// Purpose : Get range as a string.
+// Example: "1,2,3,50-60,63,67,70-"
+//=======================================================================
+void GroupColor::GetColorStr( TCollection_AsciiString& theResStr ) const
+{
+ theResStr.Clear();
+ theResStr += TCollection_AsciiString( myColor.Red() );
+ theResStr += TCollection_AsciiString( ";" ) + TCollection_AsciiString( myColor.Green() );
+ theResStr += TCollection_AsciiString( ";" ) + TCollection_AsciiString( myColor.Blue() );
+}
+
+/*
+ Class : ElemGeomType
+ Description : Predicate to check element geometry type
+*/
+
+ElemGeomType::ElemGeomType()
+{
+ myMesh = 0;
+ myType = SMDSAbs_All;
+ myGeomType = SMDSGeom_TRIANGLE;
+}
+
+void ElemGeomType::SetMesh( const SMDS_Mesh* theMesh )
+{
+ myMesh = theMesh;
+}
+
+bool ElemGeomType::IsSatisfy( long theId )
+{
+ if (!myMesh) return false;
+ const SMDS_MeshElement* anElem = myMesh->FindElement( theId );
+ const SMDSAbs_ElementType anElemType = anElem->GetType();
+ if ( !anElem || (myType != SMDSAbs_All && anElemType != myType) )
+ return false;
+ const int aNbNode = anElem->NbNodes();
+ bool isOk = false;
+ switch( anElemType )
+ {
+ case SMDSAbs_Node:
+ isOk = (myGeomType == SMDSGeom_POINT);
+ break;
+
+ case SMDSAbs_Edge:
+ isOk = (myGeomType == SMDSGeom_EDGE);
+ break;
+
+ case SMDSAbs_Face:
+ if ( myGeomType == SMDSGeom_TRIANGLE )
+ isOk = (!anElem->IsPoly() && aNbNode == 3);
+ else if ( myGeomType == SMDSGeom_QUADRANGLE )
+ isOk = (!anElem->IsPoly() && aNbNode == 4);
+ else if ( myGeomType == SMDSGeom_POLYGON )
+ isOk = anElem->IsPoly();
+ break;
+
+ case SMDSAbs_Volume:
+ if ( myGeomType == SMDSGeom_TETRA )
+ isOk = (!anElem->IsPoly() && aNbNode == 4);
+ else if ( myGeomType == SMDSGeom_PYRAMID )
+ isOk = (!anElem->IsPoly() && aNbNode == 5);
+ else if ( myGeomType == SMDSGeom_PENTA )
+ isOk = (!anElem->IsPoly() && aNbNode == 6);
+ else if ( myGeomType == SMDSGeom_HEXA )
+ isOk = (!anElem->IsPoly() && aNbNode == 8);
+ else if ( myGeomType == SMDSGeom_POLYHEDRA )
+ isOk = anElem->IsPoly();
+ break;
+ default: break;
+ }
+ return isOk;
+}
+
+void ElemGeomType::SetType( SMDSAbs_ElementType theType )
+{
+ myType = theType;
+}
+
+SMDSAbs_ElementType ElemGeomType::GetType() const
+{
+ return myType;
+}
+
+void ElemGeomType::SetGeomType( SMDSAbs_GeometryType theType )
+{
+ myGeomType = theType;
+}
+
+SMDSAbs_GeometryType ElemGeomType::GetGeomType() const
+{
+ return myGeomType;
+}
+
/*
Class : RangeOfIds
Description : Predicate for Range of Ids.
diff --git a/src/Controls/SMESH_ControlsDef.hxx b/src/Controls/SMESH_ControlsDef.hxx
index abc5117cd..d692a6e5d 100644
--- a/src/Controls/SMESH_ControlsDef.hxx
+++ b/src/Controls/SMESH_ControlsDef.hxx
@@ -38,6 +38,7 @@
#include
#include
#include
+#include
#include "SMDSAbs_ElementType.hxx"
#include "SMDS_MeshNode.hxx"
@@ -382,7 +383,23 @@ namespace SMESH{
const SMDS_Mesh* myMesh;
};
typedef boost::shared_ptr FreeEdgesPtr;
+
+
+ /*
+ Class : FreeNodes
+ Description : Predicate for free nodes
+ */
+ class SMESHCONTROLS_EXPORT FreeNodes: public virtual Predicate{
+ public:
+ FreeNodes();
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
+ virtual bool IsSatisfy( long theNodeId );
+ virtual SMDSAbs_ElementType GetType() const;
+ protected:
+ const SMDS_Mesh* myMesh;
+ };
+
/*
Class : RangeOfIds
@@ -696,6 +713,83 @@ namespace SMESH{
typedef boost::shared_ptr ElementsOnShapePtr;
+ /*
+ Class : FreeFaces
+ Description : Predicate for free faces
+ */
+ class SMESHCONTROLS_EXPORT FreeFaces: public virtual Predicate{
+ public:
+ FreeFaces();
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
+ virtual bool IsSatisfy( long theElementId );
+ virtual SMDSAbs_ElementType GetType() const;
+
+ private:
+ const SMDS_Mesh* myMesh;
+ };
+
+ /*
+ Class : LinearOrQuadratic
+ Description : Predicate for free faces
+ */
+ class SMESHCONTROLS_EXPORT LinearOrQuadratic: public virtual Predicate{
+ public:
+ LinearOrQuadratic();
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
+ virtual bool IsSatisfy( long theElementId );
+ void SetType( SMDSAbs_ElementType theType );
+ virtual SMDSAbs_ElementType GetType() const;
+
+ private:
+ const SMDS_Mesh* myMesh;
+ SMDSAbs_ElementType myType;
+ };
+ typedef boost::shared_ptr LinearOrQuadraticPtr;
+
+ /*
+ Class : GroupColor
+ Description : Functor for check color of group to whic mesh element belongs to
+ */
+ class SMESHCONTROLS_EXPORT GroupColor: public virtual Predicate{
+ public:
+ GroupColor();
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
+ virtual bool IsSatisfy( long theElementId );
+ void SetType( SMDSAbs_ElementType theType );
+ virtual SMDSAbs_ElementType GetType() const;
+ void SetColorStr( const TCollection_AsciiString& );
+ void GetColorStr( TCollection_AsciiString& ) const;
+
+ private:
+ typedef std::set< long > TIDs;
+
+ Quantity_Color myColor;
+ SMDSAbs_ElementType myType;
+ TIDs myIDs;
+ };
+ typedef boost::shared_ptr GroupColorPtr;
+
+ /*
+ Class : ElemGeomType
+ Description : Predicate to check element geometry type
+ */
+ class SMESHCONTROLS_EXPORT ElemGeomType: public virtual Predicate{
+ public:
+ ElemGeomType();
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
+ virtual bool IsSatisfy( long theElementId );
+ void SetType( SMDSAbs_ElementType theType );
+ virtual SMDSAbs_ElementType GetType() const;
+ void SetGeomType( SMDSAbs_GeometryType theType );
+ virtual SMDSAbs_GeometryType GetGeomType() const;
+
+ private:
+ const SMDS_Mesh* myMesh;
+ SMDSAbs_ElementType myType;
+ SMDSAbs_GeometryType myGeomType;
+ };
+ typedef boost::shared_ptr ElemGeomTypePtr;
+
/*
FILTER
*/
diff --git a/src/OBJECT/SMESH_Actor.cxx b/src/OBJECT/SMESH_Actor.cxx
index 7be22f7c5..49d838bac 100644
--- a/src/OBJECT/SMESH_Actor.cxx
+++ b/src/OBJECT/SMESH_Actor.cxx
@@ -23,8 +23,8 @@
// File : SMESH_Actor.cxx
// Author : Nicolas REJNERI
// Module : SMESH
-// $Header$
-//
+
+
#include "SMESH_ActorDef.h"
#include "SMESH_ActorUtils.h"
#include "SMESH_DeviceActor.h"
@@ -153,6 +153,27 @@ SMESH_ActorDef::SMESH_ActorDef()
aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
+ my2DExtProp = vtkProperty::New();
+ my2DExtProp->DeepCopy(mySurfaceProp);
+ SMESH::GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
+ anRGB[0] = 1 - anRGB[0];
+ anRGB[1] = 1 - anRGB[1];
+ anRGB[2] = 1 - anRGB[2];
+ my2DExtProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+
+ my2DExtActor = SMESH_DeviceActor::New();
+ my2DExtActor->SetUserMatrix(aMatrix);
+ my2DExtActor->PickableOff();
+ my2DExtActor->SetProperty(my2DExtProp);
+ my2DExtActor->SetBackfaceProperty(my2DExtProp);
+ my2DExtActor->SetRepresentation(SMESH_DeviceActor::eInsideframe);
+ aFilter = my2DExtActor->GetExtractUnstructuredGrid();
+ aFilter->RegisterCellsWithType(VTK_TRIANGLE);
+ aFilter->RegisterCellsWithType(VTK_POLYGON);
+ aFilter->RegisterCellsWithType(VTK_QUAD);
+ aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
+ aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
+
my3DActor = SMESH_DeviceActor::New();
my3DActor->SetUserMatrix(aMatrix);
my3DActor->PickableOff();
@@ -196,7 +217,7 @@ SMESH_ActorDef::SMESH_ActorDef()
my1DProp->DeepCopy(myEdgeProp);
my1DProp->SetLineWidth(aLineWidth + aLineWidthInc);
my1DProp->SetPointSize(aPointSize);
-
+
my1DExtProp = vtkProperty::New();
my1DExtProp->DeepCopy(myEdgeProp);
anRGB[0] = 1 - anRGB[0];
@@ -235,7 +256,26 @@ SMESH_ActorDef::SMESH_ActorDef()
myNodeActor->SetRepresentation(SMESH_DeviceActor::ePoint);
aFilter = myNodeActor->GetExtractUnstructuredGrid();
aFilter->SetModeOfExtraction(VTKViewer_ExtractUnstructuredGrid::ePoints);
+
+ myNodeExtProp = vtkProperty::New();
+ myNodeExtProp->DeepCopy(myNodeProp);
+ anRGB[0] = 1 - anRGB[0];
+ anRGB[1] = 1 - anRGB[1];
+ anRGB[2] = 1 - anRGB[2];
+ myNodeExtProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+ myNodeExtProp->SetPointSize(aPointSize);
+ myNodeExtActor = SMESH_DeviceActor::New();
+ myNodeExtActor->SetUserMatrix(aMatrix);
+ myNodeExtActor->SetStoreClippingMapping(true);
+ myNodeExtActor->PickableOff();
+ myNodeExtActor->SetHighlited(true);
+ myNodeExtActor->SetVisibility(false);
+ myNodeExtActor->SetProperty(myNodeExtProp);
+ myNodeExtActor->SetRepresentation(SMESH_DeviceActor::ePoint);
+ aFilter = myNodeExtActor->GetExtractUnstructuredGrid();
+ aFilter->SetModeOfExtraction(VTKViewer_ExtractUnstructuredGrid::ePoints);
+ aFilter->RegisterCellsWithType(VTK_VERTEX);
//Definition of Pickable and Highlitable engines
//----------------------------------------------
@@ -393,7 +433,8 @@ SMESH_ActorDef::~SMESH_ActorDef()
myPreselectProp->Delete();
myNodeProp->Delete();
-
+ myNodeExtProp->Delete();
+
my1DProp->Delete();
my1DActor->Delete();
@@ -401,11 +442,15 @@ SMESH_ActorDef::~SMESH_ActorDef()
my1DExtActor->Delete();
my2DActor->Delete();
+ my2DExtProp->Delete();
+ my2DExtActor->Delete();
my3DActor->Delete();
myNodeActor->Delete();
myBaseActor->Delete();
+ myNodeExtActor->Delete();
+
myHighlitableActor->Delete();
//Deleting of pints numbering pipeline
@@ -581,6 +626,14 @@ SetControlMode(eControl theMode,
aFunctor.reset(new SMESH::Controls::FreeEdges());
myControlActor = my2DActor;
break;
+ case eFreeNodes:
+ aFunctor.reset(new SMESH::Controls::FreeNodes());
+ myControlActor = myNodeActor;
+ break;
+ case eFreeFaces:
+ aFunctor.reset(new SMESH::Controls::FreeFaces());
+ myControlActor = my2DActor;
+ break;
case eMultiConnection:
aFunctor.reset(new SMESH::Controls::MultiConnection());
myControlActor = my1DActor;
@@ -662,10 +715,16 @@ SetControlMode(eControl theMode,
if(aNbCells){
myControlMode = theMode;
switch(myControlMode){
+ case eFreeNodes:
+ myNodeExtActor->SetExtControlMode(aFunctor);
+ break;
case eFreeEdges:
case eFreeBorders:
my1DExtActor->SetExtControlMode(aFunctor);
break;
+ case eFreeFaces:
+ my2DExtActor->SetExtControlMode(aFunctor);
+ break;
case eLength2D:
case eMultiConnection2D:
my1DExtActor->SetExtControlMode(aFunctor,myScalarBarActor,myLookupTable);
@@ -682,6 +741,7 @@ SetControlMode(eControl theMode,
switch(myControlMode){
case eLength2D:
case eFreeEdges:
+ case eFreeFaces:
case eMultiConnection2D:
//SetEntityMode(eEdges);
SetEntityMode(eFaces);
@@ -709,15 +769,18 @@ void SMESH_ActorDef::AddToRender(vtkRenderer* theRenderer){
theRenderer->AddActor(myNodeActor);
theRenderer->AddActor(myBaseActor);
+
+ theRenderer->AddActor(myNodeExtActor);
my3DActor->AddToRender(theRenderer);
my2DActor->AddToRender(theRenderer);
+ my2DExtActor->AddToRender(theRenderer);
theRenderer->AddActor(my1DActor);
theRenderer->AddActor(my1DExtActor);
theRenderer->AddActor(myHighlitableActor);
-
+
theRenderer->AddActor2D(myScalarBarActor);
myPtsSelectVisiblePoints->SetRenderer(theRenderer);
@@ -733,12 +796,15 @@ void SMESH_ActorDef::RemoveFromRender(vtkRenderer* theRenderer){
theRenderer->RemoveActor(myNodeActor);
theRenderer->RemoveActor(myBaseActor);
+ theRenderer->RemoveActor(myNodeExtActor);
+
theRenderer->RemoveActor(myHighlitableActor);
theRenderer->RemoveActor(my1DActor);
theRenderer->RemoveActor(my1DExtActor);
my2DActor->RemoveFromRender(theRenderer);
+ my2DExtActor->RemoveFromRender(theRenderer);
my3DActor->RemoveFromRender(theRenderer);
theRenderer->RemoveActor(myScalarBarActor);
@@ -761,24 +827,29 @@ bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj,
myNodeActor->Init(myVisualObj,myImplicitBoolean);
myBaseActor->Init(myVisualObj,myImplicitBoolean);
-
+
myHighlitableActor->Init(myVisualObj,myImplicitBoolean);
+
+ myNodeExtActor->Init(myVisualObj,myImplicitBoolean);
my1DActor->Init(myVisualObj,myImplicitBoolean);
my1DExtActor->Init(myVisualObj,myImplicitBoolean);
my2DActor->Init(myVisualObj,myImplicitBoolean);
+ my2DExtActor->Init(myVisualObj,myImplicitBoolean);
my3DActor->Init(myVisualObj,myImplicitBoolean);
my1DActor->GetMapper()->SetLookupTable(myLookupTable);
my1DExtActor->GetMapper()->SetLookupTable(myLookupTable);
my2DActor->GetMapper()->SetLookupTable(myLookupTable);
+ my2DExtActor->GetMapper()->SetLookupTable(myLookupTable);
my3DActor->GetMapper()->SetLookupTable(myLookupTable);
vtkFloatingPointType aFactor, aUnits;
my2DActor->GetPolygonOffsetParameters(aFactor,aUnits);
my2DActor->SetPolygonOffsetParameters(aFactor,aUnits*0.75);
+ my2DExtActor->SetPolygonOffsetParameters(aFactor,aUnits*0.5);
SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
if( !mgr )
@@ -825,13 +896,16 @@ void SMESH_ActorDef::SetTransform(VTKViewer_Transform* theTransform){
myNodeActor->SetTransform(theTransform);
myBaseActor->SetTransform(theTransform);
-
+
myHighlitableActor->SetTransform(theTransform);
+ myNodeExtActor->SetTransform(theTransform);
+
my1DActor->SetTransform(theTransform);
my1DExtActor->SetTransform(theTransform);
my2DActor->SetTransform(theTransform);
+ my2DExtActor->SetTransform(theTransform);
my3DActor->SetTransform(theTransform);
Modified();
@@ -886,6 +960,7 @@ void SMESH_ActorDef::SetShrinkFactor(vtkFloatingPointType theValue){
my1DExtActor->SetShrinkFactor(theValue);
my2DActor->SetShrinkFactor(theValue);
+ my2DExtActor->SetShrinkFactor(theValue);
my3DActor->SetShrinkFactor(theValue);
Modified();
@@ -900,6 +975,7 @@ void SMESH_ActorDef::SetShrink(){
my1DExtActor->SetShrink();
my2DActor->SetShrink();
+ my2DExtActor->SetShrink();
my3DActor->SetShrink();
myIsShrunk = true;
@@ -915,6 +991,7 @@ void SMESH_ActorDef::UnShrink(){
my1DExtActor->UnShrink();
my2DActor->UnShrink();
+ my2DExtActor->UnShrink();
my3DActor->UnShrink();
myIsShrunk = false;
@@ -951,10 +1028,13 @@ void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation){
myNodeActor->VisibilityOff();
myBaseActor->VisibilityOff();
+ myNodeExtActor->VisibilityOff();
+
my1DActor->VisibilityOff();
my1DExtActor->VisibilityOff();
my2DActor->VisibilityOff();
+ my2DExtActor->VisibilityOff();
my3DActor->VisibilityOff();
myScalarBarActor->VisibilityOff();
@@ -964,13 +1044,19 @@ void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation){
if(GetVisibility()){
if(theIsUpdateRepersentation)
SetRepresentation(GetRepresentation());
-
+
if(myControlMode != eNone){
switch(myControlMode){
+ case eFreeNodes:
+ myNodeExtActor->VisibilityOn();
+ break;
case eFreeEdges:
case eFreeBorders:
my1DExtActor->VisibilityOn();
break;
+ case eFreeFaces:
+ my2DExtActor->VisibilityOn();
+ break;
case eLength2D:
case eMultiConnection2D:
my1DExtActor->VisibilityOn();
@@ -1117,6 +1203,7 @@ void SMESH_ActorDef::SetRepresentation(int theMode){
myPickableActor = myBaseActor;
myNodeActor->SetVisibility(false);
+ myNodeExtActor->SetVisibility(false);
vtkProperty *aProp = NULL, *aBackProp = NULL;
SMESH_DeviceActor::EReperesent aReperesent = SMESH_DeviceActor::EReperesent(-1);
switch(myRepresentation){
@@ -1141,12 +1228,15 @@ void SMESH_ActorDef::SetRepresentation(int theMode){
my2DActor->SetProperty(aProp);
my2DActor->SetBackfaceProperty(aBackProp);
my2DActor->SetRepresentation(aReperesent);
+
+ my2DExtActor->SetRepresentation(aReperesent);
my3DActor->SetProperty(aProp);
my3DActor->SetBackfaceProperty(aBackProp);
my3DActor->SetRepresentation(aReperesent);
my1DExtActor->SetVisibility(false);
+ my2DExtActor->SetVisibility(false);
switch(myControlMode){
case eLength:
@@ -1331,6 +1421,7 @@ void SMESH_ActorDef::SetSufaceColor(vtkFloatingPointType r,vtkFloatingPointType
void SMESH_ActorDef::GetSufaceColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b){
::GetColor(mySurfaceProp,r,g,b);
+ my2DExtProp->SetColor(1.0-r,1.0-g,1.0-b);
}
void SMESH_ActorDef::SetBackSufaceColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b){
@@ -1355,6 +1446,7 @@ void SMESH_ActorDef::GetEdgeColor(vtkFloatingPointType& r,vtkFloatingPointType&
void SMESH_ActorDef::SetNodeColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b){
myNodeProp->SetColor(r,g,b);
+ myNodeExtProp->SetColor(1.0-r,1.0-g,1.0-b);
Modified();
}
@@ -1398,6 +1490,7 @@ void SMESH_ActorDef::SetLineWidth(vtkFloatingPointType theVal){
void SMESH_ActorDef::SetNodeSize(vtkFloatingPointType theVal){
myNodeProp->SetPointSize(theVal);
+ myNodeExtProp->SetPointSize(theVal);
myHighlightProp->SetPointSize(theVal);
myPreselectProp->SetPointSize(theVal);
@@ -1431,11 +1524,14 @@ SetImplicitFunctionUsed(bool theIsImplicitFunctionUsed)
myBaseActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
myHighlitableActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
+
+ myNodeExtActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
my1DActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
my1DExtActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
my2DActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
+ my2DExtActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
my3DActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
}
@@ -1597,7 +1693,7 @@ void SMESH_ActorDef::UpdateScalarBar()
else
aScalarBarTitleProp->ItalicOff();
- if ( f.underline() )
+ if ( f.overline() )
aScalarBarTitleProp->ShadowOn();
else
aScalarBarTitleProp->ShadowOff();
@@ -1632,7 +1728,7 @@ void SMESH_ActorDef::UpdateScalarBar()
else
aScalarBarLabelProp->ItalicOff();
- if( f.underline() )
+ if( f.overline() )
aScalarBarLabelProp->ShadowOn();
else
aScalarBarLabelProp->ShadowOff();
diff --git a/src/OBJECT/SMESH_Actor.h b/src/OBJECT/SMESH_Actor.h
index 94a9e0408..df02e86e4 100644
--- a/src/OBJECT/SMESH_Actor.h
+++ b/src/OBJECT/SMESH_Actor.h
@@ -23,8 +23,7 @@
// File : SMESH_Actor.h
// Author : Nicolas REJNERI
// Module : SMESH
-// $Header$
-//
+
#ifndef SMESH_ACTOR_H
#define SMESH_ACTOR_H
@@ -95,9 +94,9 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
virtual void SetFacesOriented(bool theIsFacesOriented) = 0;
virtual bool GetFacesOriented() = 0;
- enum eControl{eNone, eLength, eLength2D, eFreeBorders, eFreeEdges, eMultiConnection,
- eArea, eTaper, eAspectRatio, eMinimumAngle, eWarping, eSkew,
- eAspectRatio3D, eMultiConnection2D, eVolume3D};
+ enum eControl{eNone, eLength, eLength2D, eFreeBorders, eFreeEdges, eFreeNodes,
+ eFreeFaces, eMultiConnection, eArea, eTaper, eAspectRatio,
+ eMinimumAngle, eWarping, eSkew, eAspectRatio3D, eMultiConnection2D, eVolume3D};
virtual void SetControlMode(eControl theMode) = 0;
virtual eControl GetControlMode() = 0;
diff --git a/src/OBJECT/SMESH_ActorDef.h b/src/OBJECT/SMESH_ActorDef.h
index d1e43ff23..619f0096a 100644
--- a/src/OBJECT/SMESH_ActorDef.h
+++ b/src/OBJECT/SMESH_ActorDef.h
@@ -23,8 +23,8 @@
// File : SMESH_ActorDef.h
// Author : Nicolas REJNERI
// Module : SMESH
-// $Header$
//
+
#ifndef SMESH_ACTORDEF_H
#define SMESH_ACTORDEF_H
@@ -215,10 +215,15 @@ class SMESH_ActorDef : public SMESH_Actor
SMESH_DeviceActor* myHighlitableActor;
eControl myControlMode;
+ vtkProperty* my2DExtProp;
SMESH_DeviceActor* my2DActor;
+ SMESH_DeviceActor* my2DExtActor;
SMESH_DeviceActor* my3DActor;
SMESH_DeviceActor* myControlActor;
+ vtkProperty* myNodeExtProp;
+ SMESH_DeviceActor* myNodeExtActor;
+
vtkProperty* my1DProp;
SMESH_DeviceActor* my1DActor;
vtkProperty* my1DExtProp;
diff --git a/src/OBJECT/SMESH_DeviceActor.cxx b/src/OBJECT/SMESH_DeviceActor.cxx
index 64a1a15fb..c24f10bfc 100644
--- a/src/OBJECT/SMESH_DeviceActor.cxx
+++ b/src/OBJECT/SMESH_DeviceActor.cxx
@@ -23,8 +23,8 @@
// File : SMESH_DeviceActor.cxx
// Author :
// Module : SMESH
-// $Header$
//
+
#include "SMESH_DeviceActor.h"
#include "SMESH_ExtractGeometry.h"
#include "SMESH_ControlsDef.hxx"
@@ -483,13 +483,15 @@ SMESH_DeviceActor
myVisualObj->UpdateFunctor(theFunctor);
using namespace SMESH::Controls;
- if(FreeBorders* aFreeBorders = dynamic_cast(theFunctor.get())){
+ if ( dynamic_cast(theFunctor.get()) ||
+ dynamic_cast(theFunctor.get()) ) {
+ Predicate* aFreePredicate = dynamic_cast(theFunctor.get());
myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
vtkIdType aNbCells = aGrid->GetNumberOfCells();
for( vtkIdType i = 0; i < aNbCells; i++ ){
vtkIdType anObjId = myVisualObj->GetElemObjId(i);
- if(aFreeBorders->IsSatisfy(anObjId))
+ if(aFreePredicate->IsSatisfy(anObjId))
myExtractUnstructuredGrid->RegisterCell(i);
}
if(!myExtractUnstructuredGrid->IsCellsRegistered())
@@ -542,6 +544,18 @@ SMESH_DeviceActor
SetUnstructuredGrid(aDataSet);
aDataSet->Delete();
+ }else if(FreeNodes* aFreeNodes = dynamic_cast(theFunctor.get())){
+ myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
+ vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
+ vtkIdType aNbCells = aGrid->GetNumberOfCells();
+ for( vtkIdType i = 0; i < aNbCells; i++ ){
+ vtkIdType anObjId = myVisualObj->GetNodeObjId(i);
+ if(aFreeNodes->IsSatisfy(anObjId))
+ myExtractUnstructuredGrid->RegisterCell(i);
+ }
+ if(!myExtractUnstructuredGrid->IsCellsRegistered())
+ myExtractUnstructuredGrid->RegisterCell(-1);
+ SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid());
}
}
diff --git a/src/SMDS/SMDSAbs_ElementType.hxx b/src/SMDS/SMDSAbs_ElementType.hxx
index 314c7895e..a76772e3f 100644
--- a/src/SMDS/SMDSAbs_ElementType.hxx
+++ b/src/SMDS/SMDSAbs_ElementType.hxx
@@ -39,6 +39,26 @@ enum SMDSAbs_ElementType
SMDSAbs_NbElementTypes
};
+/*! enumeration for element geometry type */
+enum SMDSAbs_GeometryType
+{
+ // 0D element
+ SMDSGeom_POINT,
+ // 1D element
+ SMDSGeom_EDGE,
+ // 2D element
+ SMDSGeom_TRIANGLE,
+ SMDSGeom_QUADRANGLE,
+ SMDSGeom_POLYGON,
+ // 3D element
+ SMDSGeom_TETRA,
+ SMDSGeom_PYRAMID,
+ SMDSGeom_PENTA,
+ SMDSGeom_HEXA,
+ SMDSGeom_POLYHEDRA,
+};
+
+
enum SMDSAbs_ElementOrder {
ORDER_ANY, /*! entities of any order */
ORDER_LINEAR, /*! entities of 1st order */
diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx
index b22ef6343..b68acbe1c 100644
--- a/src/SMESH/SMESH_Algo.cxx
+++ b/src/SMESH/SMESH_Algo.cxx
@@ -23,8 +23,8 @@
// File : SMESH_Algo.cxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-// $Header$
//
+
#include "SMESH_Algo.hxx"
#include "SMESH_Comment.hxx"
#include "SMESH_Gen.hxx"
@@ -285,12 +285,7 @@ bool SMESH_Algo::IsReversedSubMesh (const TopoDS_Face& theFace,
//================================================================================
/*!
- * \brief Initialize my parameter values by the mesh built on the geometry
- * \param theMesh - the built mesh
- * \param theShape - the geometry of interest
- * \retval bool - true if parameter values have been successfully defined
- *
- * Just return false as the algorithm does not hold parameters values
+ * \brief Just return false as the algorithm does not hold parameters values
*/
//================================================================================
@@ -299,7 +294,10 @@ bool SMESH_Algo::SetParametersByMesh(const SMESH_Mesh* /*theMesh*/,
{
return false;
}
-
+bool SMESH_Algo::SetParametersByElementSize(double, const SMESH_Mesh*)
+{
+ return false;
+}
//================================================================================
/*!
* \brief Fill vector of node parameters on geometrical edge, including vertex nodes
@@ -359,6 +357,70 @@ bool SMESH_Algo::GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh,
return theParams.size() > 1;
}
+//================================================================================
+/*!
+ * \brief Fill vector of node parameters on geometrical edge, including vertex nodes
+ * \param theMesh - The mesh containing nodes
+ * \param theEdge - The geometrical edge of interest
+ * \param theParams - The resulting vector of sorted node parameters
+ * \retval bool - false if not all parameters are OK
+ */
+//================================================================================
+
+bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh* theMesh,
+ const TopoDS_Edge& theEdge,
+ const bool ignoreMediumNodes,
+ map< double, const SMDS_MeshNode* > & theNodes)
+{
+ theNodes.clear();
+
+ if ( !theMesh || theEdge.IsNull() )
+ return false;
+
+ SMESHDS_SubMesh * eSubMesh = theMesh->MeshElements( theEdge );
+ if ( !eSubMesh || !eSubMesh->GetElements()->more() )
+ return false; // edge is not meshed
+
+ int nbNodes = 0;
+ set < double > paramSet;
+ if ( eSubMesh )
+ {
+ // loop on nodes of an edge: sort them by param on edge
+ SMDS_NodeIteratorPtr nIt = eSubMesh->GetNodes();
+ while ( nIt->more() )
+ {
+ const SMDS_MeshNode* node = nIt->next();
+ if ( ignoreMediumNodes ) {
+ SMDS_ElemIteratorPtr elemIt = node->GetInverseElementIterator();
+ if ( elemIt->more() && elemIt->next()->IsMediumNode( node ))
+ continue;
+ }
+ const SMDS_PositionPtr& pos = node->GetPosition();
+ if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE )
+ return false;
+ const SMDS_EdgePosition* epos =
+ static_cast(node->GetPosition().get());
+ theNodes.insert( make_pair( epos->GetUParameter(), node ));
+ ++nbNodes;
+ }
+ }
+ // add vertex nodes
+ TopoDS_Vertex v1, v2;
+ TopExp::Vertices(theEdge, v1, v2);
+ const SMDS_MeshNode* n1 = VertexNode( v1, (SMESHDS_Mesh*) theMesh );
+ const SMDS_MeshNode* n2 = VertexNode( v2, (SMESHDS_Mesh*) theMesh );
+ Standard_Real f, l;
+ BRep_Tool::Range(theEdge, f, l);
+ if ( v1.Orientation() != TopAbs_FORWARD )
+ std::swap( f, l );
+ if ( n1 && ++nbNodes )
+ theNodes.insert( make_pair( f, n1 ));
+ if ( n2 && ++nbNodes )
+ theNodes.insert( make_pair( l, n2 ));
+
+ return theNodes.size() == nbNodes;
+}
+
//================================================================================
/*!
* \brief Make filter recognize only compatible hypotheses
diff --git a/src/SMESH/SMESH_Algo.hxx b/src/SMESH/SMESH_Algo.hxx
index 0e2ab7c22..806b3d0f2 100644
--- a/src/SMESH/SMESH_Algo.hxx
+++ b/src/SMESH/SMESH_Algo.hxx
@@ -23,8 +23,8 @@
// File : SMESH_Algo.hxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-// $Header$
//
+
#ifndef _SMESH_ALGO_HXX_
#define _SMESH_ALGO_HXX_
@@ -41,6 +41,7 @@
#include
#include
#include
+#include
class SMESH_Gen;
class SMESH_Mesh;
@@ -162,12 +163,10 @@ public:
bool InitCompatibleHypoFilter( SMESH_HypoFilter & theFilter,
const bool ignoreAuxiliary) const;
/*!
- * \brief Initialize my parameter values by the mesh built on the geometry
- *
- * Just return false as the algorithm does not hold parameters values
+ * \brief Just return false as the algorithm does not hold parameters values
*/
- virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh,
- const TopoDS_Shape& theShape);
+ virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
+ virtual bool SetParametersByElementSize(double elemLenght, const SMESH_Mesh* theMesh=0);
/*!
* \brief return compute error
*/
@@ -241,6 +240,18 @@ public:
static bool GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh,
const TopoDS_Edge& theEdge,
std::vector< double > & theParams);
+ /*!
+ * \brief Fill map of node parameter on geometrical edge to node it-self
+ * \param theMesh - The mesh containing nodes
+ * \param theEdge - The geometrical edge of interest
+ * \param theNodes - The resulting map
+ * \param ignoreMediumNodes - to store medium nodes of quadratic elements or not
+ * \retval bool - false if not all parameters are OK
+ */
+ static bool GetSortedNodesOnEdge(const SMESHDS_Mesh* theMesh,
+ const TopoDS_Edge& theEdge,
+ const bool ignoreMediumNodes,
+ std::map< double, const SMDS_MeshNode* > & theNodes);
/*!
* \brief Find out elements orientation on a geometrical face
* \param theFace - The face correctly oriented in the shape being meshed
diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx
index f065be2c0..955e1335d 100644
--- a/src/SMESH/SMESH_Gen.cxx
+++ b/src/SMESH/SMESH_Gen.cxx
@@ -23,8 +23,7 @@
// File : SMESH_Gen.cxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-// $Header$
-//
+
#include "SMESH_Gen.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_HypoFilter.hxx"
@@ -54,6 +53,7 @@ SMESH_Gen::SMESH_Gen()
MESSAGE("SMESH_Gen::SMESH_Gen");
_localId = 0;
_hypId = 0;
+ _segmentation = 10;
}
//=============================================================================
@@ -128,9 +128,11 @@ SMESH_Mesh* SMESH_Gen::CreateMesh(int theStudyId, bool theIsEmbeddedMode)
*/
//=============================================================================
-bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
- const TopoDS_Shape & aShape,
- const bool anUpward)
+bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape,
+ const bool anUpward,
+ const ::MeshDimension aDim,
+ TSetOfInt* aShapesId)
{
MESSAGE("SMESH_Gen::Compute");
@@ -154,16 +156,27 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
SMESH_subMesh* smToCompute = smIt->next();
// do not mesh vertices of a pseudo shape
- if ( !aMesh.HasShapeToMesh() &&
- smToCompute->GetSubShape().ShapeType() == TopAbs_VERTEX )
+ const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType();
+ if ( !aMesh.HasShapeToMesh() && aShType == TopAbs_VERTEX )
continue;
+ // check for preview dimension limitations
+ if ( aShapesId && GetShapeDim( aShType ) > (int)aDim )
+ {
+ // clear compute state to not show previous compute errors
+ // if preview invoked less dimension less than previous
+ smToCompute->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ continue;
+ }
+
if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
// we check all the submeshes here and detect if any of them failed to compute
if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
ret = false;
+ else if ( aShapesId )
+ aShapesId->insert( smToCompute->GetId() );
}
return ret;
}
@@ -183,7 +196,12 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
continue;
const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
- if ( GetShapeDim( aSubShape ) < 1 ) break;
+ const int aShapeDim = GetShapeDim( aSubShape );
+ if ( aShapeDim < 1 ) break;
+
+ // check for preview dimension limitations
+ if ( aShapesId && aShapeDim > (int)aDim )
+ continue;
SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
if ( algo && !algo->NeedDescretBoundary() )
@@ -191,7 +209,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
if ( algo->SupportSubmeshes() )
smWithAlgoSupportingSubmeshes.push_back( smToCompute );
else
+ {
smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+ if ( aShapesId )
+ aShapesId->insert( smToCompute->GetId() );
+ }
}
}
// ------------------------------------------------------------
@@ -218,8 +240,14 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
SMESH_subMesh* smToCompute = smIt->next();
const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
- if ( aSubShape.ShapeType() == TopAbs_VERTEX ) continue;
+ const int aShapeDim = GetShapeDim( aSubShape );
+ //if ( aSubShape.ShapeType() == TopAbs_VERTEX ) continue;
+ if ( aShapeDim < 1 ) continue;
+ // check for preview dimension limitations
+ if ( aShapesId && GetShapeDim( aSubShape.ShapeType() ) > (int)aDim )
+ continue;
+
SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
filter
.And( SMESH_HypoFilter::IsApplicableTo( aSubShape ))
@@ -228,8 +256,8 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) {
SMESH_Hypothesis::Hypothesis_Status status;
if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
- // mesh a lower smToCompute
- Compute( aMesh, aSubShape );
+ // mesh a lower smToCompute starting from vertices
+ Compute( aMesh, aSubShape, /*anUpward=*/true, aDim, aShapesId );
}
}
}
@@ -238,12 +266,21 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
// ----------------------------------------------------------
for ( subIt = smWithAlgoSupportingSubmeshes.rbegin(); subIt != subEnd; ++subIt )
if ( sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
+ {
+ const TopAbs_ShapeEnum aShType = sm->GetSubShape().ShapeType();
+ // check for preview dimension limitations
+ if ( aShapesId && GetShapeDim( aShType ) > (int)aDim )
+ continue;
+
sm->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+ if ( aShapesId )
+ aShapesId->insert( sm->GetId() );
+ }
// -----------------------------------------------
// mesh the rest subshapes starting from vertices
// -----------------------------------------------
- ret = Compute( aMesh, aShape, /*anUpward=*/true );
+ ret = Compute( aMesh, aShape, /*anUpward=*/true, aDim, aShapesId );
}
MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret);
@@ -665,35 +702,35 @@ StudyContextStruct *SMESH_Gen::GetStudyContext(int studyId)
return myStudyContext;
}
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
+// //=============================================================================
+// /*!
+// *
+// */
+// //=============================================================================
-void SMESH_Gen::Save(int studyId, const char *aUrlOfFile)
-{
-}
+// void SMESH_Gen::Save(int studyId, const char *aUrlOfFile)
+// {
+// }
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
+// //=============================================================================
+// /*!
+// *
+// */
+// //=============================================================================
-void SMESH_Gen::Load(int studyId, const char *aUrlOfFile)
-{
-}
+// void SMESH_Gen::Load(int studyId, const char *aUrlOfFile)
+// {
+// }
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
+// //=============================================================================
+// /*!
+// *
+// */
+// //=============================================================================
-void SMESH_Gen::Close(int studyId)
-{
-}
+// void SMESH_Gen::Close(int studyId)
+// {
+// }
//=============================================================================
/*!
@@ -707,14 +744,14 @@ int SMESH_Gen::GetShapeDim(const TopAbs_ShapeEnum & aShapeType)
if ( dim.empty() )
{
dim.resize( TopAbs_SHAPE, -1 );
- dim[ TopAbs_COMPOUND ] = 3;
- dim[ TopAbs_COMPSOLID ] = 3;
- dim[ TopAbs_SOLID ] = 3;
- dim[ TopAbs_SHELL ] = 3;
- dim[ TopAbs_FACE ] = 2;
- dim[ TopAbs_WIRE ] = 1;
- dim[ TopAbs_EDGE ] = 1;
- dim[ TopAbs_VERTEX ] = 0;
+ dim[ TopAbs_COMPOUND ] = MeshDim_3D;
+ dim[ TopAbs_COMPSOLID ] = MeshDim_3D;
+ dim[ TopAbs_SOLID ] = MeshDim_3D;
+ dim[ TopAbs_SHELL ] = MeshDim_3D;
+ dim[ TopAbs_FACE ] = MeshDim_2D;
+ dim[ TopAbs_WIRE ] = MeshDim_1D;
+ dim[ TopAbs_EDGE ] = MeshDim_1D;
+ dim[ TopAbs_VERTEX ] = MeshDim_0D;
}
return dim[ aShapeType ];
}
diff --git a/src/SMESH/SMESH_Gen.hxx b/src/SMESH/SMESH_Gen.hxx
index 9d1b40561..855138ee8 100644
--- a/src/SMESH/SMESH_Gen.hxx
+++ b/src/SMESH/SMESH_Gen.hxx
@@ -23,8 +23,8 @@
// File : SMESH_Gen.hxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-// $Header$
//
+
#ifndef _SMESH_GEN_HXX_
#define _SMESH_GEN_HXX_
@@ -44,6 +44,7 @@
#include
#include
+#include
class SMESHDS_Document;
@@ -56,6 +57,8 @@ typedef struct studyContextStruct
SMESHDS_Document * myDocument;
} StudyContextStruct;
+typedef std::set TSetOfInt;
+
class SMESH_EXPORT SMESH_Gen
{
public:
@@ -68,16 +71,26 @@ class SMESH_EXPORT SMESH_Gen
/*!
* \brief Computes aMesh on aShape
* \param anUpward - compute from vertices up to more complex shape (internal usage)
+ * \param aDim - upper level dimension of the mesh computation
+ * \param aShapesId - list of shapes with computed mesh entities (elements or nodes)
* \retval bool - true if none submesh failed to compute
*/
- bool Compute(::SMESH_Mesh & aMesh,
- const TopoDS_Shape & aShape,
- const bool anUpward=false);
+ bool Compute(::SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape,
+ const bool anUpward=false,
+ const ::MeshDimension aDim=::MeshDim_3D,
+ TSetOfInt* aShapesId=0);
bool CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
// notify on bad state of attached algos, return false
// if Compute() would fail because of some algo bad state
+ /*!
+ * \brief Sets number of segments per diagonal of boundary box of geometry by which
+ * default segment length of appropriate 1D hypotheses is defined
+ */
+ void SetBoundaryBoxSegmentation( int theNbSegments ) { _segmentation = theNbSegments; }
+ int GetBoundaryBoxSegmentation() const { return _segmentation; }
struct TAlgoStateError
{
@@ -109,13 +122,13 @@ class SMESH_EXPORT SMESH_Gen
// inherited methods from SALOMEDS::Driver
- void Save(int studyId, const char *aUrlOfFile);
- void Load(int studyId, const char *aUrlOfFile);
- void Close(int studyId);
- const char *ComponentDataType();
+// void Save(int studyId, const char *aUrlOfFile);
+// void Load(int studyId, const char *aUrlOfFile);
+// void Close(int studyId);
+// const char *ComponentDataType();
- const char *IORToLocalPersistentID(const char *IORString, bool & IsAFile);
- const char *LocalPersistentIDToIOR(const char *aLocalPersistentID);
+// const char *IORToLocalPersistentID(const char *IORString, bool & IsAFile);
+// const char *LocalPersistentIDToIOR(const char *aLocalPersistentID);
int GetANewId();
@@ -132,6 +145,10 @@ class SMESH_EXPORT SMESH_Gen
// hypotheses managing
int _hypId;
+
+ // number of segments per diagonal of boundary box of geometry by which
+ // default segment length of appropriate 1D hypotheses is defined
+ int _segmentation;
};
#endif
diff --git a/src/SMESH/SMESH_Hypothesis.hxx b/src/SMESH/SMESH_Hypothesis.hxx
index 355f166a4..366ffeab1 100644
--- a/src/SMESH/SMESH_Hypothesis.hxx
+++ b/src/SMESH/SMESH_Hypothesis.hxx
@@ -23,8 +23,8 @@
// File : SMESH_Hypothesis.hxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-// $Header$
//
+
#ifndef _SMESH_HYPOTHESIS_HXX_
#define _SMESH_HYPOTHESIS_HXX_
@@ -36,6 +36,14 @@ class SMESH_Gen;
class TopoDS_Shape;
class SMESH_Mesh;
+enum MeshDimension // dimension of mesh
+{
+ MeshDim_0D = 0,
+ MeshDim_1D,
+ MeshDim_2D,
+ MeshDim_3D
+};
+
class SMESH_EXPORT SMESH_Hypothesis: public SMESHDS_Hypothesis
{
public:
@@ -71,12 +79,18 @@ public:
/*!
* \brief Initialize my parameter values by the mesh built on the geometry
- * \param theMesh - the built mesh
- * \param theShape - the geometry of interest
- * \retval bool - true if parameter values have been successfully defined
+ * \param theMesh - the built mesh
+ * \param theShape - the geometry of interest
+ * \retval bool - true if parameter values have been successfully defined
*/
virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape)=0;
+ /*!
+ * \brief Initialize my parameter values by linear size of mesh element.
+ * \retval bool - true if parameter values have been successfully defined
+ */
+ virtual bool SetParametersByElementSize(double elemLenght, const SMESH_Mesh* theMesh=0)=0;
+
/*!
* \brief Return true if me is an auxiliary hypothesis
* \retval bool - auxiliary or not
diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx
index 4479c7de8..5f29eb32c 100644
--- a/src/SMESH/SMESH_Mesh.cxx
+++ b/src/SMESH/SMESH_Mesh.cxx
@@ -23,7 +23,6 @@
// File : SMESH_Mesh.cxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-// $Header$
//
#include "SMESH_Mesh.hxx"
#include "SMESH_subMesh.hxx"
@@ -50,7 +49,9 @@
#include "DriverSTL_R_SMDS_Mesh.h"
#undef _Precision_HeaderFile
+#include
#include
+#include
#include
#include
#include
@@ -95,6 +96,7 @@ SMESH_Mesh::SMESH_Mesh(int theLocalId,
_myMeshDS = theDocument->GetMesh(_idDoc);
_isShapeToMesh = false;
_isAutoColor = false;
+ _shapeDiagonal = 0.0;
_myMeshDS->ShapeToMesh( PseudoShape() );
}
@@ -155,6 +157,8 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
// clear SMESHDS
TopoDS_Shape aNullShape;
_myMeshDS->ShapeToMesh( aNullShape );
+
+ _shapeDiagonal = 0.0;
}
// set a new geometry
@@ -202,6 +206,33 @@ const TopoDS_Solid& SMESH_Mesh::PseudoShape()
return aSolid;
}
+//=======================================================================
+/*!
+ * \brief Return diagonal size of bounding box of a shape
+ */
+//=======================================================================
+
+double SMESH_Mesh::GetShapeDiagonalSize(const TopoDS_Shape & aShape)
+{
+ Bnd_Box Box;
+ BRepBndLib::Add(aShape, Box);
+ return sqrt( Box.SquareExtent() );
+}
+
+//=======================================================================
+/*!
+ * \brief Return diagonal size of bounding box of shape to mesh
+ */
+//=======================================================================
+
+double SMESH_Mesh::GetShapeDiagonalSize() const
+{
+ if ( _shapeDiagonal == 0. && _isShapeToMesh )
+ const_cast(this)->_shapeDiagonal = GetShapeDiagonalSize( GetShapeToMesh() );
+
+ return _shapeDiagonal;
+}
+
//=======================================================================
/*!
* \brief Remove all nodes and elements
@@ -265,6 +296,32 @@ void SMESH_Mesh::Clear()
// }
}
+//=======================================================================
+/*!
+ * \brief Remove all nodes and elements of indicated shape
+ */
+//=======================================================================
+
+void SMESH_Mesh::ClearSubMesh(const int theShapeId)
+{
+ // clear sub-meshes; get ready to re-compute as a side-effect
+ if ( SMESH_subMesh *sm = GetSubMeshContaining( theShapeId ) )
+ {
+ SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
+ /*complexShapeFirst=*/false);
+ while ( smIt->more() )
+ {
+ sm = smIt->next();
+ TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType();
+ if ( shapeType == TopAbs_VERTEX || shapeType < TopAbs_SOLID )
+ // all other shapes depends on vertices so they are already cleaned
+ sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
+ // to recompute even if failed
+ sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ }
+ }
+}
+
//=======================================================================
//function : UNVToMesh
//purpose :
@@ -1453,3 +1510,41 @@ SMDSAbs_ElementType SMESH_Mesh::GetElementType( const int id, const bool iselem
{
return _myMeshDS->GetElementType( id, iselem );
}
+
+//=============================================================================
+/*!
+ * \brief Convert group on geometry into standalone group
+ */
+//=============================================================================
+
+SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID )
+{
+ SMESH_Group* aGroup = 0;
+ std::map < int, SMESH_Group * >::iterator itg = _mapGroup.find( theGroupID );
+ if ( itg == _mapGroup.end() )
+ return aGroup;
+
+ SMESH_Group* anOldGrp = (*itg).second;
+ SMESHDS_GroupBase* anOldGrpDS = anOldGrp->GetGroupDS();
+ if ( !anOldGrp || !anOldGrpDS )
+ return aGroup;
+
+ // create new standalone group
+ aGroup = new SMESH_Group (theGroupID, this, anOldGrpDS->GetType(), anOldGrp->GetName() );
+ _mapGroup[theGroupID] = aGroup;
+
+ SMESHDS_Group* aNewGrpDS = dynamic_cast( aGroup->GetGroupDS() );
+ GetMeshDS()->RemoveGroup( anOldGrpDS );
+ GetMeshDS()->AddGroup( aNewGrpDS );
+
+ // add elements (or nodes) into new created group
+ SMDS_ElemIteratorPtr anItr = anOldGrpDS->GetElements();
+ while ( anItr->more() )
+ aNewGrpDS->Add( (anItr->next())->GetID() );
+
+ // remove old group
+ delete anOldGrp;
+
+ return aGroup;
+}
+
diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx
index 2d2808a37..91ae67eda 100644
--- a/src/SMESH/SMESH_Mesh.hxx
+++ b/src/SMESH/SMESH_Mesh.hxx
@@ -23,7 +23,6 @@
// File : SMESH_Mesh.hxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-// $Header$
//
#ifndef _SMESH_MESH_HXX_
#define _SMESH_MESH_HXX_
@@ -75,6 +74,14 @@ public:
* \brief Return true if there is a geometry to be meshed, not PseudoShape()
*/
bool HasShapeToMesh() const { return _isShapeToMesh; }
+ /*!
+ * \brief Return diagonal size of bounding box of shape to mesh.
+ */
+ double GetShapeDiagonalSize() const;
+ /*!
+ * \brief Return diagonal size of bounding box of a shape.
+ */
+ static double GetShapeDiagonalSize(const TopoDS_Shape & aShape);
/*!
* \brief Return a solid which is returned by GetShapeToMesh() if
* a real geometry to be meshed was not set
@@ -86,6 +93,11 @@ public:
*/
void Clear();
+ /*!
+ * \brief Remove all nodes and elements of indicated shape
+ */
+ void ClearSubMesh(const int theShapeId);
+
int UNVToMesh(const char* theFileName);
/*!
* consult DriverMED_R_SMESHDS_Mesh::ReadStatus for returned value
@@ -230,6 +242,7 @@ public:
void RemoveGroup (const int theGroupID);
+ SMESH_Group* ConvertToStandalone ( int theGroupID );
SMDSAbs_ElementType GetElementType( const int id, const bool iselem );
@@ -253,6 +266,8 @@ protected:
SMESH_Gen * _gen;
bool _isAutoColor;
+
+ double _shapeDiagonal; //!< diagonal size of bounding box of shape to mesh
TopTools_IndexedDataMapOfShapeListOfShape _mapAncestors;
diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx
index 487646ed9..063f68819 100644
--- a/src/SMESH/SMESH_MeshEditor.cxx
+++ b/src/SMESH/SMESH_MeshEditor.cxx
@@ -90,22 +90,6 @@ struct TNodeXYZ : public gp_XYZ {
TNodeXYZ( const SMDS_MeshNode* n ):gp_XYZ( n->X(), n->Y(), n->Z() ) {}
};
-typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink;
-
-//=======================================================================
-/*!
- * \brief A sorted pair of nodes
- */
-//=======================================================================
-
-struct TLink: public NLink
-{
- TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 )
- { if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); }
- TLink(const NLink& link ):NLink( link )
- { if ( first->GetID() < second->GetID() ) std::swap( first, second ); }
-};
-
//=======================================================================
//function : SMESH_MeshEditor
//purpose :
@@ -1479,10 +1463,10 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
// 1. map of elements with their linkIDs
// 2. map of linkIDs with their elements
- map< TLink, list< const SMDS_MeshElement* > > mapLi_listEl;
- map< TLink, list< const SMDS_MeshElement* > >::iterator itLE;
- map< const SMDS_MeshElement*, set< TLink > > mapEl_setLi;
- map< const SMDS_MeshElement*, set< TLink > >::iterator itEL;
+ map< SMESH_TLink, list< const SMDS_MeshElement* > > mapLi_listEl;
+ map< SMESH_TLink, list< const SMDS_MeshElement* > >::iterator itLE;
+ map< const SMDS_MeshElement*, set< SMESH_TLink > > mapEl_setLi;
+ map< const SMDS_MeshElement*, set< SMESH_TLink > >::iterator itEL;
TIDSortedElemSet::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
@@ -1501,7 +1485,7 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
// fill maps
for ( i = 0; i < 3; i++ ) {
- TLink link( aNodes[i], aNodes[i+1] );
+ SMESH_TLink link( aNodes[i], aNodes[i+1] );
// check if elements sharing a link can be fused
itLE = mapLi_listEl.find( link );
if ( itLE != mapLi_listEl.end() ) {
@@ -1527,7 +1511,7 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
int nbElems = (*itLE).second.size();
if ( nbElems < 2 ) {
const SMDS_MeshElement* elem = (*itLE).second.front();
- TLink link = (*itLE).first;
+ SMESH_TLink link = (*itLE).first;
mapEl_setLi[ elem ].erase( link );
if ( mapEl_setLi[ elem ].empty() )
mapEl_setLi.erase( elem );
@@ -1553,11 +1537,11 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
// search elements to fuse starting from startElem or links of elements
// fused earlyer - startLinks
- list< TLink > startLinks;
+ list< SMESH_TLink > startLinks;
while ( startElem || !startLinks.empty() ) {
while ( !startElem && !startLinks.empty() ) {
// Get an element to start, by a link
- TLink linkId = startLinks.front();
+ SMESH_TLink linkId = startLinks.front();
startLinks.pop_front();
itLE = mapLi_listEl.find( linkId );
if ( itLE != mapLi_listEl.end() ) {
@@ -1573,15 +1557,15 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
if ( startElem ) {
// Get candidates to be fused
const SMDS_MeshElement *tr1 = startElem, *tr2 = 0, *tr3 = 0;
- const TLink *link12, *link13;
+ const SMESH_TLink *link12, *link13;
startElem = 0;
ASSERT( mapEl_setLi.find( tr1 ) != mapEl_setLi.end() );
- set< TLink >& setLi = mapEl_setLi[ tr1 ];
+ set< SMESH_TLink >& setLi = mapEl_setLi[ tr1 ];
ASSERT( !setLi.empty() );
- set< TLink >::iterator itLi;
+ set< SMESH_TLink >::iterator itLi;
for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ )
{
- const TLink & link = (*itLi);
+ const SMESH_TLink & link = (*itLi);
itLE = mapLi_listEl.find( link );
if ( itLE == mapLi_listEl.end() )
continue;
@@ -1602,10 +1586,10 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems,
}
// add other links of elem to list of links to re-start from
- set< TLink >& links = mapEl_setLi[ elem ];
- set< TLink >::iterator it;
+ set< SMESH_TLink >& links = mapEl_setLi[ elem ];
+ set< SMESH_TLink >::iterator it;
for ( it = links.begin(); it != links.end(); it++ ) {
- const TLink& link2 = (*it);
+ const SMESH_TLink& link2 = (*it);
if ( link2 != link )
startLinks.push_back( link2 );
}
@@ -2462,9 +2446,8 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems,
// fix nodes on mesh boundary
if ( checkBoundaryNodes ) {
- typedef pair TLink;
- map< TLink, int > linkNbMap; // how many times a link encounters in elemsOnFace
- map< TLink, int >::iterator link_nb;
+ map< NLink, int > linkNbMap; // how many times a link encounters in elemsOnFace
+ map< NLink, int >::iterator link_nb;
// put all elements links to linkNbMap
list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
for ( ; elemIt != elemsOnFace.end(); ++elemIt ) {
@@ -2476,7 +2459,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems,
const SMDS_MeshNode* curNode, *prevNode = elem->GetNode( nbn );
for ( int iN = 0; iN < nbn; ++iN ) {
curNode = elem->GetNode( iN );
- TLink link;
+ NLink link;
if ( curNode < prevNode ) link = make_pair( curNode , prevNode );
else link = make_pair( prevNode , curNode );
prevNode = curNode;
@@ -7547,8 +7530,8 @@ SMESH_MeshEditor::FindMatchingNodes(set& theSide1,
if ( theSecondNode1 != theSecondNode2 )
nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 ));
- set< TLink > linkSet; // set of nodes where order of nodes is ignored
- linkSet.insert( TLink( theFirstNode1, theSecondNode1 ));
+ set< SMESH_TLink > linkSet; // set of nodes where order of nodes is ignored
+ linkSet.insert( SMESH_TLink( theFirstNode1, theSecondNode1 ));
list< NLink > linkList[2];
linkList[0].push_back( NLink( theFirstNode1, theSecondNode1 ));
@@ -7663,8 +7646,8 @@ SMESH_MeshEditor::FindMatchingNodes(set& theSide1,
for ( int i = 0; i < nbN; i++ )
{
const SMDS_MeshNode* n2 = f0->GetNode( i );
- pair< set< TLink >::iterator, bool > iter_isnew =
- linkSet.insert( TLink( n1, n2 ));
+ pair< set< SMESH_TLink >::iterator, bool > iter_isnew =
+ linkSet.insert( SMESH_TLink( n1, n2 ));
if ( !iter_isnew.second ) { // already in a set: no need to process
linkSet.erase( iter_isnew.first );
}
@@ -7684,3 +7667,92 @@ SMESH_MeshEditor::FindMatchingNodes(set& theSide1,
return SEW_OK;
}
+
+/*!
+ \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+ \param theNodes - identifiers of nodes to be doubled
+ \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
+ nodes. If list of element identifiers is empty then nodes are doubled but
+ they not assigned to elements
+ \return TRUE if operation has been completed successfully, FALSE otherwise
+*/
+bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes,
+ const std::list< int >& theListOfModifiedElems )
+{
+ myLastCreatedElems.Clear();
+ myLastCreatedNodes.Clear();
+
+ if ( theListOfNodes.size() == 0 )
+ return false;
+
+ SMESHDS_Mesh* aMeshDS = GetMeshDS();
+ if ( !aMeshDS )
+ return false;
+
+ // iterate through nodes and duplicate them
+
+ std::map< const SMDS_MeshNode*, const SMDS_MeshNode* > anOldNodeToNewNode;
+
+ std::list< int >::const_iterator aNodeIter;
+ for ( aNodeIter = theListOfNodes.begin(); aNodeIter != theListOfNodes.end(); ++aNodeIter )
+ {
+ int aCurr = *aNodeIter;
+ SMDS_MeshNode* aNode = (SMDS_MeshNode*)aMeshDS->FindNode( aCurr );
+ if ( !aNode )
+ continue;
+
+ // duplicate node
+
+ const SMDS_MeshNode* aNewNode = aMeshDS->AddNode( aNode->X(), aNode->Y(), aNode->Z() );
+ if ( aNewNode )
+ {
+ anOldNodeToNewNode[ aNode ] = aNewNode;
+ myLastCreatedNodes.Append( aNewNode );
+ }
+ }
+
+ // Create map of new nodes for modified elements
+
+ std::map< SMDS_MeshElement*, vector > anElemToNodes;
+
+ std::list< int >::const_iterator anElemIter;
+ for ( anElemIter = theListOfModifiedElems.begin();
+ anElemIter != theListOfModifiedElems.end(); ++anElemIter )
+ {
+ int aCurr = *anElemIter;
+ SMDS_MeshElement* anElem = (SMDS_MeshElement*)aMeshDS->FindElement( aCurr );
+ if ( !anElem )
+ continue;
+
+ vector aNodeArr( anElem->NbNodes() );
+
+ SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
+ int ind = 0;
+ while ( anIter->more() )
+ {
+ SMDS_MeshNode* aCurrNode = (SMDS_MeshNode*)anIter->next();
+ if ( aCurr && anOldNodeToNewNode.find( aCurrNode ) != anOldNodeToNewNode.end() )
+ {
+ const SMDS_MeshNode* aNewNode = anOldNodeToNewNode[ aCurrNode ];
+ aNodeArr[ ind++ ] = aNewNode;
+ }
+ else
+ aNodeArr[ ind++ ] = aCurrNode;
+ }
+ anElemToNodes[ anElem ] = aNodeArr;
+ }
+
+ // Change nodes of elements
+
+ std::map< SMDS_MeshElement*, vector >::iterator
+ anElemToNodesIter = anElemToNodes.begin();
+ for ( ; anElemToNodesIter != anElemToNodes.end(); ++anElemToNodesIter )
+ {
+ const SMDS_MeshElement* anElem = anElemToNodesIter->first;
+ vector aNodeArr = anElemToNodesIter->second;
+ if ( anElem )
+ aMeshDS->ChangeElementNodes( anElem, &aNodeArr[ 0 ], anElem->NbNodes() );
+ }
+
+ return true;
+}
diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx
index 6e9819e27..ccab3fbb6 100644
--- a/src/SMESH/SMESH_MeshEditor.hxx
+++ b/src/SMESH/SMESH_MeshEditor.hxx
@@ -47,6 +47,24 @@ typedef std::map > TElemOfElemListMap;
typedef std::map TNodeNodeMap;
+
+typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink;
+
+//=======================================================================
+/*!
+ * \brief A sorted pair of nodes
+ */
+//=======================================================================
+
+struct SMESH_TLink: public NLink
+{
+ SMESH_TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 )
+ { if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); }
+ SMESH_TLink(const NLink& link ):NLink( link )
+ { if ( first->GetID() < second->GetID() ) std::swap( first, second ); }
+};
+
+
class SMDS_MeshFace;
class SMDS_MeshNode;
class gp_Ax1;
@@ -509,6 +527,9 @@ public:
const SMESH_SequenceOfElemPtr& GetLastCreatedNodes() const { return myLastCreatedNodes; }
const SMESH_SequenceOfElemPtr& GetLastCreatedElems() const { return myLastCreatedElems; }
+
+ bool DoubleNodes( const std::list< int >& theListOfNodes,
+ const std::list< int >& theListOfModifiedElems );
private:
diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx
index 6b962be03..c8189a49a 100644
--- a/src/SMESHGUI/SMESHGUI.cxx
+++ b/src/SMESHGUI/SMESHGUI.cxx
@@ -771,6 +771,10 @@
aTitle = QObject::tr( "MULTI_BORDERS" );
aControl = SMESH_Actor::eMultiConnection;
break;
+ case 6005:
+ aTitle = QObject::tr( "FREE_NODES" );
+ aControl = SMESH_Actor::eFreeNodes;
+ break;
case 6019:
aTitle = QObject::tr( "MULTI2D_BORDERS" );
aControl = SMESH_Actor::eMultiConnection2D;
@@ -807,6 +811,10 @@
aTitle = QObject::tr( "SMESH_VOLUME" );
aControl = SMESH_Actor::eVolume3D;
break;
+ case 6021:
+ aTitle = QObject::tr( "FREE_FACES" );
+ aControl = SMESH_Actor::eFreeFaces;
+ break;
}
anActor->SetControlMode(aControl);
anActor->GetScalarBarActor()->SetTitle(aTitle.toLatin1().data());
@@ -1061,6 +1069,11 @@ SalomeApp_Module( "SMESH" )
{
CORBA::Boolean anIsEmbeddedMode;
myComponentSMESH = SMESH_Client::GetSMESHGen(getApp()->orb(),anIsEmbeddedMode);
+
+ // 0019923: EDF 765 SMESH : default values of hypothesis
+ SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr(this);
+ int nbSeg = aResourceMgr->integerValue( "SMESH", "segmentation" );
+ myComponentSMESH->SetBoundaryBoxSegmentation( nbSeg );
}
myActiveDialogBox = 0;
@@ -1564,21 +1577,17 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
}
case 701: // COMPUTE MESH
+ case 711: // PRECOMPUTE MESH
{
if (checkLock(aStudy)) break;
-
- startOperation( 701 );
+ startOperation( theCommandID );
}
break;
- case 702: // Create mesh
- startOperation( 702 );
- break;
- case 703: // Create sub-mesh
- startOperation( 703 );
- break;
+ case 702: // Create mesh
+ case 703: // Create sub-mesh
case 704: // Edit mesh/sub-mesh
- startOperation( 704 );
+ startOperation( theCommandID );
break;
case 710: // Build compound mesh
{
@@ -1880,6 +1889,36 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
break;
}
+ case 815: // Edit GEOM GROUP as standalone
+ {
+ if ( !vtkwnd )
+ {
+ SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ),
+ tr( "NOT_A_VTK_VIEWER" ) );
+ break;
+ }
+
+ if(checkLock(aStudy)) break;
+ EmitSignalDeactivateDialog();
+
+ LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+ SALOME_ListIO selected;
+ if( aSel )
+ aSel->selectedObjects( selected );
+
+ SALOME_ListIteratorOfListIO It (selected);
+ for ( ; It.More(); It.Next() )
+ {
+ SMESH::SMESH_GroupOnGeom_var aGroup =
+ SMESH::IObjectToInterface(It.Value());
+ if (!aGroup->_is_nil()) {
+ SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, aGroup, true );
+ aDlg->show();
+ }
+ }
+ break;
+ }
+
case 810: // Union Groups
case 811: // Intersect groups
case 812: // Cut groups
@@ -1896,12 +1935,28 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
EmitSignalDeactivateDialog();
- int aMode;
- if ( theCommandID == 810 ) aMode = SMESHGUI_GroupOpDlg::UNION;
- else if ( theCommandID == 811 ) aMode = SMESHGUI_GroupOpDlg::INTERSECT;
- else aMode = SMESHGUI_GroupOpDlg::CUT;
+ SMESHGUI_GroupOpDlg* aDlg = 0;
+ if ( theCommandID == 810 )
+ aDlg = new SMESHGUI_UnionGroupsDlg( this );
+ else if ( theCommandID == 811 )
+ aDlg = new SMESHGUI_IntersectGroupsDlg( this );
+ else
+ aDlg = new SMESHGUI_CutGroupsDlg( this );
+
+ aDlg->show();
+
+ break;
+ }
+
+ case 814: // Create groups of entities from existing groups of superior dimensions
+ {
+ if ( checkLock( aStudy ) )
+ break;
+
+ EmitSignalDeactivateDialog();
+ SMESHGUI_GroupOpDlg* aDlg = new SMESHGUI_DimGroupDlg( this );
+ aDlg->show();
- ( new SMESHGUI_GroupOpDlg( this, aMode ) )->show();
break;
}
@@ -2022,7 +2077,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
if( aSel )
aSel->selectedObjects( selected );
- bool isAny = false; // iss there any appropriate object selected
+ bool isAny = false; // is there any appropriate object selected
SALOME_ListIteratorOfListIO It( selected );
for ( ; It.More(); It.Next() )
@@ -2050,14 +2105,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
newName = LightApp_NameDlg::getName(desktop(), newName);
if ( !newName.isEmpty() )
{
- //old source: aStudy->renameIObject( IObject, newName );
- aName->SetValue( newName.toLatin1().constData() );
-
- // if current object is group update group's name
- SMESH::SMESH_GroupBase_var aGroup =
- SMESH::IObjectToInterface(IObject);
- if (!aGroup->_is_nil() )
- aGroup->SetName( newName.toLatin1().constData() );
+ SMESHGUI::GetSMESHGen()->SetName(obj->GetIOR().c_str(), newName.toLatin1().data());
updateObjBrowser();
}
@@ -2390,7 +2438,9 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
case 6002:
case 6003:
case 6004:
+ case 6005:
case 6009:
+ case 6021:
if ( vtkwnd ) {
LightApp_SelectionMgr* mgr = selectionMgr();
@@ -2596,23 +2646,28 @@ void SMESHGUI::initialize( CAM_Application* app )
createSMESHAction( 703, "CREATE_SUBMESH", "ICON_DLG_ADD_SUBMESH" );
createSMESHAction( 704, "EDIT_MESHSUBMESH","ICON_DLG_EDIT_MESH" );
createSMESHAction( 710, "BUILD_COMPOUND", "ICON_BUILD_COMPOUND" );
+ createSMESHAction( 711, "PRECOMPUTE", "ICON_PRECOMPUTE" );
createSMESHAction( 806, "CREATE_GEO_GROUP","ICON_CREATE_GEO_GROUP" );
createSMESHAction( 801, "CREATE_GROUP", "ICON_CREATE_GROUP" );
createSMESHAction( 802, "CONSTRUCT_GROUP", "ICON_CONSTRUCT_GROUP" );
createSMESHAction( 803, "EDIT_GROUP", "ICON_EDIT_GROUP" );
+ createSMESHAction( 815, "EDIT_GEOMGROUP_AS_GROUP", "ICON_EDIT_GROUP" );
createSMESHAction( 804, "ADD" );
createSMESHAction( 805, "REMOVE" );
createSMESHAction( 810, "UN_GROUP", "ICON_UNION" );
createSMESHAction( 811, "INT_GROUP", "ICON_INTERSECT" );
createSMESHAction( 812, "CUT_GROUP", "ICON_CUT" );
+ createSMESHAction( 814, "UNDERLYING_ELEMS","ICON_UNDERLYING_ELEMS" );
createSMESHAction( 813, "DEL_GROUP", "ICON_DEL_GROUP" );
createSMESHAction( 900, "ADV_INFO", "ICON_ADV_INFO" );
createSMESHAction( 902, "STD_INFO", "ICON_STD_INFO" );
createSMESHAction( 903, "WHAT_IS", "ICON_WHAT_IS" );
createSMESHAction( 6001, "LENGTH", "ICON_LENGTH", 0, true );
createSMESHAction( 6002, "FREE_EDGE", "ICON_FREE_EDGE", 0, true );
+ createSMESHAction( 6021, "FREE_FACES", "ICON_FREE_FACES", 0, true );
createSMESHAction( 6003, "FREE_BORDER", "ICON_FREE_EDGE_2D", 0, true );
createSMESHAction( 6004, "CONNECTION", "ICON_CONNECTION", 0, true );
+ createSMESHAction( 6005, "FREE_NODE", "ICON_FREE_NODE", 0, true );
createSMESHAction( 6011, "AREA", "ICON_AREA", 0, true );
createSMESHAction( 6012, "TAPER", "ICON_TAPER", 0, true );
createSMESHAction( 6013, "ASPECT", "ICON_ASPECT", 0, true );
@@ -2731,16 +2786,20 @@ void SMESHGUI::initialize( CAM_Application* app )
createMenu( 710, meshId, -1 );
createMenu( separator(), meshId, -1 );
createMenu( 701, meshId, -1 );
+ createMenu( 711, meshId, -1 );
createMenu( separator(), meshId, -1 );
createMenu( 801, meshId, -1 );
createMenu( 806, meshId, -1 );
createMenu( 802, meshId, -1 );
createMenu( 803, meshId, -1 );
+ createMenu( 815, meshId, -1 );
createMenu( separator(), meshId, -1 );
createMenu( 810, meshId, -1 );
createMenu( 811, meshId, -1 );
createMenu( 812, meshId, -1 );
createMenu( separator(), meshId, -1 );
+ createMenu( 814, meshId, -1 );
+ createMenu( separator(), meshId, -1 );
createMenu( 813, meshId, -1 );
createMenu( separator(), meshId, -1 );
createMenu( 900, meshId, -1 );
@@ -2752,6 +2811,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createMenu( 6001, ctrlId, -1 );
createMenu( 6004, ctrlId, -1 );
createMenu( separator(), ctrlId, -1 );
+ createMenu( 6005, ctrlId, -1 );
createMenu( 6002, ctrlId, -1 );
createMenu( 6018, ctrlId, -1 );
createMenu( 6019, ctrlId, -1 );
@@ -2764,6 +2824,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createMenu( separator(), ctrlId, -1 );
createMenu( 6017, ctrlId, -1 );
createMenu( 6009, ctrlId, -1 );
+ createMenu( 6021, ctrlId, -1 );
createMenu( separator(), ctrlId, -1 );
createMenu( 400, addId, -1 );
@@ -2826,11 +2887,13 @@ void SMESHGUI::initialize( CAM_Application* app )
createTool( 710, meshTb );
createTool( separator(), meshTb );
createTool( 701, meshTb );
+ createTool( 711, meshTb );
createTool( separator(), meshTb );
createTool( 801, meshTb );
createTool( 806, meshTb );
createTool( 802, meshTb );
createTool( 803, meshTb );
+ //createTool( 815, meshTb );
createTool( separator(), meshTb );
createTool( 900, meshTb );
createTool( 902, meshTb );
@@ -2841,6 +2904,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createTool( 6003, ctrlTb );
createTool( 6004, ctrlTb );
createTool( separator(), ctrlTb );
+ createTool( 6005, ctrlTb );
createTool( 6002, ctrlTb );
createTool( 6018, ctrlTb );
createTool( 6019, ctrlTb );
@@ -2853,6 +2917,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createTool( separator(), ctrlTb );
createTool( 6017, ctrlTb );
createTool( 6009, ctrlTb );
+ createTool( 6021, ctrlTb );
createTool( separator(), ctrlTb );
createTool( 400, addRemTb );
@@ -2929,12 +2994,15 @@ void SMESHGUI::initialize( CAM_Application* app )
createPopupItem( 150, OB, mesh, "&& selcount=1 && isImported" ); // FILE INFORMATION
createPopupItem( 703, OB, mesh, "&& isComputable"); // CREATE_SUBMESH
- createPopupItem( 703, OB, subMesh, "&& isComputable" ); // CREATE_SUBMESH
+ //createPopupItem( 703, OB, subMesh, "&& isComputable" ); // CREATE_SUBMESH
createPopupItem( 704, OB, mesh, "&& isComputable"); // EDIT_MESHSUBMESH
createPopupItem( 704, OB, subMesh, "&& isComputable" ); // EDIT_MESHSUBMESH
createPopupItem( 803, OB, group ); // EDIT_GROUP
+ createPopupItem( 815, OB, group, "&& groupType = 'GroupOnGeom'" ); // EDIT_GROUP
+
popupMgr()->insert( separator(), -1, 0 );
createPopupItem( 701, OB, mesh, "&& isComputable" ); // COMPUTE
+ createPopupItem( 711, OB, mesh, "&& isComputable" ); // PRECOMPUTE
createPopupItem( 214, OB, mesh_group ); // UPDATE
createPopupItem( 900, OB, mesh_group ); // ADV_INFO
createPopupItem( 902, OB, mesh ); // STD_INFO
@@ -2964,6 +3032,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createPopupItem( 803, View, group ); // EDIT_GROUP
createPopupItem( 804, View, elems ); // ADD
createPopupItem( 805, View, elems ); // REMOVE
+
popupMgr()->insert( separator(), -1, 0 );
createPopupItem( 214, View, mesh_group ); // UPDATE
createPopupItem( 900, View, mesh_group ); // ADV_INFO
@@ -3091,6 +3160,7 @@ void SMESHGUI::initialize( CAM_Application* app )
// Controls
//-------------------------------------------------
QString
+ aMeshInVtkHasNodes = aMeshInVTK + "&&" + hasNodes,
aMeshInVtkHasEdges = aMeshInVTK + "&&" + hasEdges,
aMeshInVtkHasFaces = aMeshInVTK + "&&" + hasFaces,
aMeshInVtkHasVolumes = aMeshInVTK + "&&" + hasVolumes;
@@ -3116,8 +3186,12 @@ void SMESHGUI::initialize( CAM_Application* app )
popupMgr()->insert( separator(), anId, -1 );
+ popupMgr()->insert( action( 6005 ), anId, -1 ); // FREE_NODE
+ popupMgr()->setRule( action( 6005 ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( 6005 ), "controlMode = 'eFreeNodes'", QtxPopupMgr::ToggleRule );
+
popupMgr()->insert( action( 6002 ), anId, -1 ); // FREE_EDGE
- popupMgr()->setRule( action( 6002 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( 6002 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
popupMgr()->setRule( action( 6002 ), "controlMode = 'eFreeEdges'", QtxPopupMgr::ToggleRule );
popupMgr()->insert( action( 6018 ), anId, -1 ); // LENGTH_2D
@@ -3162,6 +3236,11 @@ void SMESHGUI::initialize( CAM_Application* app )
popupMgr()->setRule( action( 6009 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
popupMgr()->setRule( action( 6009 ), "controlMode = 'eVolume3D'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert( action( 6021 ), anId, -1 ); // FREE_FACE
+ popupMgr()->setRule( action( 6021 ), aMeshInVtkHasFaces /*aMeshInVtkHasVolumes*/,
+ QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( 6021 ), "controlMode = 'eFreeFaces'", QtxPopupMgr::ToggleRule );
+
popupMgr()->insert( separator(), anId, -1 );
popupMgr()->insert( action( 201 ), anId, -1 ); // SCALAR_BAR_PROP
@@ -3330,6 +3409,7 @@ void SMESHGUI::onViewManagerActivated( SUIT_ViewManager* mgr )
void SMESHGUI::createPreferences()
{
+ // General tab ------------------------------------------------------------------------
int genTab = addPreference( tr( "PREF_TAB_GENERAL" ) );
int updateGroup = addPreference( tr( "PREF_GROUP_UPDATE" ), genTab );
@@ -3378,6 +3458,14 @@ void SMESHGUI::createPreferences()
setPreferenceProperty( notifyMode, "strings", modes );
setPreferenceProperty( notifyMode, "indexes", indices );
+ int segGroup = addPreference( tr( "PREF_GROUP_SEGMENT_LENGTH" ), genTab );
+ setPreferenceProperty( segGroup, "columns", 2 );
+ int segLen = addPreference( tr( "PREF_SEGMENT_LENGTH" ), segGroup, LightApp_Preferences::IntSpin,
+ "SMESH", "segmentation" );
+ setPreferenceProperty( segLen, "min", 1 );
+ setPreferenceProperty( segLen, "max", 10000000 );
+
+ // Mesh tab ------------------------------------------------------------------------
int meshTab = addPreference( tr( "PREF_TAB_MESH" ) );
int nodeGroup = addPreference( tr( "PREF_GROUP_NODES" ), meshTab );
setPreferenceProperty( nodeGroup, "columns", 2 );
@@ -3420,6 +3508,7 @@ void SMESHGUI::createPreferences()
addPreference( tr( "PREF_ORIENTATION_3D_VECTORS" ), orientGroup, LightApp_Preferences::Bool, "SMESH", "orientation_3d_vectors" );
+ // Selection tab ------------------------------------------------------------------------
int selTab = addPreference( tr( "PREF_TAB_SELECTION" ) );
int selGroup = addPreference( tr( "PREF_GROUP_SELECTION" ), selTab );
@@ -3448,28 +3537,17 @@ void SMESHGUI::createPreferences()
addPreference( tr( "PREF_ELEMENTS" ), precSelGroup, LightApp_Preferences::Double, "SMESH", "selection_precision_element" );
addPreference( tr( "PREF_OBJECTS" ), precSelGroup, LightApp_Preferences::Double, "SMESH", "selection_precision_object" );
+ // Scalar Bar tab ------------------------------------------------------------------------
int sbarTab = addPreference( tr( "SMESH_SCALARBAR" ) );
int fontGr = addPreference( tr( "SMESH_FONT_SCALARBAR" ), sbarTab );
setPreferenceProperty( fontGr, "columns", 2 );
- int tfont = addPreference( tr( "SMESH_TITLE" ), fontGr, LightApp_Preferences::Font, "SMESH", "scalar_bar_title_font" );
+ addVtkFontPref( tr( "SMESH_TITLE" ), fontGr, "scalar_bar_title_font" );
addPreference( tr( "PREF_TITLE_COLOR" ), fontGr, LightApp_Preferences::Color, "SMESH", "scalar_bar_title_color" );
- int lfont = addPreference( tr( "SMESH_LABELS" ), fontGr, LightApp_Preferences::Font, "SMESH", "scalar_bar_label_font" );
+
+ addVtkFontPref( tr( "SMESH_LABELS" ), fontGr, "scalar_bar_label_font" );
addPreference( tr( "PREF_LABELS_COLOR" ), fontGr, LightApp_Preferences::Color, "SMESH", "scalar_bar_label_color" );
- QStringList fam;
- fam.append( tr( "SMESH_FONT_ARIAL" ) );
- fam.append( tr( "SMESH_FONT_COURIER" ) );
- fam.append( tr( "SMESH_FONT_TIMES" ) );
- int wflag = ( QtxFontEdit::Family | QtxFontEdit::Scripting );
-
- setPreferenceProperty( tfont, "families", fam );
- setPreferenceProperty( tfont, "system", false );
- setPreferenceProperty( tfont, "widget_flags", wflag );
- setPreferenceProperty( lfont, "families", fam );
- setPreferenceProperty( lfont, "system", false );
- setPreferenceProperty( lfont, "widget_flags", wflag );
-
int colorsLabelsGr = addPreference( tr( "SMESH_LABELS_COLORS_SCALARBAR" ), sbarTab );
setPreferenceProperty( colorsLabelsGr, "columns", 2 );
@@ -3535,7 +3613,7 @@ void SMESHGUI::createPreferences()
void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
{
- if( sect=="SMESH" ){
+ if( sect=="SMESH" ) {
float sbX1,sbY1,sbW,sbH;
float aTol = 1.00000009999999;
std::string aWarning;
@@ -3551,7 +3629,7 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
if(sbX1+sbW > aTol){
aWarning = "Origin and Size Vertical: X+Width > 1\n";
sbX1=0.01;
- sbW=0.05;
+ sbW=0.08;
aResourceMgr->setValue("SMESH", "scalar_bar_vertical_x", sbX1);
aResourceMgr->setValue("SMESH", "scalar_bar_vertical_width", sbW);
}
@@ -3570,8 +3648,8 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
sbW = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_width", sbW);
if(sbX1+sbW > aTol){
aWarning = "Origin and Size Horizontal: X+Width > 1\n";
- sbX1=0.01;
- sbW=0.05;
+ sbX1=0.1;
+ sbW=0.08;
aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_x", sbX1);
aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_width", sbW);
}
@@ -3582,11 +3660,15 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
if(sbY1+sbH > aTol){
aWarning = "Origin and Size Horizontal: Y+Height > 1\n";
sbY1=0.01;
- sbH=0.05;
+ sbH=0.08;
aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_y", sbY1);
aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_height",sbH);
}
}
+ else if ( name == "segmentation" ) {
+ int nbSeg = aResourceMgr->integerValue( "SMESH", "segmentation" );
+ myComponentSMESH->SetBoundaryBoxSegmentation( nbSeg );
+ }
if(aWarning.size() != 0){
aWarning += "The default values are applied instead.";
@@ -3672,6 +3754,9 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const
case 704: // Edit mesh/sub-mesh
op = new SMESHGUI_MeshOp( false );
break;
+ case 711: // Precompute mesh
+ op = new SMESHGUI_PrecomputeOp();
+ break;
case 806: // Create group on geom
op = new SMESHGUI_GroupOnShapeOp();
break;
@@ -4175,3 +4260,35 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
}
}
}
+
+/*!
+ \brief Adds preferences for dfont of VTK viewer
+ \param label label
+ \param pIf group identifier
+ \param param parameter
+ \return identifier of preferences
+*/
+int SMESHGUI::addVtkFontPref( const QString& label, const int pId, const QString& param )
+{
+ int tfont = addPreference( label, pId, LightApp_Preferences::Font, "VISU", param );
+
+ setPreferenceProperty( tfont, "mode", QtxFontEdit::Custom );
+
+ QStringList fam;
+ fam.append( tr( "SMESH_FONT_ARIAL" ) );
+ fam.append( tr( "SMESH_FONT_COURIER" ) );
+ fam.append( tr( "SMESH_FONT_TIMES" ) );
+
+ setPreferenceProperty( tfont, "fonts", fam );
+
+ int f = QtxFontEdit::Family | QtxFontEdit::Bold | QtxFontEdit::Italic | QtxFontEdit::Shadow;
+ setPreferenceProperty( tfont, "features", f );
+
+ return tfont;
+}
+
+
+
+
+
+
diff --git a/src/SMESHGUI/SMESHGUI.h b/src/SMESHGUI/SMESHGUI.h
index ae56d0a3c..d8cb5eb97 100644
--- a/src/SMESHGUI/SMESHGUI.h
+++ b/src/SMESHGUI/SMESHGUI.h
@@ -149,6 +149,9 @@ protected:
private:
void OnEditDelete();
+ int addVtkFontPref( const QString& label,
+ const int pId,
+ const QString& param );
private :
static SMESH::SMESH_Gen_var myComponentSMESH;
diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx
index 6c28ac700..9a6f5dbdc 100644
--- a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx
+++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx
@@ -51,8 +51,10 @@
#include
#include
#include
+#include
// SALOME KERNEL includes
+#include
#include
// OCCT includes
@@ -85,10 +87,6 @@
// VTK includes
#include
-// IDL includes
-#include
-#include CORBA_SERVER_HEADER(SMESH_Gen)
-
// STL includes
#include
#include
@@ -791,7 +789,8 @@ void SMESHGUI_MeshInfosBox::SetInfoByMesh(SMESH::SMESH_Mesh_var mesh)
*/
//=======================================================================
-SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg(): SMESHGUI_Dialog( 0, false, true, Close/* | Help*/ )
+SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg( QWidget* parent )
+ : SMESHGUI_Dialog( parent, false, true, Close/* | Help*/ )
{
QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame());
aDlgLay->setMargin( 0 );
@@ -804,6 +803,16 @@ SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg(): SMESHGUI_Dialog( 0, false, true, Clo
aDlgLay->setStretchFactor(aMainFrame, 1);
}
+// =========================================================================================
+/*!
+ * \brief Destructor
+ */
+//=======================================================================
+
+SMESHGUI_ComputeDlg::~SMESHGUI_ComputeDlg()
+{
+}
+
//=======================================================================
// function : createMainFrame()
// purpose : Create frame containing dialog's fields
@@ -921,37 +930,33 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent)
*/
//================================================================================
-SMESHGUI_ComputeOp::SMESHGUI_ComputeOp()
+SMESHGUI_BaseComputeOp::SMESHGUI_BaseComputeOp()
+ : SMESHGUI_Operation(),
+ myCompDlg( 0 )
{
- myDlg = new SMESHGUI_ComputeDlg;
myTShapeDisplayer = new SMESH::TShapeDisplayer();
myBadMeshDisplayer = 0;
//myHelpFileName = "/files/about_meshes.htm"; // V3
myHelpFileName = "about_meshes_page.html"; // V4
-
- // connect signals and slots
- connect(myDlg->myShowBtn, SIGNAL (clicked()), SLOT(onPreviewShape()));
- connect(myDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape()));
- connect(myDlg->myBadMeshBtn, SIGNAL (clicked()), SLOT(onShowBadMesh()));
- connect(table(), SIGNAL(itemSelectionChanged()), SLOT(currentCellChanged()));
- connect(table(), SIGNAL(currentCellChanged(int,int,int,int)), SLOT(currentCellChanged()));
}
-//=======================================================================
-// function : startOperation()
-// purpose : Init dialog fields, connect signals and slots, show dialog
-//=======================================================================
+//================================================================================
+/*!
+ * \brief Start operation
+ * \purpose Init dialog fields, connect signals and slots, show dialog
+ */
+//================================================================================
-void SMESHGUI_ComputeOp::startOperation()
+void SMESHGUI_BaseComputeOp::startOperation()
{
- SMESHGUI_Operation::startOperation();
-
- // check selection
+ // create compute dialog if not created before
+ computeDlg();
myMesh = SMESH::SMESH_Mesh::_nil();
myMainShape = GEOM::GEOM_Object::_nil();
+ // check selection
LightApp_SelectionMgr *Sel = selectionMgr();
SALOME_ListIO selected; Sel->selectedObjects( selected );
@@ -964,16 +969,28 @@ void SMESHGUI_ComputeOp::startOperation()
return;
}
- Handle(SALOME_InteractiveObject) IObject = selected.First();
- myMesh = SMESH::GetMeshByIO(IObject);
+ myIObject = selected.First();
+ myMesh = SMESH::GetMeshByIO(myIObject);
if (myMesh->_is_nil()) {
SUIT_MessageBox::warning(desktop(),
tr("SMESH_WRN_WARNING"),
tr("SMESH_WRN_NO_AVAILABLE_DATA"));
onCancel();
- return;
- }
+ }
+ myMainShape = myMesh->GetShapeToMesh();
+
+ SMESHGUI_Operation::startOperation();
+}
+
+//================================================================================
+/*!
+ * \brief computeMesh()
+*/
+//================================================================================
+
+void SMESHGUI_BaseComputeOp::computeMesh()
+{
// COMPUTE MESH
SMESH::MemoryReserve aMemoryReserve;
@@ -984,12 +1001,11 @@ void SMESHGUI_ComputeOp::startOperation()
bool computeFailed = true, memoryLack = false;
_PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
- myMainShape = myMesh->GetShapeToMesh();
bool hasShape = myMesh->HasShapeToMesh();
bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape;
if ( shapeOK && aMeshSObj )
{
- myDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
+ myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen();
SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape);
if ( errors->length() > 0 ) {
@@ -1032,7 +1048,7 @@ void SMESHGUI_ComputeOp::startOperation()
#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
#endif
- SMESH::Update(IObject, true);
+ SMESH::Update(myIObject, true);
}
catch (...) {
#ifdef _DEBUG_
@@ -1046,77 +1062,119 @@ void SMESHGUI_ComputeOp::startOperation()
}
}
}
- Sel->setSelectedObjects( selected );
+ LightApp_SelectionMgr *Sel = selectionMgr();
+ if ( Sel )
+ {
+ SALOME_ListIO selected;
+ selected.Append( myIObject );
+ Sel->setSelectedObjects( selected );
+ }
}
}
if ( memoryLack )
aMemoryReserve.release();
- myDlg->setWindowTitle(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
- myDlg->myMemoryLackGroup->hide();
+ myCompDlg->setWindowTitle(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
// SHOW ERRORS
-
+
bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
bool noHypoError = ( aHypErrors.isEmpty() );
- if ( memoryLack )
- {
- myDlg->myMemoryLackGroup->show();
- myDlg->myFullInfo->hide();
- myDlg->myBriefInfo->hide();
- myDlg->myHypErrorGroup->hide();
- myDlg->myCompErrorGroup->hide();
+ SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
+ int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
+
+ bool isShowResultDlg = true;
+ switch( aNotifyMode ) {
+ case 0: // show the mesh computation result dialog NEVER
+ isShowResultDlg = false;
+ commit();
+ break;
+ case 1: // show the mesh computation result dialog if there are some errors
+ if ( memoryLack || !noCompError || !noHypoError )
+ isShowResultDlg = true;
+ else
+ {
+ isShowResultDlg = false;
+ commit();
+ }
+ break;
+ default: // show the result dialog after each mesh computation
+ isShowResultDlg = true;
}
- else if ( noCompError && noHypoError )
+
+ // SHOW RESULTS
+ if ( isShowResultDlg )
+ showComputeResult( memoryLack, noCompError,aCompErrors, noHypoError, aHypErrors );
+}
+
+void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack,
+ const bool theNoCompError,
+ SMESH::compute_error_array_var& theCompErrors,
+ const bool theNoHypoError,
+ const QString& theHypErrors )
+{
+ bool hasShape = myMesh->HasShapeToMesh();
+ SMESHGUI_ComputeDlg* aCompDlg = computeDlg();
+ aCompDlg->myMemoryLackGroup->hide();
+
+ if ( theMemoryLack )
{
- myDlg->myFullInfo->SetInfoByMesh( myMesh );
- myDlg->myFullInfo->show();
- myDlg->myBriefInfo->hide();
- myDlg->myHypErrorGroup->hide();
- myDlg->myCompErrorGroup->hide();
+ aCompDlg->myMemoryLackGroup->show();
+ aCompDlg->myFullInfo->hide();
+ aCompDlg->myBriefInfo->hide();
+ aCompDlg->myHypErrorGroup->hide();
+ aCompDlg->myCompErrorGroup->hide();
+ }
+ else if ( theNoCompError && theNoHypoError )
+ {
+ aCompDlg->myFullInfo->SetInfoByMesh( myMesh );
+ aCompDlg->myFullInfo->show();
+ aCompDlg->myBriefInfo->hide();
+ aCompDlg->myHypErrorGroup->hide();
+ aCompDlg->myCompErrorGroup->hide();
}
else
{
- QTableWidget* tbl = myDlg->myTable;
- myDlg->myBriefInfo->SetInfoByMesh( myMesh );
- myDlg->myBriefInfo->show();
- myDlg->myFullInfo->hide();
+ QTableWidget* tbl = aCompDlg->myTable;
+ aCompDlg->myBriefInfo->SetInfoByMesh( myMesh );
+ aCompDlg->myBriefInfo->show();
+ aCompDlg->myFullInfo->hide();
- if ( noHypoError ) {
- myDlg->myHypErrorGroup->hide();
+ if ( theNoHypoError ) {
+ aCompDlg->myHypErrorGroup->hide();
}
else {
- myDlg->myHypErrorGroup->show();
- myDlg->myHypErrorLabel->setText( aHypErrors );
+ aCompDlg->myHypErrorGroup->show();
+ aCompDlg->myHypErrorLabel->setText( theHypErrors );
}
- if ( noCompError ) {
- myDlg->myCompErrorGroup->hide();
+ if ( theNoCompError ) {
+ aCompDlg->myCompErrorGroup->hide();
}
else {
- myDlg->myCompErrorGroup->show();
+ aCompDlg->myCompErrorGroup->show();
if ( !hasShape ) {
- myDlg->myPublishBtn->hide();
- myDlg->myShowBtn->hide();
+ aCompDlg->myPublishBtn->hide();
+ aCompDlg->myShowBtn->hide();
}
else {
- myDlg->myPublishBtn->show();
- myDlg->myShowBtn->show();
+ aCompDlg->myPublishBtn->show();
+ aCompDlg->myShowBtn->show();
}
// fill table of errors
- tbl->setRowCount( aCompErrors->length() );
+ tbl->setRowCount( theCompErrors->length() );
if ( !hasShape ) tbl->hideColumn( COL_SHAPE );
else tbl->showColumn( COL_SHAPE );
tbl->setColumnWidth( COL_ERROR, 200 );
bool hasBadMesh = false;
- for ( int row = 0; row < aCompErrors->length(); ++row )
+ for ( int row = 0; row < theCompErrors->length(); ++row )
{
- SMESH::ComputeError & err = aCompErrors[ row ];
+ SMESH::ComputeError & err = theCompErrors[ row ];
QString text = err.algoName.in();
if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) );
@@ -1150,31 +1208,16 @@ void SMESHGUI_ComputeOp::startOperation()
tbl->resizeColumnToContents( COL_SHAPE );
if ( hasBadMesh )
- myDlg->myBadMeshBtn->show();
+ aCompDlg->myBadMeshBtn->show();
else
- myDlg->myBadMeshBtn->hide();
+ aCompDlg->myBadMeshBtn->hide();
tbl->setCurrentCell(0,0);
currentCellChanged(); // to update buttons
}
}
- SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
- int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
-
- switch( aNotifyMode ) {
- case 0: // show the mesh computation result dialog NEVER
- commit();
- break;
- case 1: // show the mesh computation result dialog if there are some errors
- if ( memoryLack || !noCompError || !noHypoError )
- myDlg->show();
- else
- commit();
- break;
- default: // show the result dialog after each mesh computation
- myDlg->show();
- }
-
+ // show dialog and wait, becase Compute can be invoked from Preview operation
+ aCompDlg->exec();
}
//================================================================================
@@ -1183,10 +1226,11 @@ void SMESHGUI_ComputeOp::startOperation()
*/
//================================================================================
-void SMESHGUI_ComputeOp::stopOperation()
+void SMESHGUI_BaseComputeOp::stopOperation()
{
SMESHGUI_Operation::stopOperation();
- myTShapeDisplayer->SetVisibility( false );
+ if ( myTShapeDisplayer )
+ myTShapeDisplayer->SetVisibility( false );
if ( myBadMeshDisplayer ) {
myBadMeshDisplayer->SetVisibility( false );
// delete it in order not to have problems at its destruction when the viewer
@@ -1194,6 +1238,7 @@ void SMESHGUI_ComputeOp::stopOperation()
delete myBadMeshDisplayer;
myBadMeshDisplayer = 0;
}
+ myIObject.Nullify();
}
//================================================================================
@@ -1202,7 +1247,7 @@ void SMESHGUI_ComputeOp::stopOperation()
*/
//================================================================================
-void SMESHGUI_ComputeOp::onPublishShape()
+void SMESHGUI_BaseComputeOp::onPublishShape()
{
GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
SALOMEDS::Study_var study = SMESHGUI::GetSMESHGen()->GetCurrentStudy();
@@ -1251,7 +1296,7 @@ void SMESHGUI_ComputeOp::onPublishShape()
*/
//================================================================================
-void SMESHGUI_ComputeOp::onShowBadMesh()
+void SMESHGUI_BaseComputeOp::onShowBadMesh()
{
myTShapeDisplayer->SetVisibility( false );
QList rows;
@@ -1284,7 +1329,7 @@ void SMESHGUI_ComputeOp::onShowBadMesh()
*/
//================================================================================
-void SMESHGUI_ComputeOp::currentCellChanged()
+void SMESHGUI_BaseComputeOp::currentCellChanged()
{
myTShapeDisplayer->SetVisibility( false );
if ( myBadMeshDisplayer )
@@ -1314,9 +1359,9 @@ void SMESHGUI_ComputeOp::currentCellChanged()
if ( !table()->item(row, COL_BAD_MESH)->text().isEmpty() )
hasBadMesh = true;
}
- myDlg->myPublishBtn->setEnabled( publishEnable );
- myDlg->myShowBtn ->setEnabled( showEnable );
- myDlg->myBadMeshBtn->setEnabled( hasBadMesh && ( nbSelected == 1 ));
+ myCompDlg->myPublishBtn->setEnabled( publishEnable );
+ myCompDlg->myShowBtn ->setEnabled( showEnable );
+ myCompDlg->myBadMeshBtn->setEnabled( hasBadMesh && ( nbSelected == 1 ));
}
//================================================================================
@@ -1325,7 +1370,7 @@ void SMESHGUI_ComputeOp::currentCellChanged()
*/
//================================================================================
-void SMESHGUI_ComputeOp::onPreviewShape()
+void SMESHGUI_BaseComputeOp::onPreviewShape()
{
if ( myTShapeDisplayer )
{
@@ -1353,8 +1398,10 @@ void SMESHGUI_ComputeOp::onPreviewShape()
*/
//================================================================================
-SMESHGUI_ComputeOp::~SMESHGUI_ComputeOp()
+SMESHGUI_BaseComputeOp::~SMESHGUI_BaseComputeOp()
{
+ delete myCompDlg;
+ myCompDlg = 0;
delete myTShapeDisplayer;
if ( myBadMeshDisplayer )
delete myBadMeshDisplayer;
@@ -1362,14 +1409,73 @@ SMESHGUI_ComputeOp::~SMESHGUI_ComputeOp()
//================================================================================
/*!
- * \brief Gets dialog of this operation
- * \retval LightApp_Dialog* - pointer to dialog of this operation
+ * \brief Gets dialog of compute operation
+ * \retval SMESHGUI_ComputeDlg* - pointer to dialog of this operation
*/
//================================================================================
-LightApp_Dialog* SMESHGUI_ComputeOp::dlg() const
+SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::computeDlg() const
{
- return myDlg;
+ if ( !myCompDlg )
+ {
+ SMESHGUI_BaseComputeOp* me = (SMESHGUI_BaseComputeOp*)this;
+ me->myCompDlg = new SMESHGUI_ComputeDlg( desktop() );
+ // connect signals and slots
+ connect(myCompDlg->myShowBtn, SIGNAL (clicked()), SLOT(onPreviewShape()));
+ connect(myCompDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape()));
+ connect(myCompDlg->myBadMeshBtn, SIGNAL (clicked()), SLOT(onShowBadMesh()));
+
+ QTableWidget* aTable = me->table();
+ connect(aTable, SIGNAL(itemSelectionChanged()), SLOT(currentCellChanged()));
+ connect(aTable, SIGNAL(currentCellChanged(int,int,int,int)), SLOT(currentCellChanged()));
+ }
+ return myCompDlg;
+}
+
+//================================================================================
+/*!
+ * \brief Return a table
+ */
+//================================================================================
+
+QTableWidget* SMESHGUI_BaseComputeOp::table()
+{
+ return myCompDlg->myTable;
+}
+
+
+//================================================================================
+/*!
+ * \brief Constructor
+*/
+//================================================================================
+
+SMESHGUI_ComputeOp::SMESHGUI_ComputeOp()
+ : SMESHGUI_BaseComputeOp()
+{
+}
+
+
+//================================================================================
+/*!
+ * \brief Desctructor
+*/
+//================================================================================
+
+SMESHGUI_ComputeOp::~SMESHGUI_ComputeOp()
+{
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action: compute mesh
+ */
+//================================================================================
+
+void SMESHGUI_ComputeOp::startOperation()
+{
+ SMESHGUI_BaseComputeOp::startOperation();
+ computeMesh();
}
//================================================================================
@@ -1385,11 +1491,422 @@ bool SMESHGUI_ComputeOp::onApply()
//================================================================================
/*!
- * \brief Return a table
+ * \brief Gets dialog of this operation
+ * \retval LightApp_Dialog* - pointer to dialog of this operation
*/
//================================================================================
-QTableWidget* SMESHGUI_ComputeOp::table()
+LightApp_Dialog* SMESHGUI_ComputeOp::dlg() const
{
- return myDlg->myTable;
+ return computeDlg();
+}
+
+//================================================================================
+/*!
+ * \brief Constructor
+*/
+//================================================================================
+
+SMESHGUI_PrecomputeOp::SMESHGUI_PrecomputeOp()
+ : SMESHGUI_BaseComputeOp(),
+ myDlg( 0 ),
+ myActiveDlg( 0 ),
+ myPreviewDisplayer( 0 )
+{
+ myHelpFileName = "preview_meshes_page.html"; // V4
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+SMESHGUI_PrecomputeOp::~SMESHGUI_PrecomputeOp()
+{
+ delete myDlg;
+ myDlg = 0;
+ myActiveDlg = 0;
+ if ( myPreviewDisplayer )
+ delete myPreviewDisplayer;
+ myPreviewDisplayer = 0;
+}
+
+//================================================================================
+/*!
+ * \brief Gets current dialog of this operation
+ * \retval LightApp_Dialog* - pointer to dialog of this operation
+ */
+//================================================================================
+
+LightApp_Dialog* SMESHGUI_PrecomputeOp::dlg() const
+{
+ return myActiveDlg;
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action: prepare data
+ */
+//================================================================================
+
+void SMESHGUI_PrecomputeOp::startOperation()
+{
+ if ( !myDlg )
+ {
+ myDlg = new SMESHGUI_PrecomputeDlg( desktop() );
+
+ // connect signals
+ connect( myDlg, SIGNAL( preview() ), this, SLOT( onPreview() ) );
+ }
+ myActiveDlg = myDlg;
+
+ // connect signal to compute dialog. which will be shown after Compute mesh operation
+ SMESHGUI_ComputeDlg* cmpDlg = computeDlg();
+ if ( cmpDlg )
+ {
+ // disconnect signals
+ disconnect( cmpDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) );
+ disconnect( cmpDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
+ disconnect( cmpDlg, SIGNAL( dlgCancel() ), this, SLOT( onCancel() ) );
+ disconnect( cmpDlg, SIGNAL( dlgClose() ), this, SLOT( onCancel() ) );
+ disconnect( cmpDlg, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) );
+
+ // connect signals
+ if( cmpDlg->testButtonFlags( QtxDialog::OK ) )
+ connect( cmpDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) );
+ if( cmpDlg->testButtonFlags( QtxDialog::Apply ) )
+ connect( cmpDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
+ if( cmpDlg->testButtonFlags( QtxDialog::Help ) )
+ connect( cmpDlg, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) );
+ if( cmpDlg->testButtonFlags( QtxDialog::Cancel ) )
+ connect( cmpDlg, SIGNAL( dlgCancel() ), this, SLOT( onCancel() ) );
+ if( cmpDlg->testButtonFlags( QtxDialog::Close ) )
+ connect( cmpDlg, SIGNAL( dlgClose() ), this, SLOT( onCancel() ) );
+ }
+
+ SMESHGUI_BaseComputeOp::startOperation();
+
+ myDlg->show();
+}
+
+//================================================================================
+/*!
+ * \brief Stops operation
+ */
+//================================================================================
+
+void SMESHGUI_PrecomputeOp::stopOperation()
+{
+ if ( myPreviewDisplayer )
+ {
+ myPreviewDisplayer->SetVisibility( false );
+ delete myPreviewDisplayer;
+ myPreviewDisplayer = 0;
+ }
+ myMapShapeId.clear();
+ SMESHGUI_BaseComputeOp::stopOperation();
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action: reinitialise dialog
+ */
+//================================================================================
+
+void SMESHGUI_PrecomputeOp::resumeOperation()
+{
+ if ( myActiveDlg == myDlg )
+ initDialog();
+ SMESHGUI_BaseComputeOp::resumeOperation();
+}
+
+void SMESHGUI_PrecomputeOp::initDialog()
+{
+ QList modes;
+ QMap modeMap;
+ _PTR(SObject) aHypRoot;
+ _PTR(GenericAttribute) anAttr;
+ int aPart = SMESH::Tag_RefOnAppliedAlgorithms;
+
+ _PTR(SObject) pMesh = studyDS()->FindObjectID( myIObject->getEntry() );
+ if ( pMesh && pMesh->FindSubObject( aPart, aHypRoot ) )
+ {
+ _PTR(ChildIterator) anIter =
+ SMESH::GetActiveStudyDocument()->NewChildIterator( aHypRoot );
+ for ( ; anIter->More(); anIter->Next() )
+ {
+ _PTR(SObject) anObj = anIter->Value();
+ _PTR(SObject) aRefObj;
+ if ( anObj->ReferencedObject( aRefObj ) )
+ anObj = aRefObj;
+ else
+ continue;
+
+ if ( anObj->FindAttribute( anAttr, "AttributeName" ) )
+ {
+ CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
+ if ( CORBA::is_nil( aVar ) )
+ continue;
+
+ SMESH::SMESH_Algo_var algo = SMESH::SMESH_3D_Algo::_narrow( aVar );
+ if ( !algo->_is_nil() )
+ {
+ modeMap[ SMESH::DIM_1D ] = 0;
+ modeMap[ SMESH::DIM_2D ] = 0;
+ }
+ else
+ {
+ algo = SMESH::SMESH_2D_Algo::_narrow( aVar );
+ if ( !algo->_is_nil() )
+ modeMap[ SMESH::DIM_2D ] = 0;
+ }
+ }
+ }
+ }
+ if ( modeMap.contains( SMESH::DIM_1D ) )
+ modes.append( SMESH::DIM_1D );
+ if ( modeMap.contains( SMESH::DIM_2D ) )
+ modes.append( SMESH::DIM_2D );
+
+ myDlg->setPreviewModes( modes );
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action:
+ */
+//================================================================================
+
+bool SMESHGUI_PrecomputeOp::onApply()
+{
+ QObject* obj = sender();
+ if ( obj != myDlg && myActiveDlg == myDlg )
+ return true; // just return from error messages
+ if ( myActiveDlg == myDlg )
+ {
+ myDlg->hide();
+ myMapShapeId.clear();
+ myActiveDlg = computeDlg();
+ computeMesh();
+ }
+
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action: compute mesh
+ */
+//================================================================================
+
+void SMESHGUI_PrecomputeOp::onCancel()
+{
+ QObject* curDlg = sender();
+ if ( curDlg == computeDlg() )
+ {
+ if ( myActiveDlg == myDlg ) // return from error messages
+ myDlg->show();
+
+ return;
+ }
+
+ if ( myActiveDlg == myDlg && !myMesh->_is_nil() && myMapShapeId.count() )
+ {
+ // ask to remove already computed mesh elements
+ if ( SUIT_MessageBox::question( desktop(), tr( "SMESH_WARNING" ),
+ tr( "CLEAR_SUBMESH_QUESTION" ),
+ tr( "SMESH_BUT_DELETE" ), tr( "SMESH_BUT_NO" ), 0, 1 ) == 0 )
+ {
+ // remove all submeshes for collected shapes
+ QMap::const_iterator it = myMapShapeId.constBegin();
+ for ( ; it != myMapShapeId.constEnd(); ++it )
+ myMesh->ClearSubMesh( *it );
+ }
+ }
+ myMapShapeId.clear();
+ SMESHGUI_BaseComputeOp::onCancel();
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action: preview mesh
+ */
+//================================================================================
+
+void SMESHGUI_PrecomputeOp::onPreview()
+{
+ if ( !myDlg || myMesh->_is_nil() || myMainShape->_is_nil() )
+ return;
+
+ _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
+ if ( !aMeshSObj )
+ return;
+ // Compute preview of mesh,
+ // i.e. compute mesh till indicated dimension
+ int dim = myDlg->getPreviewMode();
+
+ SMESH::MemoryReserve aMemoryReserve;
+
+ SMESH::compute_error_array_var aCompErrors;
+ QString aHypErrors;
+
+ bool computeFailed = true, memoryLack = false;
+
+ SMESHGUI_ComputeDlg* aCompDlg = computeDlg();
+ aCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
+
+ SMESHGUI* gui = getSMESHGUI();
+ SMESH::SMESH_Gen_var gen = gui->GetSMESHGen();
+ SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape);
+ if ( errors->length() > 0 ) {
+ aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() );
+ }
+
+ SUIT_OverrideCursor aWaitCursor;
+
+ SVTK_ViewWindow* view = SMESH::GetViewWindow( gui );
+ if ( myPreviewDisplayer ) delete myPreviewDisplayer;
+ myPreviewDisplayer = new SMESHGUI_MeshEditPreview( view );
+
+ SMESH::long_array_var aShapesId = new SMESH::long_array();
+ try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+ OCC_CATCH_SIGNALS;
+#endif
+
+ SMESH::MeshPreviewStruct_var previewData =
+ gen->Precompute(myMesh, myMainShape, (SMESH::Dimension)dim, aShapesId);
+ SMESH::MeshPreviewStruct* previewRes = previewData._retn();
+ if ( previewRes && previewRes->nodesXYZ.length() > 0 )
+ {
+ computeFailed = false;
+ myPreviewDisplayer->SetData( previewRes );
+ // append shape indeces with computed mesh entities
+ for ( int i = 0, n = aShapesId->length(); i < n; i++ )
+ myMapShapeId[ aShapesId[ i ] ] = 0;
+ }
+ else
+ myPreviewDisplayer->SetVisibility(false);
+ }
+ catch(const SALOME::SALOME_Exception & S_ex){
+ memoryLack = true;
+ myPreviewDisplayer->SetVisibility(false);
+ }
+
+ try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+ OCC_CATCH_SIGNALS;
+#endif
+ aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
+ // check if there are memory problems
+ for ( int i = 0; (i < aCompErrors->length()) && !memoryLack; ++i )
+ memoryLack = ( aCompErrors[ i ].code == SMESH::COMPERR_MEMORY_PB );
+ }
+ catch(const SALOME::SALOME_Exception & S_ex){
+ memoryLack = true;
+ }
+
+ if ( memoryLack )
+ aMemoryReserve.release();
+
+ bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
+ bool noHypoError = ( aHypErrors.isEmpty() );
+
+ SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( gui );
+ int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
+
+ bool isShowError = true;
+ switch( aNotifyMode ) {
+ case 0: // show the mesh computation result dialog NEVER
+ isShowError = false;
+ break;
+ case 1: // show the mesh computation result dialog if there are some errors
+ default: // show the result dialog after each mesh computation
+ if ( !computeFailed && !memoryLack && noCompError && noHypoError )
+ isShowError = false;
+ break;
+ }
+
+ aWaitCursor.suspend();
+ // SHOW ERRORS
+ if ( isShowError )
+ {
+ myDlg->hide();
+ aCompDlg->setWindowTitle(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
+ showComputeResult( memoryLack, noCompError, aCompErrors, noHypoError, aHypErrors );
+ }
+}
+
+
+//================================================================================
+/*!
+ * \brief Constructor
+*/
+//================================================================================
+
+SMESHGUI_PrecomputeDlg::SMESHGUI_PrecomputeDlg( QWidget* parent )
+ : SMESHGUI_Dialog( parent, false, false, OK | Cancel | Help )
+{
+ setWindowTitle( tr( "CAPTION" ) );
+
+ setButtonText( OK, tr( "COMPUTE" ) );
+ QFrame* main = mainFrame();
+
+ QVBoxLayout* layout = new QVBoxLayout( main );
+
+ QFrame* frame = new QFrame( main );
+ layout->setMargin(0); layout->setSpacing(0);
+ layout->addWidget( frame );
+
+ QHBoxLayout* frameLay = new QHBoxLayout( frame );
+ frameLay->setMargin(0); frameLay->setSpacing(SPACING);
+
+ myPreviewMode = new QtxComboBox( frame );
+ frameLay->addWidget( myPreviewMode );
+
+ myPreviewBtn = new QPushButton( tr( "PREVIEW" ), frame );
+ frameLay->addWidget( myPreviewBtn );
+
+ connect( myPreviewBtn, SIGNAL( clicked( bool ) ), this, SIGNAL( preview() ) );
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+*/
+//================================================================================
+
+SMESHGUI_PrecomputeDlg::~SMESHGUI_PrecomputeDlg()
+{
+}
+
+//================================================================================
+/*!
+ * \brief Sets available preview modes
+*/
+//================================================================================
+
+void SMESHGUI_PrecomputeDlg::setPreviewModes( const QList& theModes )
+{
+ myPreviewMode->clear();
+ QList::const_iterator it = theModes.constBegin();
+ for ( int i = 0; it != theModes.constEnd(); ++it, i++ )
+ {
+ QString mode = QString( "PREVIEW_%1" ).arg( *it );
+ myPreviewMode->addItem( tr( mode.toLatin1().data() ) );
+ myPreviewMode->setId( i, *it );
+ }
+ myPreviewBtn->setEnabled( !theModes.isEmpty() );
+}
+
+//================================================================================
+/*!
+ * \brief Returns current preview mesh mode
+*/
+//================================================================================
+
+int SMESHGUI_PrecomputeDlg::getPreviewMode() const
+{
+ return myPreviewMode->currentId();
}
diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.h b/src/SMESHGUI/SMESHGUI_ComputeDlg.h
index c7a6f0e74..5ec969cc7 100644
--- a/src/SMESHGUI/SMESHGUI_ComputeDlg.h
+++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.h
@@ -31,29 +31,82 @@
#include "SMESHGUI_Dialog.h"
#include "SMESHGUI_Operation.h"
+// SALOME GUI includes
+#include
+
// Qt includes
+#include
+#include
#include
// IDL includes
#include
+#include CORBA_SERVER_HEADER(SMESH_Gen)
#include CORBA_SERVER_HEADER(SMESH_Mesh)
class QFrame;
class QPushButton;
class QTableWidget;
class QLabel;
+class QtxComboBox;
class SMESHGUI_ComputeDlg;
+class SMESHGUI_PrecomputeDlg;
class SMESHGUI_MeshEditPreview;
+class SMESH::compute_error_array;
+
namespace SMESH
{
class TShapeDisplayer;
}
+/*!
+ * \brief Base operation to compute a mesh and show computation errors
+ */
+class SMESHGUI_EXPORT SMESHGUI_BaseComputeOp: public SMESHGUI_Operation
+{
+ Q_OBJECT
+
+public:
+ SMESHGUI_BaseComputeOp();
+ virtual ~SMESHGUI_BaseComputeOp();
+
+protected:
+ virtual void startOperation();
+ virtual void stopOperation();
+
+ SMESHGUI_ComputeDlg* computeDlg() const;
+ void computeMesh();
+ void showComputeResult( const bool,
+ const bool,
+ SMESH::compute_error_array_var&,
+ const bool,
+ const QString& );
+
+protected slots:
+ void onPreviewShape();
+ void onPublishShape();
+ void onShowBadMesh();
+ void currentCellChanged();
+
+private:
+ QTableWidget* table();
+
+private:
+ QPointer myCompDlg;
+
+protected:
+ SMESH::SMESH_Mesh_var myMesh;
+ GEOM::GEOM_Object_var myMainShape;
+ SMESH::TShapeDisplayer* myTShapeDisplayer;
+ SMESHGUI_MeshEditPreview* myBadMeshDisplayer;
+ Handle(SALOME_InteractiveObject) myIObject;
+};
+
/*!
* \brief Operation to compute a mesh and show computation errors
*/
-class SMESHGUI_EXPORT SMESHGUI_ComputeOp: public SMESHGUI_Operation
+class SMESHGUI_EXPORT SMESHGUI_ComputeOp: public SMESHGUI_BaseComputeOp
{
Q_OBJECT
@@ -65,26 +118,43 @@ public:
protected:
virtual void startOperation();
- virtual void stopOperation();
protected slots:
virtual bool onApply();
+};
+
+/*!
+ * \brief Operation to preview and compute a mesh and show computation errors
+ */
+class SMESHGUI_EXPORT SMESHGUI_PrecomputeOp: public SMESHGUI_BaseComputeOp
+{
+ Q_OBJECT
+
+public:
+ SMESHGUI_PrecomputeOp();
+ virtual ~SMESHGUI_PrecomputeOp();
+
+ virtual LightApp_Dialog* dlg() const;
+
+protected:
+ virtual void startOperation();
+ virtual void stopOperation();
+ virtual void resumeOperation();
+
+ virtual void initDialog();
+
+protected slots:
+ virtual bool onApply();
+ virtual void onCancel();
private slots:
- void onPreviewShape();
- void onPublishShape();
- void onShowBadMesh();
- void currentCellChanged();
+ void onPreview();
private:
- QTableWidget* table();
-
- SMESHGUI_ComputeDlg* myDlg;
-
- SMESH::SMESH_Mesh_var myMesh;
- GEOM::GEOM_Object_var myMainShape;
- SMESH::TShapeDisplayer* myTShapeDisplayer;
- SMESHGUI_MeshEditPreview* myBadMeshDisplayer;
+ QMap< int, int > myMapShapeId;
+ QPointer myActiveDlg;
+ QPointer myDlg;
+ SMESHGUI_MeshEditPreview* myPreviewDisplayer;
};
/*!
@@ -143,9 +213,10 @@ class SMESHGUI_EXPORT SMESHGUI_ComputeDlg : public SMESHGUI_Dialog
Q_OBJECT
public:
- SMESHGUI_ComputeDlg();
+ SMESHGUI_ComputeDlg( QWidget* );
+ virtual ~SMESHGUI_ComputeDlg();
-private:
+protected:
QFrame* createMainFrame( QWidget* );
QLabel* myMeshName;
@@ -161,7 +232,32 @@ private:
SMESHGUI_MeshInfosBox* myBriefInfo;
SMESHGUI_MeshInfosBox* myFullInfo;
- friend class SMESHGUI_ComputeOp;
+ friend class SMESHGUI_BaseComputeOp;
+ friend class SMESHGUI_PrecomputeOp;
};
+/*!
+ * \brief Dialog to preview and compute a mesh and show computation errors
+ */
+
+class SMESHGUI_EXPORT SMESHGUI_PrecomputeDlg : public SMESHGUI_Dialog
+{
+ Q_OBJECT
+
+public:
+ SMESHGUI_PrecomputeDlg( QWidget* );
+ virtual ~SMESHGUI_PrecomputeDlg();
+
+ void setPreviewModes( const QList& );
+ int getPreviewMode() const;
+
+signals:
+ void preview();
+
+private:
+ QPushButton* myPreviewBtn;
+ QtxComboBox* myPreviewMode;
+};
+
+
#endif // SMESHGUI_COMPUTEDLG_H
diff --git a/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx b/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx
index 621ec92b2..8044fe73b 100644
--- a/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx
+++ b/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx
@@ -32,6 +32,7 @@
#include "SMESHGUI_MeshUtils.h"
#include "SMESHGUI_SpinBox.h"
#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_FilterDlg.h"
#include
#include
@@ -109,7 +110,8 @@ private:
SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theModule )
: QDialog( SMESH::GetDesktop( theModule ) ),
mySMESHGUI( theModule ),
- mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
+ mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+ myFilterDlg( 0 )
{
SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( mySMESHGUI );
QPixmap edgeImage ( mgr->loadPixmap("SMESH", tr("ICON_DLG_EDGE")));
@@ -164,6 +166,8 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
ElementsLineEdit = new QLineEdit(GroupArguments);
ElementsLineEdit->setValidator(myIdValidator);
+ QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+ connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
// Controls for the whole mesh selection
MeshCheck = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
@@ -272,11 +276,12 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
GroupArgumentsLayout->addWidget(ElementsLab, 0, 0);
GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
GroupArgumentsLayout->addWidget(ElementsLineEdit, 0, 2);
- GroupArgumentsLayout->addWidget(MeshCheck, 1, 0, 1, 3);
- GroupArgumentsLayout->addWidget(PathGrp, 2, 0, 1, 3);
- GroupArgumentsLayout->addWidget(BasePointGrp, 3, 0, 1, 3);
- GroupArgumentsLayout->addWidget(AnglesGrp, 4, 0, 1, 3);
- GroupArgumentsLayout->addWidget(MakeGroupsCheck, 5, 0, 1, 3);
+ GroupArgumentsLayout->addWidget(filterBtn, 0, 3);
+ GroupArgumentsLayout->addWidget(MeshCheck, 1, 0, 1, 4);
+ GroupArgumentsLayout->addWidget(PathGrp, 2, 0, 1, 4);
+ GroupArgumentsLayout->addWidget(BasePointGrp, 3, 0, 1, 4);
+ GroupArgumentsLayout->addWidget(AnglesGrp, 4, 0, 1, 4);
+ GroupArgumentsLayout->addWidget(MakeGroupsCheck, 5, 0, 1, 4);
/***************************************************************/
// common buttons group box
@@ -382,6 +387,10 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
SMESHGUI_ExtrusionAlongPathDlg::~SMESHGUI_ExtrusionAlongPathDlg()
{
// no need to delete child widgets, Qt does it all for us
+ if ( myFilterDlg != 0 ) {
+ myFilterDlg->setParent( 0 );
+ delete myFilterDlg;
+ }
}
//=================================================================================
@@ -693,8 +702,11 @@ void SMESHGUI_ExtrusionAlongPathDlg::reject()
disconnect(mySelectionMgr, 0, this, 0);
mySelectionMgr->clearFilters();
//mySelectionMgr->clearSelected();
- SMESH::SetPickable(); // ???
- SMESH::SetPointRepresentation(false);
+ if (SMESH::GetCurrentVtkView()) {
+ SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
+ SMESH::SetPointRepresentation(false);
+ SMESH::SetPickable();
+ }
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(ActorSelection);
mySMESHGUI->ResetState();
@@ -1199,3 +1211,25 @@ void SMESHGUI_ExtrusionAlongPathDlg::keyPressEvent( QKeyEvent* e )
ClickOnHelp();
}
}
+
+//=================================================================================
+// function : setFilters()
+// purpose : SLOT. Called when "Filter" button pressed.
+//=================================================================================
+void SMESHGUI_ExtrusionAlongPathDlg::setFilters()
+{
+ if ( !myFilterDlg )
+ {
+ QList types;
+ types.append( SMESH::EDGE );
+ types.append( SMESH::FACE );
+ myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, types );
+ }
+ myFilterDlg->Init( Elements1dRB->isChecked() ? SMESH::EDGE : SMESH::FACE );
+
+ myFilterDlg->SetSelection();
+ myFilterDlg->SetMesh( myMesh );
+ myFilterDlg->SetSourceWg( ElementsLineEdit );
+
+ myFilterDlg->show();
+}
diff --git a/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.h b/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.h
index 4e1aed8c3..9ca43c0d1 100644
--- a/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.h
+++ b/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.h
@@ -50,6 +50,7 @@ class SMESHGUI;
class SMESH_Actor;
class SMESHGUI_IdValidator;
class SMESHGUI_SpinBox;
+class SMESHGUI_FilterDlg;
class SVTK_Selector;
class LightApp_SelectionMgr;
class SUIT_SelectionFilter;
@@ -134,6 +135,8 @@ private:
QString myHelpFileName;
+ SMESHGUI_FilterDlg* myFilterDlg;
+
protected slots:
void reject();
@@ -150,6 +153,7 @@ private slots:
void onSelectMesh();
void OnAngleAdded();
void OnAngleRemoved();
+ void setFilters();
};
#endif // SMESHGUI_EXTRUSIONALONGPATHDLG_H
diff --git a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx
index 75bffe091..a6f1a1cca 100644
--- a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx
+++ b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx
@@ -32,6 +32,7 @@
#include "SMESHGUI_MeshUtils.h"
#include "SMESHGUI_SpinBox.h"
#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_FilterDlg.h"
#include
#include
@@ -55,6 +56,7 @@
// OCCT includes
#include
#include
+#include
// Qt includes
#include
@@ -86,7 +88,8 @@
SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
: QDialog( SMESH::GetDesktop( theModule ) ),
mySMESHGUI( theModule ),
- mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
+ mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+ myFilterDlg( 0 )
{
QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_EDGE")));
QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_TRIANGLE")));
@@ -159,22 +162,39 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator);
+ QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+ connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
// Control for the whole mesh selection
CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
- // Controls for vector selection
+ //Control for the Distance selection
+ TextLabelDistance = new QLabel(tr("SMESH_DISTANCE"), GroupArguments);
+
TextLabelVector = new QLabel(tr("SMESH_VECTOR"), GroupArguments);
-
- TextLabelDx = new QLabel(tr("SMESH_DX"), GroupArguments);
+ TextLabelDx = new QLabel(tr("SMESH_X"), GroupArguments);
SpinBox_Dx = new SMESHGUI_SpinBox(GroupArguments);
-
- TextLabelDy = new QLabel(tr("SMESH_DY"), GroupArguments);
+
+ TextLabelDy = new QLabel(tr("SMESH_Y"), GroupArguments);
SpinBox_Dy = new SMESHGUI_SpinBox(GroupArguments);
- TextLabelDz = new QLabel(tr("SMESH_DZ"), GroupArguments);
+ TextLabelDz = new QLabel(tr("SMESH_Z"), GroupArguments);
SpinBox_Dz = new SMESHGUI_SpinBox(GroupArguments);
+ // Controls for vector selection
+
+ SelectVectorButton = new QPushButton(GroupArguments);
+ SelectVectorButton->setIcon(image2);
+
+ TextLabelVx = new QLabel(tr("SMESH_DX"), GroupArguments);
+ SpinBox_Vx = new SMESHGUI_SpinBox(GroupArguments);
+
+ TextLabelVy = new QLabel(tr("SMESH_DY"), GroupArguments);
+ SpinBox_Vy = new SMESHGUI_SpinBox(GroupArguments);
+
+ TextLabelVz = new QLabel(tr("SMESH_DZ"), GroupArguments);
+ SpinBox_Vz = new SMESHGUI_SpinBox(GroupArguments);
+
// Controls for nb. steps defining
TextLabelNbSteps = new QLabel(tr("SMESH_NUMBEROFSTEPS"), GroupArguments);
SpinBox_NbSteps = new QSpinBox(GroupArguments);
@@ -184,18 +204,27 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0);
GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
- GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 6);
+ GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 5);
+ GroupArgumentsLayout->addWidget(filterBtn, 0, 7);
GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 8);
- GroupArgumentsLayout->addWidget(TextLabelVector, 2, 0);
+ GroupArgumentsLayout->addWidget(TextLabelDistance, 2, 0);
GroupArgumentsLayout->addWidget(TextLabelDx, 2, 2);
GroupArgumentsLayout->addWidget(SpinBox_Dx, 2, 3);
GroupArgumentsLayout->addWidget(TextLabelDy, 2, 4);
GroupArgumentsLayout->addWidget(SpinBox_Dy, 2, 5);
GroupArgumentsLayout->addWidget(TextLabelDz, 2, 6);
GroupArgumentsLayout->addWidget(SpinBox_Dz, 2, 7);
- GroupArgumentsLayout->addWidget(TextLabelNbSteps, 3, 0);
- GroupArgumentsLayout->addWidget(SpinBox_NbSteps, 3, 2, 1, 6);
- GroupArgumentsLayout->addWidget(MakeGroupsCheck, 4, 0, 1, 8);
+ GroupArgumentsLayout->addWidget(TextLabelVector, 3, 0);
+ GroupArgumentsLayout->addWidget(SelectVectorButton, 3, 1);
+ GroupArgumentsLayout->addWidget(TextLabelVx, 3, 2);
+ GroupArgumentsLayout->addWidget(SpinBox_Vx, 3, 3);
+ GroupArgumentsLayout->addWidget(TextLabelVy, 3, 4);
+ GroupArgumentsLayout->addWidget(SpinBox_Vy, 3, 5);
+ GroupArgumentsLayout->addWidget(TextLabelVz, 3, 6);
+ GroupArgumentsLayout->addWidget(SpinBox_Vz, 3, 7);
+ GroupArgumentsLayout->addWidget(TextLabelNbSteps, 4, 0);
+ GroupArgumentsLayout->addWidget(SpinBox_NbSteps, 4, 2, 1, 6);
+ GroupArgumentsLayout->addWidget(MakeGroupsCheck, 5, 0, 1, 8);
/***************************************************************/
SMESHGUI_ExtrusionDlgLayout->addWidget(ConstructorsBox);
@@ -203,10 +232,14 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
SMESHGUI_ExtrusionDlgLayout->addWidget(GroupButtons);
/* Initialisations */
+ SpinBox_Vx->RangeStepAndValidator(-1, 1, 0.01, 3);
+ SpinBox_Vy->RangeStepAndValidator(-1, 1, 0.01, 3);
+ SpinBox_Vz->RangeStepAndValidator(-1, 1, 0.01, 3);
+
SpinBox_Dx->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
SpinBox_Dy->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
SpinBox_Dz->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-
+
SpinBox_NbSteps->setRange(1, 999999);
RadioButton1->setChecked(true);
@@ -239,12 +272,16 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
// to update state of the Ok & Apply buttons
+ connect(SpinBox_Vx, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
+ connect(SpinBox_Vy, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
+ connect(SpinBox_Vz, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
connect(SpinBox_Dx, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
connect(SpinBox_Dy, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
connect(SpinBox_Dz, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
connect(GroupConstructors, SIGNAL(buttonClicked(int)), SLOT(ConstructorsClicked(int)));
connect(SelectElementsButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
+ connect(SelectVectorButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
/* to close dialog if study change */
@@ -264,6 +301,10 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
//=================================================================================
SMESHGUI_ExtrusionDlg::~SMESHGUI_ExtrusionDlg()
{
+ if ( myFilterDlg != 0 ) {
+ myFilterDlg->setParent( 0 );
+ delete myFilterDlg;
+ }
}
//=================================================================================
@@ -285,6 +326,9 @@ void SMESHGUI_ExtrusionDlg::Init (bool ResetControls)
SpinBox_Dx->SetValue(0);
SpinBox_Dy->SetValue(0);
SpinBox_Dz->SetValue(0);
+ SpinBox_Vx->SetValue(0);
+ SpinBox_Vy->SetValue(0);
+ SpinBox_Vz->SetValue(0);
CheckBoxMesh->setChecked(false);
onSelectMesh(false);
@@ -299,9 +343,10 @@ void SMESHGUI_ExtrusionDlg::Init (bool ResetControls)
//=================================================================================
void SMESHGUI_ExtrusionDlg::CheckIsEnable()
{
- double aX = SpinBox_Dx->GetValue();
- double aY = SpinBox_Dy->GetValue();
- double aZ = SpinBox_Dz->GetValue();
+
+ double aX = SpinBox_Vx->GetValue()*SpinBox_Dx->GetValue();
+ double aY = SpinBox_Vy->GetValue()*SpinBox_Dy->GetValue();
+ double aZ = SpinBox_Vz->GetValue()*SpinBox_Dz->GetValue();
double aModule = sqrt(aX*aX + aY*aY + aZ*aZ);
bool anIsEnable = myNbOkElements > 0 && aModule > 1.0E-38;
@@ -341,7 +386,7 @@ void SMESHGUI_ExtrusionDlg::ConstructorsClicked (int constructorId)
}
}
- myEditCurrentArgument = LineEditElements;
+ myEditCurrentArgument = (QWidget*)LineEditElements;
LineEditElements->setFocus();
if (CheckBoxMesh->isChecked())
@@ -360,11 +405,17 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply()
return false;
if (myNbOkElements) {
-
+
+ gp_XYZ aNormale(SpinBox_Vx->GetValue(),
+ SpinBox_Vy->GetValue(),
+ SpinBox_Vz->GetValue());
+
+ aNormale /= aNormale.Modulus();
+
SMESH::DirStruct aVector;
- aVector.PS.x = SpinBox_Dx->GetValue();
- aVector.PS.y = SpinBox_Dy->GetValue();
- aVector.PS.z = SpinBox_Dz->GetValue();
+ aVector.PS.x = SpinBox_Dx->GetValue()*aNormale.X();
+ aVector.PS.y = SpinBox_Dy->GetValue()*aNormale.Y();
+ aVector.PS.z = SpinBox_Dz->GetValue()*aNormale.Z();
long aNbSteps = (long)SpinBox_NbSteps->value();
@@ -410,8 +461,11 @@ void SMESHGUI_ExtrusionDlg::ClickOnCancel()
disconnect(mySelectionMgr, 0, this, 0);
mySelectionMgr->clearFilters();
//mySelectionMgr->clearSelected();
- SMESH::SetPickable(); // ???
- SMESH::SetPointRepresentation(false);
+ if (SMESH::GetCurrentVtkView()) {
+ SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
+ SMESH::SetPointRepresentation(false);
+ SMESH::SetPickable();
+ }
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(ActorSelection);
mySMESHGUI->ResetState();
@@ -514,15 +568,15 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
// clear
myActor = 0;
myIO.Nullify();
+
QString aString = "";
-
// set busy flag
- myBusy = true;
-
- myEditCurrentArgument->setText(aString);
- myNbOkElements = 0;
- myBusy = false;
-
+ if(myEditCurrentArgument == (QWidget*)LineEditElements) {
+ myBusy = true;
+ LineEditElements->setText(aString);
+ myNbOkElements = 0;
+ myBusy = false;
+ }
// get selected mesh
SALOME_ListIO aList;
mySelectionMgr->selectedObjects(aList, SVTK_Viewer::Type());
@@ -537,7 +591,7 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
myIO = IO;
myActor = SMESH::FindActorByObject(myMesh);
- if (myEditCurrentArgument == LineEditElements) {
+ if (myEditCurrentArgument == (QWidget*)LineEditElements) {
int aNbElements = 0;
// MakeGroups is available if there are groups
@@ -595,12 +649,32 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
return;
myNbOkElements = true;
+
+ myBusy = true;
+ ((QLineEdit*)myEditCurrentArgument)->setText(aString);
+ myBusy = false;
}
+ else if(myEditCurrentArgument == (QWidget*)SpinBox_Vx){
+ TColStd_IndexedMapOfInteger aMapIndex;
+ mySelector->GetIndex(IO,aMapIndex);
+ int aNbElements = aMapIndex.Extent();
+ SMDS_Mesh* aMesh = myActor ? myActor->GetObject()->GetMesh() : 0;
- myBusy = true;
- myEditCurrentArgument->setText(aString);
- myBusy = false;
+ if(aNbElements != 1 || !aMesh)
+ return;
+
+ const SMDS_MeshFace* face = dynamic_cast(aMesh->FindElement(aMapIndex(aNbElements)));
+ if (!face)
+ return;
+
+ gp_XYZ aNormale = SMESH::getNormale(face);
+ SpinBox_Vx->SetValue(aNormale.X());
+ SpinBox_Vy->SetValue(aNormale.Y());
+ SpinBox_Vz->SetValue(aNormale.Z());
+
+ }
+
// OK
CheckIsEnable();
}
@@ -618,7 +692,7 @@ void SMESHGUI_ExtrusionDlg::SetEditCurrentArgument()
mySelectionMgr->clearFilters();
if (send == SelectElementsButton) {
- myEditCurrentArgument = LineEditElements;
+ myEditCurrentArgument = (QWidget*)LineEditElements;
if (CheckBoxMesh->isChecked()) {
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(ActorSelection);
@@ -637,7 +711,12 @@ void SMESHGUI_ExtrusionDlg::SetEditCurrentArgument()
}
}
}
-
+ else if (send == SelectVectorButton){
+ myEditCurrentArgument = (QWidget*)SpinBox_Vx;
+ if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+ aViewWindow->SetSelectionMode(FaceSelection);
+ }
+
myEditCurrentArgument->setFocus();
connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
SelectionIntoArgument();
@@ -755,3 +834,25 @@ void SMESHGUI_ExtrusionDlg::keyPressEvent( QKeyEvent* e )
ClickOnHelp();
}
}
+
+//=================================================================================
+// function : setFilters()
+// purpose : SLOT. Called when "Filter" button pressed.
+//=================================================================================
+void SMESHGUI_ExtrusionDlg::setFilters()
+{
+ if ( !myFilterDlg )
+ {
+ QList types;
+ types.append( SMESH::EDGE );
+ types.append( SMESH::FACE );
+ myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, types );
+ }
+ myFilterDlg->Init( GetConstructorId() ? SMESH::FACE : SMESH::EDGE );
+
+ myFilterDlg->SetSelection();
+ myFilterDlg->SetMesh( myMesh );
+ myFilterDlg->SetSourceWg( LineEditElements );
+
+ myFilterDlg->show();
+}
diff --git a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.h b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.h
index 84d4587a9..ee3ec9cb5 100644
--- a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.h
+++ b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.h
@@ -52,6 +52,7 @@ class SMESHGUI;
class SMESH_Actor;
class SMESHGUI_IdValidator;
class SMESHGUI_SpinBox;
+class SMESHGUI_FilterDlg;
class SVTK_Selector;
class LightApp_SelectionMgr;
class SUIT_SelectionFilter;
@@ -77,7 +78,7 @@ private:
SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */
SMESHGUI_IdValidator* myIdValidator;
LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */
- QLineEdit* myEditCurrentArgument; /* Current LineEdit */
+ QWidget* myEditCurrentArgument; /* Current argument editor */
int myNbOkElements; /* to check when elements are defined */
SVTK_Selector* mySelector;
@@ -100,12 +101,20 @@ private:
QLineEdit* LineEditElements;
QCheckBox* CheckBoxMesh;
QLabel* TextLabelVector;
+ QLabel* TextLabelDistance;
+ QPushButton* SelectVectorButton;
QLabel* TextLabelDx;
SMESHGUI_SpinBox* SpinBox_Dx;
QLabel* TextLabelDy;
SMESHGUI_SpinBox* SpinBox_Dy;
QLabel* TextLabelDz;
SMESHGUI_SpinBox* SpinBox_Dz;
+ QLabel* TextLabelVx;
+ SMESHGUI_SpinBox* SpinBox_Vx;
+ QLabel* TextLabelVy;
+ SMESHGUI_SpinBox* SpinBox_Vy;
+ QLabel* TextLabelVz;
+ SMESHGUI_SpinBox* SpinBox_Vz;
QLabel* TextLabelNbSteps;
QSpinBox* SpinBox_NbSteps;
QCheckBox* MakeGroupsCheck;
@@ -118,6 +127,8 @@ private:
QString myHelpFileName;
+ SMESHGUI_FilterDlg* myFilterDlg;
+
private slots:
void ConstructorsClicked( int );
void CheckIsEnable();
@@ -131,6 +142,7 @@ private slots:
void ActivateThisDialog();
void onTextChange( const QString& );
void onSelectMesh( bool );
+ void setFilters();
};
#endif // SMESHGUI_EXTRUSIONDLG_H
diff --git a/src/SMESHGUI/SMESHGUI_Filter.cxx b/src/SMESHGUI/SMESHGUI_Filter.cxx
index a022365c8..e6d12feec 100755
--- a/src/SMESHGUI/SMESHGUI_Filter.cxx
+++ b/src/SMESHGUI/SMESHGUI_Filter.cxx
@@ -82,17 +82,18 @@ bool SMESHGUI_PredicateFilter::IsValid( const int theCellId ) const
return false;
SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
- SMESH::ElementType anElemType = myPred->GetElementType();
- int aMeshId = anElemType == SMESH::NODE ? anActor->GetNodeObjId( theCellId )
- : anActor->GetElemObjId( theCellId );
+ SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)myPred->GetElementType();
+ int aMeshId = anElemType == SMDSAbs_Node ? anActor->GetNodeObjId( theCellId )
+ : anActor->GetElemObjId( theCellId );
// if type of element != type of predicate return true because
// this predicate is not intended for filtering sush elements
- const SMDS_MeshElement* anElem = anElemType == SMESH::NODE ? aMesh->FindNode( aMeshId )
- : aMesh->FindElement( aMeshId );
- if ( anElem != 0 && anElem->GetType() != (SMDSAbs_ElementType)myPred->GetElementType() )
- return true;
-
+ const SMDS_MeshElement* anElem = anElemType == SMDSAbs_Node ? aMesh->FindNode( aMeshId )
+ : aMesh->FindElement( aMeshId );
+ // here we guess that predicate element type can not be All in case of node selection
+ if ( !anElem || (anElemType != SMDSAbs_All && anElem->GetType() != anElemType) )
+ return false;
+
return myPred->IsSatisfy( aMeshId );
}
@@ -110,14 +111,15 @@ bool SMESHGUI_PredicateFilter::IsObjValid( const int theObjId ) const
return false;
SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
- SMESH::ElementType anElemType = myPred->GetElementType();
+ SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)myPred->GetElementType();
// if type of element != type of predicate return true because
// this predicate is not intended for filtering sush elements
- const SMDS_MeshElement* anElem = anElemType == SMESH::NODE ? aMesh->FindNode( theObjId )
- : aMesh->FindElement( theObjId );
- if ( anElem != 0 && anElem->GetType() != (SMDSAbs_ElementType)myPred->GetElementType() )
- return true;
+ const SMDS_MeshElement* anElem = anElemType == SMDSAbs_Node ? aMesh->FindNode( theObjId )
+ : aMesh->FindElement( theObjId );
+ // here we guess that predicate element type can not be All in case of node selection
+ if ( !anElem || (anElemType != SMDSAbs_All && anElem->GetType() != anElemType) )
+ return false;
return myPred->IsSatisfy( theObjId );
}
diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx
index 9491e8de6..1235ce71e 100755
--- a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx
+++ b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx
@@ -47,6 +47,8 @@
#include
#include
#include
+#include
+#include
#include
#include
@@ -699,8 +701,6 @@ void SMESHGUI_FilterTable::Init (const QList& theTypes)
if (myTables.isEmpty())
{
- int aType = theTypes.first();
-
// create main layout
QVBoxLayout* aMainLay = new QVBoxLayout(this);
aMainLay->setMargin( 0 );
@@ -730,8 +730,14 @@ void SMESHGUI_FilterTable::Init (const QList& theTypes)
mySwitchTableGrpLayout->setMargin(0);
mySwitchTableGrpLayout->setSpacing(0);
- myTables[ aType ] = createTable(mySwitchTableGrp, aType);
- mySwitchTableGrpLayout->addWidget(myTables[ aType ]);
+ QList::const_iterator typeIt = theTypes.begin();
+ for ( ; typeIt != theTypes.end(); ++typeIt ) {
+ Table* aTable = createTable(mySwitchTableGrp, *typeIt);
+ myTables[ *typeIt ] = aTable;
+ mySwitchTableGrpLayout->addWidget(aTable);
+ if ( typeIt != theTypes.begin() )
+ aTable->hide();
+ }
// create buttons
myAddBtn = new QPushButton(tr("ADD"), myTableGrp);
@@ -899,41 +905,43 @@ bool SMESHGUI_FilterTable::IsValid (const bool theMess, const int theEntityType)
for (int i = 0, n = aTable->rowCount(); i < n; i++)
{
int aCriterion = GetCriterionType(i, aType);
-
- if (aCriterion == SMESH::FT_RangeOfIds ||
+ QString errMsg;
+ if (aCriterion == SMESH::FT_GroupColor ) {
+ QtxColorButton* clrBtn = qobject_cast(aTable->cellWidget(i, 2));
+ if (clrBtn && !clrBtn->color().isValid())
+ errMsg = tr( "GROUPCOLOR_ERROR" );
+ } else if (aCriterion == SMESH::FT_ElemGeomType ) {
+ QtxComboBox* typeBox = qobject_cast(aTable->cellWidget(i, 2));
+ if (typeBox && typeBox->currentId() == -1)
+ errMsg = tr( "ERROR" );
+ } else if (aCriterion == SMESH::FT_RangeOfIds ||
aCriterion == SMESH::FT_BelongToGeom ||
aCriterion == SMESH::FT_BelongToPlane ||
aCriterion == SMESH::FT_BelongToCylinder ||
aCriterion == SMESH::FT_BelongToGenSurface ||
aCriterion == SMESH::FT_LyingOnGeom) {
- if (aTable->text(i, 2).isEmpty()) {
- if (theMess)
- SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
- tr("ERROR"));
- return false;
- }
- } else {
+ if (aTable->text(i, 2).isEmpty());
+ errMsg = tr( "ERROR" );
+ }
+ else {
bool aRes = false;
bool isSignalsBlocked = aTable->signalsBlocked();
aTable->blockSignals(true);
double aThreshold = (int)aTable->text(i, 2).toDouble(&aRes);
aTable->blockSignals(isSignalsBlocked);
- if (!aRes && aTable->isEditable(i, 2)) {
- if (theMess)
- SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
- tr("ERROR"));
- return false;
- }
+ if (!aRes && aTable->isEditable(i, 2))
+ errMsg = tr( "ERROR" );
else if (aType == SMESH::EDGE &&
GetCriterionType(i, aType) == SMESH::FT_MultiConnection &&
aThreshold == 1)
- {
- if (theMess)
- SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
- tr("MULTIEDGES_ERROR"));
- return false;
- }
+ errMsg = tr( "MULTIEDGES_ERROR" );
+ }
+
+ if (!errMsg.isEmpty()) {
+ if (theMess)
+ SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), errMsg );
+ return false;
}
QTableWidgetItem* anItem = aTable->item(i, 0);
@@ -1012,12 +1020,28 @@ void SMESHGUI_FilterTable::GetCriterion (const int theRow,
int aCriterionType = GetCriterionType(theRow, aType);
- if ( aCriterionType != SMESH::FT_RangeOfIds &&
- aCriterionType != SMESH::FT_BelongToGeom &&
- aCriterionType != SMESH::FT_BelongToPlane &&
- aCriterionType != SMESH::FT_BelongToCylinder &&
- aCriterionType != SMESH::FT_BelongToGenSurface &&
- aCriterionType != SMESH::FT_LyingOnGeom)
+ if ( aCriterionType == SMESH::FT_GroupColor )
+ {
+ QtxColorButton* clrBtn = qobject_cast(aTable->cellWidget(theRow, 2));
+ if ( clrBtn )
+ {
+ const QColor qClr = clrBtn->color();
+ QString clrStr = QString( "%1;%2;%3" ).
+ arg( qClr.red()/256. ).arg( qClr.green()/256. ).arg( qClr.blue()/256. );
+ theCriterion.ThresholdStr = clrStr.toLatin1().constData();
+ }
+ }
+ else if ( aCriterionType == SMESH::FT_ElemGeomType ) {
+ QtxComboBox* typeBox = qobject_cast(aTable->cellWidget(theRow, 2));
+ if ( typeBox )
+ theCriterion.Threshold = (double)typeBox->currentId();
+ }
+ else if ( aCriterionType != SMESH::FT_RangeOfIds &&
+ aCriterionType != SMESH::FT_BelongToGeom &&
+ aCriterionType != SMESH::FT_BelongToPlane &&
+ aCriterionType != SMESH::FT_BelongToCylinder &&
+ aCriterionType != SMESH::FT_BelongToGenSurface &&
+ aCriterionType != SMESH::FT_LyingOnGeom)
{
theCriterion.Compare = ((ComboItem*)aTable->item(theRow, 1))->value();
theCriterion.Threshold = aTable->item(theRow, 2)->text().toDouble();
@@ -1063,7 +1087,28 @@ void SMESHGUI_FilterTable::SetCriterion (const int theRow,
else
aTable->setEditable(false, theRow, 4);
- if (theCriterion.Type != SMESH::FT_RangeOfIds &&
+ if (theCriterion.Type == SMESH::FT_GroupColor )
+ {
+ QtxColorButton* clrBtn = qobject_cast(aTable->cellWidget(theRow, 2));
+ if ( clrBtn )
+ {
+ QColor qClr;
+ QString clrStr( theCriterion.ThresholdStr );
+ QStringList clrVals = clrStr.split( ";" );
+ if ( clrVals.count() > 2 )
+ qClr.setRgb( (int)256*clrVals[0].toDouble(),
+ (int)256*clrVals[1].toDouble(),
+ (int)256*clrVals[2].toDouble() );
+ clrBtn->setColor( qClr );
+ }
+ }
+ else if (theCriterion.Type == SMESH::FT_ElemGeomType )
+ {
+ QtxComboBox* typeBox = qobject_cast(aTable->cellWidget(theRow, 2));
+ if ( typeBox )
+ typeBox->setCurrentId( (int)(theCriterion.Threshold + 0.5) );
+ }
+ else if (theCriterion.Type != SMESH::FT_RangeOfIds &&
theCriterion.Type != SMESH::FT_BelongToGeom &&
theCriterion.Type != SMESH::FT_BelongToPlane &&
theCriterion.Type != SMESH::FT_BelongToCylinder &&
@@ -1071,7 +1116,10 @@ void SMESHGUI_FilterTable::SetCriterion (const int theRow,
theCriterion.Type != SMESH::FT_LyingOnGeom &&
theCriterion.Type != SMESH::FT_FreeBorders &&
theCriterion.Type != SMESH::FT_FreeEdges &&
- theCriterion.Type != SMESH::FT_BadOrientedVolume)
+ theCriterion.Type != SMESH::FT_FreeNodes &&
+ theCriterion.Type != SMESH::FT_FreeFaces &&
+ theCriterion.Type != SMESH::FT_BadOrientedVolume &&
+ theCriterion.Type != SMESH::FT_LinearOrQuadratic)
aTable->item( theRow, 2 )->setText(QString("%1").arg(theCriterion.Threshold, 0, 'g', 15));
else
{
@@ -1222,12 +1270,15 @@ void SMESHGUI_FilterTable::updateAdditionalWidget()
}
ComboItem* anItem = ((ComboItem*)aTable->item(aRow, 0));
+ int aCriterion = GetCriterionType(aRow);
bool toEnable = ((ComboItem*)aTable->item(aRow, 1))->value() == SMESH::FT_EqualTo &&
- GetCriterionType(aRow) != SMESH::FT_BelongToGeom &&
- GetCriterionType(aRow) != SMESH::FT_LyingOnGeom &&
- GetCriterionType(aRow) != SMESH::FT_RangeOfIds &&
- GetCriterionType(aRow) != SMESH::FT_FreeEdges &&
- GetCriterionType(aRow) != SMESH::FT_BadOrientedVolume;
+ aCriterion != SMESH::FT_BelongToGeom &&
+ aCriterion != SMESH::FT_LyingOnGeom &&
+ aCriterion != SMESH::FT_RangeOfIds &&
+ aCriterion != SMESH::FT_FreeEdges &&
+ aCriterion != SMESH::FT_FreeFaces &&
+ aCriterion != SMESH::FT_BadOrientedVolume;
+
if (!myAddWidgets.contains(anItem))
{
myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack);
@@ -1287,6 +1338,34 @@ void SMESHGUI_FilterTable::onCurrentChanged (int theRow, int theCol)
emit CurrentChanged(theRow, theCol);
}
+//=======================================================================
+// name : geomTypes
+// Purpose : returns available geometry types of elements
+//=======================================================================
+static QList geomTypes( const int theType )
+{
+ QList typeIds;
+ if ( theType == SMESH::NODE )
+ typeIds.append( SMESH::Geom_POINT );
+ if ( theType == SMESH::ALL || theType == SMESH::EDGE )
+ typeIds.append( SMESH::Geom_EDGE );
+ if ( theType == SMESH::ALL || theType == SMESH::FACE )
+ {
+ typeIds.append( SMESH::Geom_TRIANGLE );
+ typeIds.append( SMESH::Geom_QUADRANGLE );
+ typeIds.append( SMESH::Geom_POLYGON );
+ }
+ if ( theType == SMESH::ALL || theType == SMESH::VOLUME )
+ {
+ typeIds.append( SMESH::Geom_TETRA );
+ typeIds.append( SMESH::Geom_PYRAMID );
+ typeIds.append( SMESH::Geom_HEXA );
+ typeIds.append( SMESH::Geom_PENTA );
+ typeIds.append( SMESH::Geom_POLYHEDRA );
+ }
+ return typeIds;
+}
+
//=======================================================================
// name : SMESHGUI_FilterTable::onCriterionChanged()
// Purpose : Provides reaction on change of criterion
@@ -1298,10 +1377,47 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
ComboItem* aCompareItem = (ComboItem*)aTable->item(row, 1);
int aCriterionType = GetCriterionType(row);
+ QtxColorButton* clrBtn = qobject_cast(aTable->cellWidget(row, 2));
+ QtxComboBox* typeBox = qobject_cast(aTable->cellWidget(row, 2));
+
+ if ( (aCriterionType == SMESH::FT_GroupColor && !clrBtn) ||
+ (aCriterionType == SMESH::FT_ElemGeomType && !typeBox) )
+ {
+ bool isSignalsBlocked = aTable->signalsBlocked();
+ aTable->blockSignals( true );
+ if ( aCriterionType == SMESH::FT_GroupColor )
+ aTable->setCellWidget( row, 2, new QtxColorButton( aTable ) );
+ else {
+ QtxComboBox* typeBox = new QtxComboBox( aTable );
+ aTable->setCellWidget( row, 2, typeBox );
+ QList typeIds = geomTypes( aType );
+ QList::const_iterator anIter = typeIds.begin();
+ for ( int i = 0; anIter != typeIds.end(); ++anIter, ++i) {
+ QString typeKey = QString( "GEOM_TYPE_%1" ).arg( *anIter );
+ typeBox->addItem( tr( typeKey.toLatin1().data() ) );
+ typeBox->setId( i, *anIter );
+ }
+ }
+ aTable->blockSignals( isSignalsBlocked );
+ }
+ else if ( (aCriterionType != SMESH::FT_GroupColor && clrBtn) ||
+ (aCriterionType != SMESH::FT_ElemGeomType && typeBox) )
+ {
+ bool isSignalsBlocked = aTable->signalsBlocked();
+ aTable->blockSignals( true );
+ aTable->setCellWidget( row, 2, 0 );
+ aTable->setItem( row, 2, new QTableWidgetItem() );
+ aTable->blockSignals( isSignalsBlocked );
+ }
- if (aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders ||
- aType == SMESH::FACE && aCriterionType == SMESH::FT_FreeEdges ||
- aType == SMESH::VOLUME && aCriterionType == SMESH::FT_BadOrientedVolume)
+ if (aType == SMESH::NODE && aCriterionType == SMESH::FT_FreeNodes ||
+ aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders ||
+ aType == SMESH::FACE && (aCriterionType == SMESH::FT_FreeEdges ||
+ aCriterionType == SMESH::FT_FreeFaces) ||
+ aType == SMESH::VOLUME && aCriterionType == SMESH::FT_BadOrientedVolume ||
+ aCriterionType == SMESH::FT_LinearOrQuadratic ||
+ aCriterionType == SMESH::FT_GroupColor ||
+ aCriterionType == SMESH::FT_ElemGeomType)
{
bool isSignalsBlocked = aTable->signalsBlocked();
aTable->blockSignals( true );
@@ -1309,8 +1425,8 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
if (aCompareItem->count() > 0)
aCompareItem->clear();
aTable->setEditable(false, row, 1);
- aTable->setEditable(false, row, 2);
-
+ aTable->setEditable(aCriterionType == SMESH::FT_GroupColor ||
+ aCriterionType == SMESH::FT_ElemGeomType, row, 2);
aTable->blockSignals( isSignalsBlocked );
}
else if (aCriterionType == SMESH::FT_RangeOfIds ||
@@ -1328,6 +1444,12 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
if (!aTable->isEditable(row, 2))
aTable->setEditable(true, row, 2);
}
+ else if (aCriterionType == SMESH::FT_GroupColor ||
+ aCriterionType == SMESH::FT_ElemGeomType)
+ {
+ if (!aTable->isEditable(row, 2))
+ aTable->setEditable(true, row, 2);
+ }
else
{
if (aCompareItem->count() != 3)
@@ -1505,6 +1627,7 @@ const QMap& SMESHGUI_FilterTable::getSupportedTypes() const
aTypes[ SMESH::EDGE ] = tr("EDGES");
aTypes[ SMESH::FACE ] = tr("FACES");
aTypes[ SMESH::VOLUME ] = tr("VOLUMES");
+ aTypes[ SMESH::ALL ] = tr("ELEMENTS");
}
return aTypes;
@@ -1527,6 +1650,8 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType)
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
aCriteria[ SMESH::FT_BelongToGenSurface ] = tr("BELONG_TO_GENSURFACE");
aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM");
+ aCriteria[ SMESH::FT_FreeNodes ] = tr("FREE_NODES");
+ aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR");
}
return aCriteria;
}
@@ -1544,6 +1669,9 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType)
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
aCriteria[ SMESH::FT_BelongToGenSurface ] = tr("BELONG_TO_GENSURFACE");
aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM");
+ aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR");
+ aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR");
+ aCriteria[ SMESH::FT_ElemGeomType ] = tr("GEOM_TYPE");
}
return aCriteria;
}
@@ -1567,6 +1695,10 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType)
aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM");
aCriteria[ SMESH::FT_Length2D ] = tr("LENGTH2D");
aCriteria[ SMESH::FT_MultiConnection2D ] = tr("MULTI2D_BORDERS");
+ aCriteria[ SMESH::FT_FreeFaces ] = tr("FREE_FACES");
+ aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR");
+ aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR");
+ aCriteria[ SMESH::FT_ElemGeomType ] = tr("GEOM_TYPE");
}
return aCriteria;
}
@@ -1581,12 +1713,25 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType)
aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM");
aCriteria[ SMESH::FT_BadOrientedVolume ] = tr("BAD_ORIENTED_VOLUME");
aCriteria[ SMESH::FT_Volume3D ] = tr("VOLUME_3D");
+ aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR");
+ aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR");
+ aCriteria[ SMESH::FT_ElemGeomType ] = tr("GEOM_TYPE");
}
return aCriteria;
}
- else
+ else // SMESH::ALL
{
static QMap aCriteria;
+ if (aCriteria.isEmpty())
+ {
+ aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS");
+ aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM");
+ aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM");
+ aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR");
+ aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR");
+ aCriteria[ SMESH::FT_ElemGeomType ] = tr("GEOM_TYPE");
+ }
+
return aCriteria;
}
}
@@ -2034,15 +2179,15 @@ QWidget* SMESHGUI_FilterDlg::createSourceGroup (QWidget* theParent)
QRadioButton* aMeshBtn = new QRadioButton(tr("MESH"), aBox);
QRadioButton* aSelBtn = new QRadioButton(tr("SELECTION"), aBox);
- QRadioButton* aGrpBtn = new QRadioButton(tr("CURRENT_GROUP"), aBox);
+ QRadioButton* aDlgBtn = new QRadioButton(tr("CURRENT_DIALOG"),aBox);
aLay->addWidget(aMeshBtn);
aLay->addWidget(aSelBtn);
- aLay->addWidget(aGrpBtn);
+ aLay->addWidget(aDlgBtn);
mySourceGrp->addButton(aMeshBtn, Mesh);
mySourceGrp->addButton(aSelBtn, Selection);
- mySourceGrp->addButton(aGrpBtn, Dialog);
+ mySourceGrp->addButton(aDlgBtn, Dialog);
aSelBtn->setChecked(true);
@@ -2354,6 +2499,7 @@ Selection_Mode SMESHGUI_FilterDlg::getSelMode (const int theType) const
case SMESH::EDGE : return EdgeSelection;
case SMESH::FACE : return FaceSelection;
case SMESH::VOLUME : return VolumeSelection;
+ case SMESH::ALL : return CellSelection;
default : return ActorSelection;
}
@@ -2483,10 +2629,9 @@ void SMESHGUI_FilterDlg::SetSourceWg (QWidget* theWg)
void SMESHGUI_FilterDlg::SetMesh (SMESH::SMESH_Mesh_var theMesh)
{
myMesh = theMesh;
- if ( myMesh->_is_nil() ) {
- myButtons[BTN_OK]->setEnabled(false);
- myButtons[BTN_Apply]->setEnabled(false);
- }
+ const bool isEnable = !(myMesh->_is_nil());
+ myButtons[BTN_OK]->setEnabled(isEnable);
+ myButtons[BTN_Apply]->setEnabled(isEnable);
}
//=======================================================================
@@ -2829,13 +2974,14 @@ void SMESHGUI_FilterDlg::onSelectionDone()
}
}
+ int aCriterionType = myTable->GetCriterionType(aRow);
if (aList.Extent() != 1 ||
!myTable->CurrentCell(aRow, aCol) ||
- myTable->GetCriterionType(aRow) != SMESH::FT_BelongToGeom &&
- myTable->GetCriterionType(aRow) != SMESH::FT_BelongToPlane &&
- myTable->GetCriterionType(aRow) != SMESH::FT_BelongToCylinder &&
- myTable->GetCriterionType(aRow) != SMESH::FT_BelongToGenSurface &&
- myTable->GetCriterionType(aRow) != SMESH::FT_LyingOnGeom)
+ aCriterionType != SMESH::FT_BelongToGeom &&
+ aCriterionType != SMESH::FT_BelongToPlane &&
+ aCriterionType != SMESH::FT_BelongToCylinder &&
+ aCriterionType != SMESH::FT_BelongToGenSurface &&
+ aCriterionType != SMESH::FT_LyingOnGeom)
return;
Handle(SALOME_InteractiveObject) anIO = aList.First();
@@ -2888,23 +3034,24 @@ void SMESHGUI_FilterDlg::updateSelection()
int aRow, aCol;
+ int aCriterionType = myTable->GetCriterionType(aRow);
if (myTable->CurrentCell(aRow, aCol) &&
- (myTable->GetCriterionType(aRow) == SMESH::FT_BelongToGeom ||
- myTable->GetCriterionType(aRow) == SMESH::FT_BelongToPlane ||
- myTable->GetCriterionType(aRow) == SMESH::FT_BelongToCylinder ||
- myTable->GetCriterionType(aRow) == SMESH::FT_BelongToGenSurface ||
- myTable->GetCriterionType(aRow) == SMESH::FT_LyingOnGeom)) {
+ (aCriterionType == SMESH::FT_BelongToGeom ||
+ aCriterionType == SMESH::FT_BelongToPlane ||
+ aCriterionType == SMESH::FT_BelongToCylinder ||
+ aCriterionType == SMESH::FT_BelongToGenSurface ||
+ aCriterionType == SMESH::FT_LyingOnGeom)) {
- if (myTable->GetCriterionType(aRow) == SMESH::FT_BelongToGeom ||
- myTable->GetCriterionType(aRow) == SMESH::FT_BelongToGenSurface ||
- myTable->GetCriterionType(aRow) == SMESH::FT_LyingOnGeom) {
+ if (aCriterionType == SMESH::FT_BelongToGeom ||
+ aCriterionType == SMESH::FT_BelongToGenSurface ||
+ aCriterionType == SMESH::FT_LyingOnGeom) {
mySelectionMgr->installFilter(new GEOM_SelectionFilter( aStudy, true ));
- } else if (myTable->GetCriterionType(aRow) == SMESH::FT_BelongToPlane) {
+ } else if (aCriterionType == SMESH::FT_BelongToPlane) {
mySelectionMgr->installFilter(new GEOM_FaceFilter( aStudy, StdSelect_Plane ) );
- } else if (myTable->GetCriterionType(aRow) == SMESH::FT_BelongToCylinder) {
+ } else if (aCriterionType == SMESH::FT_BelongToCylinder) {
mySelectionMgr->installFilter(new GEOM_FaceFilter( aStudy, StdSelect_Cylinder ) );
}
myIsSelectionChanged = true;
diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx
index fda56e52a..352215c95 100644
--- a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx
+++ b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx
@@ -127,7 +127,8 @@ SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule,
// purpose :
//=================================================================================
SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule,
- SMESH::SMESH_GroupBase_ptr theGroup )
+ SMESH::SMESH_GroupBase_ptr theGroup,
+ const bool theIsConvert )
: QDialog( SMESH::GetDesktop( theModule ) ),
mySMESHGUI( theModule ),
mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
@@ -137,7 +138,7 @@ SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule,
{
initDialog( false );
if ( !theGroup->_is_nil() )
- init( theGroup );
+ init( theGroup, theIsConvert );
else
{
mySelectSubMesh->setEnabled( false );
@@ -511,7 +512,8 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_Mesh_ptr theMesh)
// function : Init()
// purpose :
//=================================================================================
-void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup)
+void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
+ const bool theIsConvert)
{
restoreShowEntityMode();
myMesh = theGroup->GetMesh();
@@ -538,23 +540,27 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup)
myTypeGroup->button(aType)->setChecked(true);
myGroup = SMESH::SMESH_Group::_narrow( theGroup );
+ myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow( theGroup );
- if (!myGroup->_is_nil())
- {
- // NPAL19389: create a group with a selection in another group
- // set actor of myMesh, if it is visible, else set
- // actor of myGroup, if it is visible, else try
- // any visible actor of group or submesh of myMesh
- // commented, because an attempt to set selection on not displayed cells leads to error
- //SetAppropriateActor();
- myActor = SMESH::FindActorByObject(myMesh);
- if ( !myActor )
- myActor = SMESH::FindActorByObject(myGroup);
- SMESH::SetPickable(myActor);
+ if (myGroup->_is_nil() && myGroupOnGeom->_is_nil())
+ return;
- myGrpTypeGroup->button(0)->setChecked(true);
- onGrpTypeChanged(0);
+ // NPAL19389: create a group with a selection in another group
+ // set actor of myMesh, if it is visible, else set
+ // actor of theGroup, if it is visible, else try
+ // any visible actor of group or submesh of myMesh
+ // commented, because an attempt to set selection on not displayed cells leads to error
+ //SetAppropriateActor();
+ myActor = SMESH::FindActorByObject(myMesh);
+ if ( !myActor )
+ myActor = SMESH::FindActorByObject(theGroup);
+ SMESH::SetPickable(myActor);
+ int grpType = (!myGroup->_is_nil() ? 0 : (theIsConvert ? 0 : 1));
+ myGrpTypeGroup->button(grpType)->setChecked(true);
+ onGrpTypeChanged(grpType);
+
+ if ( grpType == 0 ) {
myCurrentLineEdit = 0;
myElements->clear();
setSelectionMode(aType);
@@ -563,8 +569,8 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup)
setShowEntityMode(); // depends on myTypeId
myIdList.clear();
- if (!myGroup->IsEmpty()) {
- SMESH::long_array_var anElements = myGroup->GetListOfID();
+ if (!theGroup->IsEmpty()) {
+ SMESH::long_array_var anElements = theGroup->GetListOfID();
int k = anElements->length();
for (int i = 0; i < k; i++) {
myIdList.append(anElements[i]);
@@ -575,39 +581,21 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup)
}
else
{
- myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow( theGroup );
-
- if ( !myGroupOnGeom->_is_nil() )
+ QString aShapeName( "" );
+ _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+ GEOM::GEOM_Object_var aGroupShape = myGroupOnGeom->GetShape();
+ if (!aGroupShape->_is_nil())
{
- // NPAL19389: create a group with a selection in another group
- // set actor of myMesh, if it is visible, else set
- // actor of myGroupOnGeom, if it is visible, else try
- // any visible actor of group or submesh of myMesh
- // commented, because an attempt to set selection on not displayed cells leads to error
- //SetAppropriateActor();
- myActor = SMESH::FindActorByObject(myMesh);
- if ( !myActor )
- myActor = SMESH::FindActorByObject(myGroupOnGeom);
- SMESH::SetPickable(myActor);
-
- myGrpTypeGroup->button(1)->setChecked(true);
- onGrpTypeChanged(1);
-
- QString aShapeName( "" );
- _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
- GEOM::GEOM_Object_var aGroupShape = myGroupOnGeom->GetShape();
- if (!aGroupShape->_is_nil())
- {
- _PTR(SObject) aGroupShapeSO = aStudy->FindObjectID(aGroupShape->GetStudyEntry());
- aShapeName = aGroupShapeSO->GetName().c_str();
- }
- myGeomGroupLine->setText( aShapeName );
- myNameChanged = true;
- myName->blockSignals(true);
- myName->setText( "Group On " + aShapeName);
- myName->blockSignals(false);
+ _PTR(SObject) aGroupShapeSO = aStudy->FindObjectID(aGroupShape->GetStudyEntry());
+ aShapeName = aGroupShapeSO->GetName().c_str();
}
+ myGeomGroupLine->setText( aShapeName );
+ myNameChanged = true;
+ myName->blockSignals(true);
+ myName->setText( "Group On " + aShapeName);
+ myName->blockSignals(false);
}
+ updateButtons();
}
//=================================================================================
@@ -756,6 +744,17 @@ bool SMESHGUI_GroupDlg::onApply()
mySelectionMgr->clearSelected();
+ if (myGroup->_is_nil()) { // creation or conversion
+ // check if group on geometry is not null
+ if (!CORBA::is_nil(myGroupOnGeom)) {
+ if (myMesh->_is_nil())
+ return false;
+ myGroup = myMesh->ConvertToStandalone( myGroupOnGeom );
+ // nullify pointer, because object become dead
+ myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
+ }
+ }
+
if (myGroup->_is_nil()) { // creation
if (myMesh->_is_nil())
return false;
@@ -1564,8 +1563,8 @@ void SMESHGUI_GroupDlg::onAdd()
SALOME_ListIteratorOfListIO anIt (aList);
for ( ; anIt.More(); anIt.Next()) {
- SMESH::SMESH_Group_var aGroup =
- SMESH::IObjectToInterface(anIt.Value());
+ SMESH::SMESH_GroupBase_var aGroup =
+ SMESH::IObjectToInterface(anIt.Value());
if (!aGroup->_is_nil()) {
// check if mesh is the same
if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) {
diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.h b/src/SMESHGUI/SMESHGUI_GroupDlg.h
index 52e9c7e45..39a417887 100644
--- a/src/SMESHGUI/SMESHGUI_GroupDlg.h
+++ b/src/SMESHGUI/SMESHGUI_GroupDlg.h
@@ -70,7 +70,8 @@ public:
SMESHGUI_GroupDlg( SMESHGUI*,
SMESH::SMESH_Mesh_ptr = SMESH::SMESH_Mesh::_nil() );
SMESHGUI_GroupDlg( SMESHGUI*,
- SMESH::SMESH_GroupBase_ptr );
+ SMESH::SMESH_GroupBase_ptr,
+ const bool theIsConvert = false );
~SMESHGUI_GroupDlg();
static QString GetDefaultName( const QString& );
@@ -113,7 +114,8 @@ private slots:
private:
void initDialog( bool );
void init( SMESH::SMESH_Mesh_ptr );
- void init( SMESH::SMESH_GroupBase_ptr );
+ void init( SMESH::SMESH_GroupBase_ptr,
+ const bool theIsConvert = false );
void closeEvent( QCloseEvent* );
void enterEvent( QEvent* );
void hideEvent( QHideEvent* ); /* ESC key */
diff --git a/src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx
index d0bad44ee..44cdfdf94 100644
--- a/src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx
+++ b/src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx
@@ -53,6 +53,11 @@
#include
#include
#include
+#include
+#include
+#include
+#include
+#include
#define SPACING 6
#define MARGIN 11
@@ -62,32 +67,17 @@
* Description : Perform boolean operations on groups
*/
-//=======================================================================
-// name : SMESHGUI_GroupOpDlg::SMESHGUI_GroupOpDlg
-// Purpose : Constructor
-//=======================================================================
-SMESHGUI_GroupOpDlg::SMESHGUI_GroupOpDlg( SMESHGUI* theModule, const int theMode )
+/*!
+ \brief Constructor
+ \param theModule pointer on module instance
+*/
+SMESHGUI_GroupOpDlg::SMESHGUI_GroupOpDlg( SMESHGUI* theModule )
: QDialog( SMESH::GetDesktop( theModule ) ),
mySMESHGUI( theModule ),
mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
{
setModal(false);
- myMode = theMode;
-
- if (myMode == UNION) {
- setWindowTitle(tr("UNION_OF_TWO_GROUPS"));
- myHelpFileName = "using_operations_on_groups_page.html#union_anchor";
- }
- else if (myMode == INTERSECT) {
- setWindowTitle(tr("INTERSECTION_OF_TWO_GROUPS"));
- myHelpFileName = "using_operations_on_groups_page.html#intersection_anchor";
- }
- else {
- setWindowTitle(tr("CUT_OF_TWO_GROUPS"));
- myHelpFileName = "using_operations_on_groups_page.html#cut_anchor";
- }
-
mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
QVBoxLayout* aDlgLay = new QVBoxLayout (this);
@@ -103,11 +93,12 @@ SMESHGUI_GroupOpDlg::SMESHGUI_GroupOpDlg( SMESHGUI* theModule, const int theMode
Init();
}
-//=======================================================================
-// name : SMESHGUI_GroupOpDlg::createMainFrame
-// Purpose : Create frame containing dialog's input fields
-//=======================================================================
-QWidget* SMESHGUI_GroupOpDlg::createMainFrame (QWidget* theParent)
+/*!
+ \brief Creates frame containing dialog's input fields
+ \param theParent parent widget
+ \return pointer on created widget
+*/
+QWidget* SMESHGUI_GroupOpDlg::createMainFrame( QWidget* theParent )
{
QWidget* aMainGrp = new QWidget(theParent);
QVBoxLayout* aLay = new QVBoxLayout(aMainGrp);
@@ -127,46 +118,64 @@ QWidget* SMESHGUI_GroupOpDlg::createMainFrame (QWidget* theParent)
aNameGrpLayout->addWidget(myNameEdit);
// ------------------------------------------------------
- QGroupBox* anArgGrp = new QGroupBox(tr("ARGUMENTS"), aMainGrp);
- QGridLayout* anArgGrpLayout = new QGridLayout(anArgGrp);
- anArgGrpLayout->setMargin(MARGIN);
- anArgGrpLayout->setSpacing(SPACING);
+ myArgGrp = new QGroupBox(tr("ARGUMENTS"), aMainGrp);
- QLabel* aObj1Lab = new QLabel(myMode == CUT ? tr("MAIN_OBJECT") :tr("OBJECT_1"), anArgGrp);
- myBtn1 = new QPushButton(anArgGrp);
- myEdit1 = new QLineEdit(anArgGrp);
- myEdit1->setAlignment( Qt::AlignLeft );
-
- QLabel* aObj2Lab = new QLabel(myMode == CUT ? tr("TOOL_OBJECT") :tr("OBJECT_2"), anArgGrp);
- myBtn2 = new QPushButton(anArgGrp);
- myEdit2 = new QLineEdit(anArgGrp);
- myEdit2->setAlignment( Qt::AlignLeft );
-
- myEdit1->setReadOnly(true);
- myEdit2->setReadOnly(true);
-
- QPixmap aPix (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
- myBtn1->setIcon(aPix);
- myBtn2->setIcon(aPix);
-
- anArgGrpLayout->addWidget(aObj1Lab, 0, 0);
- anArgGrpLayout->addWidget(myBtn1, 0, 1);
- anArgGrpLayout->addWidget(myEdit1, 0, 2);
- anArgGrpLayout->addWidget(aObj2Lab, 1, 0);
- anArgGrpLayout->addWidget(myBtn2, 1, 1);
- anArgGrpLayout->addWidget(myEdit2, 1, 2);
// ------------------------------------------------------
- aLay->addWidget(aNameGrp);
- aLay->addWidget(anArgGrp);
+
+ QGroupBox* aColorBox = new QGroupBox(tr( "SMESH_SET_COLOR" ), this);
+ QHBoxLayout* aColorBoxLayout = new QHBoxLayout(aColorBox);
+ aColorBoxLayout->setMargin(MARGIN);
+ aColorBoxLayout->setSpacing(SPACING);
+
+ QLabel* aColorLab = new QLabel(tr( "SMESH_CHECK_COLOR" ), aColorBox );
+ myColorBtn = new QtxColorButton(aColorBox);
+ myColorBtn->setSizePolicy( QSizePolicy::MinimumExpanding,
+ myColorBtn->sizePolicy().verticalPolicy() );
+
+ aColorBoxLayout->addWidget(aColorLab);
+ aColorBoxLayout->addWidget(myColorBtn);
+
+ // ------------------------------------------------------
+ aLay->addWidget( aNameGrp );
+ aLay->addWidget( myArgGrp );
+ aLay->addWidget( aColorBox );
return aMainGrp;
}
-//=======================================================================
-// name : SMESHGUI_GroupOpDlg::createButtonFrame
-// Purpose : Create frame containing buttons
-//=======================================================================
+/*!
+ \brief Gets pointer on arguments group box
+ \return pointer on arguments group box
+*/
+QGroupBox* SMESHGUI_GroupOpDlg::getArgGrp() const
+{
+ return myArgGrp;
+}
+
+/*!
+ \brief Sets help file name
+ \param theFName help file name
+*/
+void SMESHGUI_GroupOpDlg::setHelpFileName( const QString& theFName )
+{
+ myHelpFileName = theFName;
+}
+
+/*!
+ \brief Gets pointer to the module instance
+ \return pointer to the module instance
+*/
+SMESHGUI* SMESHGUI_GroupOpDlg::getSMESHGUI() const
+{
+ return mySMESHGUI;
+}
+
+/*!
+ \brief Create frame containing buttons
+ \param theParent parent widget
+ \return pointer to the created frame
+*/
QWidget* SMESHGUI_GroupOpDlg::createButtonFrame (QWidget* theParent)
{
QGroupBox* aFrame = new QGroupBox(theParent);
@@ -197,75 +206,95 @@ QWidget* SMESHGUI_GroupOpDlg::createButtonFrame (QWidget* theParent)
return aFrame;
}
-//=======================================================================
-// name : SMESHGUI_GroupOpDlg::~SMESHGUI_GroupOpDlg
-// Purpose : Destructor
-//=======================================================================
+/*!
+ \brief Destructor
+*/
SMESHGUI_GroupOpDlg::~SMESHGUI_GroupOpDlg()
{
}
-//=======================================================================
-// name : SMESHGUI_GroupOpDlg::Init
-// Purpose : Init dialog fields, connect signals and slots, show dialog
-//=======================================================================
+/*!
+ \brief Init dialog fields, connect signals and slots, show dialog
+*/
void SMESHGUI_GroupOpDlg::Init()
{
mySMESHGUI->SetActiveDialogBox((QDialog*)this);
- myFocusWg = myEdit1;
-
- myGroup1 = SMESH::SMESH_GroupBase::_nil();
- myGroup2 = SMESH::SMESH_GroupBase::_nil();
-
+
// selection and SMESHGUI
connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(ClickOnClose()));
- connect(myBtn1, SIGNAL(clicked()), this, SLOT(onFocusChanged()));
- connect(myBtn2, SIGNAL(clicked()), this, SLOT(onFocusChanged()));
-
// set selection mode
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(ActorSelection);
mySelectionMgr->installFilter(new SMESH_TypeFilter (GROUP));
}
-//=======================================================================
-// name : SMESHGUI_GroupOpDlg::isValid
-// Purpose : Verify validity of input data
-//=======================================================================
-bool SMESHGUI_GroupOpDlg::isValid()
+/*!
+ \brief Validate list of groups used for operation. Checks whether they corresponds
+ to the same face and have one type
+ \param theListGrp input list of groups
+ \return TRUE if groups are valid, FALSE otherwise
+*/
+bool SMESHGUI_GroupOpDlg::isValid( const QList& theListGrp )
{
- // Verify validity of group name
- if (myNameEdit->text() == "") {
- SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
- tr("EMPTY_NAME"));
+ if ( theListGrp.isEmpty() )
+ {
+ SUIT_MessageBox::information( this, tr("SMESH_INSUFFICIENT_DATA"),
+ tr("INCORRECT_ARGUMENTS") );
return false;
}
- // Verufy wheter arguments speciffiyed
- if (myGroup1->_is_nil() || myGroup2->_is_nil()) {
- SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
- tr("INCORRECT_ARGUMENTS"));
- return false;
+ int aMeshId = -1, aGrpType = -1;
+ QList::const_iterator anIter;
+ for ( anIter = theListGrp.begin(); anIter != theListGrp.end(); ++anIter )
+ {
+ SMESH::SMESH_GroupBase_var aGrp = *anIter;
+ if ( CORBA::is_nil( aGrp ) )
+ continue; // nonsence
+
+ SMESH::SMESH_Mesh_var aMesh = aGrp->GetMesh();
+ if ( CORBA::is_nil( aMesh ) )
+ continue;
+
+ // mesh id
+ int aCurrId = aMesh->GetId();
+ if ( aMeshId == -1 )
+ aMeshId = aCurrId;
+ else
+ {
+ if ( aMeshId != aCurrId )
+ {
+ aMeshId = -1; // different meshes
+ break;
+ }
+ }
+
+ // group type
+ int aCurrType = aGrp->GetType();
+ if ( aGrpType == -1 )
+ aGrpType = aCurrType;
+ else
+ {
+ if ( aGrpType != aCurrType )
+ {
+ aGrpType = -1; // different types
+ break;
+ }
+ }
+
}
- // Verify whether arguments belongs to same mesh
- SMESH::SMESH_Mesh_ptr aMesh1 = myGroup1->GetMesh();
- SMESH::SMESH_Mesh_ptr aMesh2 = myGroup2->GetMesh();
-
- int aMeshId1 = !aMesh1->_is_nil() ? aMesh1->GetId() : -1;
- int aMeshId2 = !aMesh2->_is_nil() ? aMesh2->GetId() : -1;
-
- if (aMeshId1 != aMeshId2 || aMeshId1 == -1) {
+ if ( aMeshId == -1 )
+ {
SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
tr("DIFF_MESHES"));
return false;
}
- // Verify whether groups have same types of entities
- if (myGroup1->GetType() != myGroup2->GetType()) {
+ if ( aGrpType == -1 )
+ {
SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
tr("DIFF_TYPES"));
return false;
@@ -274,63 +303,33 @@ bool SMESHGUI_GroupOpDlg::isValid()
return true;
}
-//=======================================================================
-// name : SMESHGUI_GroupOpDlg::onApply
-// Purpose : SLOT called when "Apply" button pressed.
-//=======================================================================
-bool SMESHGUI_GroupOpDlg::onApply()
-{
- if (!isValid() || mySMESHGUI->isActiveStudyLocked())
- return false;
-
- SMESH::SMESH_Mesh_ptr aMesh = myGroup1->GetMesh();
- QString aName = myNameEdit->text();
- SMESH::SMESH_Group_ptr aNewGrp = SMESH::SMESH_Group::_nil();
-
- if (myMode == UNION) aNewGrp = aMesh->UnionGroups(myGroup1, myGroup2, aName.toLatin1().data());
- else if (myMode == INTERSECT) aNewGrp = aMesh->IntersectGroups(myGroup1, myGroup2, aName.toLatin1().data());
- else aNewGrp = aMesh->CutGroups(myGroup1, myGroup2, aName.toLatin1().data());
-
- if (!aNewGrp->_is_nil()) {
- mySMESHGUI->updateObjBrowser(true);
- reset();
- return true;
- } else {
- SUIT_MessageBox::critical(this, tr("SMESH_ERROR"),
- tr("SMESH_OPERATION_FAILED"));
- return false;
- }
-}
-
-//=======================================================================
-// name : SMESHGUI_GroupOpDlg::onOk
-// Purpose : SLOT called when "Ok" button pressed.
-//=======================================================================
+/*!
+ \brief SLOT called when "Ok" button pressed performs operation and closes dialog box
+*/
void SMESHGUI_GroupOpDlg::onOk()
{
- if (onApply())
+ if ( onApply() )
onClose();
}
-//=======================================================================
-// name : SMESHGUI_GroupOpDlg::onClose
-// Purpose : SLOT called when "Close" button pressed. Close dialog
-//=======================================================================
+/*!
+ \brief SLOT called when "Close" button pressed closes dialog
+*/
void SMESHGUI_GroupOpDlg::onClose()
{
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(ActorSelection);
- disconnect(mySelectionMgr, 0, this, 0);
- disconnect(mySMESHGUI, 0, this, 0);
+ disconnect( mySelectionMgr, 0, this, 0 );
+ disconnect( mySMESHGUI, 0, this, 0 );
mySMESHGUI->ResetState();
mySelectionMgr->clearFilters();
+ reset();
reject();
}
-//=================================================================================
-// function : onHelp()
-// purpose :
-//=================================================================================
+/*!
+ \brief SLOT called when "Help" button pressed shows "Help" page
+*/
void SMESHGUI_GroupOpDlg::onHelp()
{
LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
@@ -351,54 +350,108 @@ void SMESHGUI_GroupOpDlg::onHelp()
}
}
-//=======================================================================
-// name : SMESHGUI_GroupOpDlg::onSelectionDone
-// Purpose : SLOT called when selection changed
-//=======================================================================
-void SMESHGUI_GroupOpDlg::onSelectionDone()
+/*!
+ \brief Gets list of currently selected groups from selection manager
+ \param theOutList out list of groups
+ \param theOutNames out list of group of group names
+ \return TRUE if operation theOutList is not empty, FALSE otherwise
+*/
+bool SMESHGUI_GroupOpDlg::getSelectedGroups( QList& theOutList,
+ QStringList& theOutNames )
{
- if (myFocusWg == myEdit1)
- myGroup1 = SMESH::SMESH_GroupBase::_nil();
- else
- myGroup2 = SMESH::SMESH_GroupBase::_nil();
+ theOutList.clear();
- myFocusWg->setText("");
+ theOutList.clear();
+ theOutNames.clear();
- SALOME_ListIO aList;
- mySelectionMgr->selectedObjects(aList);
-
- if (aList.Extent() == 1) {
+ SALOME_ListIO aListIO;
+ mySelectionMgr->selectedObjects( aListIO );
+ SALOME_ListIteratorOfListIO anIter ( aListIO );
+ for ( ; anIter.More(); anIter.Next())
+ {
SMESH::SMESH_GroupBase_var aGroup =
- SMESH::IObjectToInterface(aList.First());
-
- if (!aGroup->_is_nil())
+ SMESH::IObjectToInterface(anIter.Value());
+ if ( !aGroup->_is_nil())
{
- myFocusWg->setText(aGroup->GetName());
- myFocusWg->setCursorPosition( 0 );
-
- if (myFocusWg == myEdit1)
- myGroup1 = aGroup;
- else
- myGroup2 = aGroup;
+ theOutList.append( aGroup );
+ theOutNames.append( aGroup->GetName() );
}
}
+
+ return theOutList.count() > 0;
}
-//=======================================================================
-// name : SMESHGUI_GroupOpDlg::onDeactivate
-// Purpose : SLOT called when dialog must be deativated
-//=======================================================================
+/*!
+ \brief Converts QT-list of group to the list acceptable by IDL interface
+ \param theIn input list
+ \return list acceptable by IDL interface
+*/
+SMESH::ListOfGroups* SMESHGUI_GroupOpDlg::convert(
+ const QList& theIn )
+{
+ SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
+ aList->length( theIn.count() );
+
+ QList::const_iterator anIter = theIn.begin();
+ for ( int i = 0; anIter != theIn.end(); ++anIter, ++i )
+ aList[ i ] = *anIter;
+
+ return aList._retn();
+}
+
+/*!
+ \brief Get color to be assigned to group
+ \return color to be assigned to group
+*/
+SALOMEDS::Color SMESHGUI_GroupOpDlg::getColor() const
+{
+ QColor aQColor = myColorBtn->color();
+
+ SALOMEDS::Color aColor;
+ aColor.R = (float)aQColor.red() / 255.0;
+ aColor.G = (float)aQColor.green() / 255.0;
+ aColor.B = (float)aQColor.blue() / 255.0;
+
+ return aColor;
+}
+
+/*!
+ \brief SLOT, called when selection is changed. Current implementation does
+ nothing. The method should be redefined in derived classes to update
+ corresponding GUI controls
+*/
+void SMESHGUI_GroupOpDlg::onSelectionDone()
+{
+}
+
+/*!
+ \brief Calls onSelectionDone() and setVisible() method of base class
+ \param visible the visible state of the dialog
+*/
+void SMESHGUI_GroupOpDlg::setVisible( bool visible )
+{
+ if ( visible )
+ {
+ onSelectionDone();
+ resize( minimumSizeHint().width(), sizeHint().height() );
+ }
+ QDialog::setVisible( visible );
+}
+
+/*!
+ \brief SLOT called when dialog must be deativated
+*/
void SMESHGUI_GroupOpDlg::onDeactivate()
{
setEnabled(false);
mySelectionMgr->clearFilters();
}
-//=======================================================================
-// name : SMESHGUI_GroupOpDlg::enterEvent
-// Purpose : Event filter
-//=======================================================================
-void SMESHGUI_GroupOpDlg::enterEvent (QEvent*)
+/*!
+ \brief Event filter updates selection mode and selection filter. This virtual method
+ is redefined from the base class it is called when dialog obtains input focus
+*/
+void SMESHGUI_GroupOpDlg::enterEvent(QEvent*)
{
mySMESHGUI->EmitSignalDeactivateDialog();
setEnabled(true);
@@ -407,43 +460,49 @@ void SMESHGUI_GroupOpDlg::enterEvent (QEvent*)
mySelectionMgr->installFilter(new SMESH_TypeFilter (GROUP));
}
-//=======================================================================
-// name : SMESHGUI_GroupOpDlg::closeEvent
-// purpose :
-//=======================================================================
-void SMESHGUI_GroupOpDlg::closeEvent (QCloseEvent*)
+/*!
+ \brief Provides reaction on close event, closes the dialog box
+*/
+void SMESHGUI_GroupOpDlg::closeEvent(QCloseEvent*)
{
onClose();
}
-//=======================================================================
-// name : SMESHGUI_GroupOpDlg::onFocusChanged
-// Purpose : SLOT. Called when "Select" button pressed.
-//=======================================================================
-void SMESHGUI_GroupOpDlg::onFocusChanged()
-{
- const QObject* aSender = sender();
- myFocusWg = aSender == myBtn1 ? myEdit1 : myEdit2;
- onSelectionDone();
-}
-
-//=======================================================================
-// name : SMESHGUI_GroupOpDlg::reset
-// Purpose : Rest state of dialog
-//=======================================================================
+/*!
+ \brief Resets state of the dialog, initializes its fields with default value, etc.
+ Usually called by onApply() slot to reinitialize dialog fields. This virtual method
+ should be redefined in derived class to update its own fileds
+*/
void SMESHGUI_GroupOpDlg::reset()
{
myNameEdit->setText("");
- myEdit1->setText("");
- myEdit2->setText("");
- myFocusWg = myEdit1;
myNameEdit->setFocus();
}
-//=================================================================================
-// function : keyPressEvent()
-// purpose :
-//=================================================================================
+/*!
+ \brief Gets name of group to be created
+ \return name of group to be created
+ \sa setName()
+*/
+QString SMESHGUI_GroupOpDlg::getName() const
+{
+ return myNameEdit->text();
+}
+
+/*!
+ \brief Sets name of group to be created
+ \param theName name of group to be created
+ \sa getName()
+*/
+void SMESHGUI_GroupOpDlg::setName( const QString& theName )
+{
+ myNameEdit->setText( theName );
+}
+
+/*!
+ \brief Provides reaction on “F1” button pressing
+ \param e key press event
+*/
void SMESHGUI_GroupOpDlg::keyPressEvent( QKeyEvent* e )
{
QDialog::keyPressEvent( e );
@@ -455,3 +514,535 @@ void SMESHGUI_GroupOpDlg::keyPressEvent( QKeyEvent* e )
onHelp();
}
}
+
+/*!
+ \brief This virtual slot does nothing and should be redefined in derived classes
+ \return return false;
+*/
+bool SMESHGUI_GroupOpDlg::onApply()
+{
+ return false;
+}
+
+// === === === === === === === === === === === === === === === === === === === === ===
+
+/*!
+ \brief Constructor
+ \param theModule module
+*/
+SMESHGUI_UnionGroupsDlg::SMESHGUI_UnionGroupsDlg( SMESHGUI* theModule )
+: SMESHGUI_GroupOpDlg( theModule )
+{
+ setWindowTitle(tr("UNION_OF_GROUPS"));
+ setHelpFileName( "using_operations_on_groups_page.html#union_anchor" );
+
+ QGroupBox* anArgGrp = getArgGrp();
+ myListWg = new QListWidget( anArgGrp );
+
+ QHBoxLayout* aLay = new QHBoxLayout( anArgGrp );
+ aLay->addWidget( myListWg );
+}
+
+/*!
+ \brief Destructor
+*/
+SMESHGUI_UnionGroupsDlg::~SMESHGUI_UnionGroupsDlg()
+{
+}
+
+/*!
+ \brief This virtual method redefined from the base class resets state
+ of the dialog, initializes its fields with default value, etc.
+*/
+void SMESHGUI_UnionGroupsDlg::reset()
+{
+ SMESHGUI_GroupOpDlg::reset();
+ myListWg->clear();
+ myGroups.clear();
+}
+
+/*!
+ \brief SLOT called when apply button is pressed performs operation
+ \return TRUE if operation has been completed successfully, FALSE otherwise
+*/
+bool SMESHGUI_UnionGroupsDlg::onApply()
+{
+ if ( getSMESHGUI()->isActiveStudyLocked())
+ return false;
+
+ // Verify validity of group name
+ if ( getName() == "" )
+ {
+ SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
+ SMESHGUI_GroupOpDlg::tr("EMPTY_NAME"));
+ return false;
+ }
+
+ if ( !isValid( myGroups ) )
+ return false;
+
+ SMESH::SMESH_Mesh_var aMesh = myGroups.first()->GetMesh();
+ QString aName = getName();
+
+ bool aRes = false;
+ try
+ {
+ SMESH::ListOfGroups_var aList = convert( myGroups );
+ SMESH::SMESH_Group_var aNewGrp =
+ aMesh->UnionListOfGroups( aList, aName.toLatin1().constData() );
+ if ( !CORBA::is_nil( aNewGrp ) )
+ {
+ aNewGrp->SetColor( getColor() );
+ aRes = true;
+ }
+ }
+ catch( ... )
+ {
+ aRes = false;
+ }
+
+ if ( aRes )
+ {
+ getSMESHGUI()->updateObjBrowser(true);
+ reset();
+ return true;
+ }
+ else
+ {
+ SUIT_MessageBox::critical(this, tr("SMESH_ERROR"),
+ tr("SMESH_OPERATION_FAILED"));
+ return false;
+ }
+}
+
+/*!
+ \brief SLOT, called when selection is changed, updates corresponding GUI controls
+*/
+void SMESHGUI_UnionGroupsDlg::onSelectionDone()
+{
+ QStringList aNames;
+ getSelectedGroups( myGroups, aNames );
+ myListWg->clear();
+ myListWg->addItems( aNames );
+}
+
+// === === === === === === === === === === === === === === === === === === === === ===
+
+/*!
+ \brief Constructor
+ \param theModule module
+*/
+SMESHGUI_IntersectGroupsDlg::SMESHGUI_IntersectGroupsDlg( SMESHGUI* theModule )
+: SMESHGUI_GroupOpDlg( theModule )
+{
+ setWindowTitle(tr("INTERSECTION_OF_GROUPS"));
+ setHelpFileName( "using_operations_on_groups_page.html#intersection_anchor" );
+
+ QGroupBox* anArgGrp = getArgGrp();
+ myListWg = new QListWidget( anArgGrp );
+
+ QHBoxLayout* aLay = new QHBoxLayout( anArgGrp );
+ aLay->addWidget( myListWg );
+}
+
+/*!
+ \brief Destructor
+*/
+SMESHGUI_IntersectGroupsDlg::~SMESHGUI_IntersectGroupsDlg()
+{
+}
+
+/*!
+ \brief This virtual method redefined from the base class resets state
+ of the dialog, initializes its fields with default value, etc.
+*/
+void SMESHGUI_IntersectGroupsDlg::reset()
+{
+ SMESHGUI_GroupOpDlg::reset();
+ myListWg->clear();
+ myGroups.clear();
+}
+
+/*!
+ \brief SLOT called when apply button is pressed performs operation
+ \return TRUE if operation has been completed successfully, FALSE otherwise
+*/
+bool SMESHGUI_IntersectGroupsDlg::onApply()
+{
+ if ( getSMESHGUI()->isActiveStudyLocked())
+ return false;
+
+ // Verify validity of group name
+ if ( getName() == "" )
+ {
+ SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
+ SMESHGUI_GroupOpDlg::tr("EMPTY_NAME"));
+ return false;
+ }
+
+ if ( !isValid( myGroups ) )
+ return false;
+
+ SMESH::SMESH_Mesh_var aMesh = myGroups.first()->GetMesh();
+ QString aName = getName();
+
+ bool aRes = false;
+ try
+ {
+ SMESH::ListOfGroups_var aList = convert( myGroups );
+ SMESH::SMESH_Group_var aNewGrp =
+ aMesh->IntersectListOfGroups( aList, aName.toLatin1().constData() );
+ if ( !CORBA::is_nil( aNewGrp ) )
+ {
+ aNewGrp->SetColor( getColor() );
+ aRes = true;
+ }
+ }
+ catch( ... )
+ {
+ aRes = false;
+ }
+
+ if ( aRes )
+ {
+ getSMESHGUI()->updateObjBrowser(true);
+ reset();
+ return true;
+ }
+ else
+ {
+ SUIT_MessageBox::critical(this, tr("SMESH_ERROR"),
+ tr("SMESH_OPERATION_FAILED"));
+ return false;
+ }
+}
+
+/*!
+ \brief SLOT, called when selection is changed, updates corresponding GUI controls
+*/
+void SMESHGUI_IntersectGroupsDlg::onSelectionDone()
+{
+ QStringList aNames;
+ getSelectedGroups( myGroups, aNames );
+ myListWg->clear();
+ myListWg->addItems( aNames );
+}
+
+// === === === === === === === === === === === === === === === === === === === === ===
+
+/*!
+ \brief Constructor
+ \param theModule module
+*/
+SMESHGUI_CutGroupsDlg::SMESHGUI_CutGroupsDlg( SMESHGUI* theModule )
+: SMESHGUI_GroupOpDlg( theModule )
+{
+ setWindowTitle(tr("CUT_OF_GROUPS"));
+ setHelpFileName( "using_operations_on_groups_page.html#cut_anchor" );
+
+ QGroupBox* anArgGrp = getArgGrp();
+
+ QPixmap aPix (SMESH::GetResourceMgr( getSMESHGUI() )->loadPixmap("SMESH", tr("ICON_SELECT")));
+
+ // frame 1
+ QFrame* aFrame1 = new QFrame( anArgGrp );
+ QLabel* aLbl1 = new QLabel( tr("MAIN_OBJECT"), aFrame1 );
+ aLbl1->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+ myBtn1 = new QPushButton( aFrame1 );
+ myBtn1->setIcon(aPix);
+ myListWg1 = new QListWidget( aFrame1 );
+
+ QGridLayout* aLay1 = new QGridLayout( aFrame1 );
+ aLay1->setSpacing( SPACING );
+ aLay1->addWidget( aLbl1, 0, 0 );
+ aLay1->addWidget( myBtn1, 0, 1 );
+ aLay1->addWidget( myListWg1, 1, 0, 1, 2 );
+ //QSpacerItem* aHSpacer1 = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ //aLay1->addItem( aHSpacer1, 0, 2 );
+
+
+ // frame 2
+ QFrame* aFrame2 = new QFrame( anArgGrp );
+ QLabel* aLbl2 = new QLabel( tr("TOOL_OBJECT"), aFrame2 );
+ aLbl2->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+ myBtn2 = new QPushButton( aFrame2 );
+ myBtn2->setIcon(aPix);
+ myListWg2 = new QListWidget( aFrame2 );
+
+ QGridLayout* aLay2 = new QGridLayout( aFrame2 );
+ aLay2->setSpacing( SPACING );
+ aLay2->addWidget( aLbl2, 0, 0 );
+ aLay2->addWidget( myBtn2, 0, 1 );
+ aLay2->addWidget( myListWg2, 1, 0, 1, 2 );
+ //QSpacerItem* aHSpacer2 = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ //aLay2->addItem( aHSpacer2, 0, 2 );
+
+ // create button group
+
+ QButtonGroup* aGrp = new QButtonGroup( anArgGrp );
+ aGrp->addButton( myBtn1, 0 );
+ aGrp->addButton( myBtn2, 1 );
+ myBtn1->setCheckable( true );
+ myBtn2->setCheckable( true );
+ aGrp->setExclusive( true );
+ myBtn1->setChecked( true );
+
+ // fill layout
+ QHBoxLayout* aLay = new QHBoxLayout( anArgGrp );
+ aLay->setSpacing( SPACING );
+ aLay->addWidget( aFrame1 );
+ aLay->addWidget( aFrame2 );
+}
+
+/*!
+ \brief Destructor
+*/
+SMESHGUI_CutGroupsDlg::~SMESHGUI_CutGroupsDlg()
+{
+}
+
+/*!
+ \brief This virtual method redefined from the base class resets state
+ of the dialog, initializes its fields with default value, etc.
+*/
+void SMESHGUI_CutGroupsDlg::reset()
+{
+ SMESHGUI_GroupOpDlg::reset();
+
+ myListWg1->clear();
+ myGroups1.clear();
+
+ myListWg2->clear();
+ myGroups2.clear();
+}
+
+/*!
+ \brief SLOT called when apply button is pressed performs operation
+ \return TRUE if operation has been completed successfully, FALSE otherwise
+*/
+bool SMESHGUI_CutGroupsDlg::onApply()
+{
+ if ( getSMESHGUI()->isActiveStudyLocked())
+ return false;
+
+ // Verify validity of group name
+ if ( getName() == "" )
+ {
+ SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
+ SMESHGUI_GroupOpDlg::tr("EMPTY_NAME"));
+ return false;
+ }
+
+ if ( myGroups1.isEmpty() || myGroups2.isEmpty() )
+ {
+ SUIT_MessageBox::information( this, tr("SMESH_INSUFFICIENT_DATA"),
+ SMESHGUI_GroupOpDlg::tr("INCORRECT_ARGUMENTS") );
+ return false;
+ }
+
+ QList aGroups = myGroups1;
+ QList::iterator anIter;
+ for ( anIter = myGroups2.begin(); anIter != myGroups2.end(); ++anIter )
+ aGroups.append( *anIter );
+
+ if ( !isValid( aGroups ) )
+ return false;
+
+ SMESH::SMESH_Mesh_var aMesh = myGroups1.first()->GetMesh();
+ QString aName = getName();
+
+ bool aRes = false;
+ try
+ {
+ SMESH::ListOfGroups_var aList1 = convert( myGroups1 );
+ SMESH::ListOfGroups_var aList2 = convert( myGroups2 );
+ SMESH::SMESH_Group_var aNewGrp =
+ aMesh->CutListOfGroups( aList1, aList2, aName.toLatin1().constData() );
+ if ( !CORBA::is_nil( aNewGrp ) )
+ {
+ aNewGrp->SetColor( getColor() );
+ aRes = true;
+ }
+ }
+ catch( ... )
+ {
+ aRes = false;
+ }
+
+ if ( aRes )
+ {
+ getSMESHGUI()->updateObjBrowser(true);
+ reset();
+ return true;
+ }
+ else
+ {
+ SUIT_MessageBox::critical(this, tr("SMESH_ERROR"),
+ tr("SMESH_OPERATION_FAILED"));
+ return false;
+ }
+}
+
+/*!
+ \brief SLOT, called when selection is changed, updates corresponding GUI controls
+*/
+void SMESHGUI_CutGroupsDlg::onSelectionDone()
+{
+ QStringList aNames;
+ if ( myBtn2->isChecked() )
+ {
+ getSelectedGroups( myGroups2, aNames );
+ myListWg2->clear();
+ myListWg2->addItems( aNames );
+ }
+ else
+ {
+ getSelectedGroups( myGroups1, aNames );
+ myListWg1->clear();
+ myListWg1->addItems( aNames );
+ }
+}
+
+// === === === === === === === === === === === === === === === === === === === === ===
+
+/*!
+ \brief Constructor
+ \param theModule module
+*/
+SMESHGUI_DimGroupDlg::SMESHGUI_DimGroupDlg( SMESHGUI* theModule )
+: SMESHGUI_GroupOpDlg( theModule )
+{
+ setWindowTitle( tr( "CREATE_GROUP_OF_UNDERLYING_ELEMS" ) );
+ setHelpFileName( "creating_groups_page.html#gui_create_dim_group" );
+
+ QGroupBox* anArgGrp = getArgGrp();
+
+ QLabel* aLbl = new QLabel( tr( "ELEMENTS_TYPE" ), anArgGrp );
+
+ myCombo = new QComboBox( anArgGrp );
+ static QStringList anItems;
+ if ( anItems.isEmpty() )
+ {
+ anItems.append( tr( "NODE" ) );
+ anItems.append( tr( "EDGE" ) );
+ anItems.append( tr( "FACE" ) );
+ anItems.append( tr( "VOLUME" ) );
+ }
+ myCombo->addItems( anItems );
+ myCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+
+ myListWg = new QListWidget( anArgGrp );
+
+ // layout
+ QGridLayout* aLay = new QGridLayout( anArgGrp );
+ aLay->setSpacing( SPACING );
+ aLay->addWidget( aLbl, 0, 0 );
+ aLay->addWidget( myCombo, 0, 1 );
+ aLay->addWidget( myListWg, 1, 0, 1, 2 );
+}
+
+/*!
+ \brief Destructor
+*/
+SMESHGUI_DimGroupDlg::~SMESHGUI_DimGroupDlg()
+{
+}
+
+/*!
+ \brief This virtual method redefined from the base class resets state
+ of the dialog, initializes its fields with default value, etc.
+*/
+void SMESHGUI_DimGroupDlg::reset()
+{
+ SMESHGUI_GroupOpDlg::reset();
+ myListWg->clear();
+ myGroups.clear();
+}
+
+/*!
+ \brief Gets elements type
+ \return elements type
+ \sa setElementType()
+*/
+SMESH::ElementType SMESHGUI_DimGroupDlg::getElementType() const
+{
+ return (SMESH::ElementType)( myCombo->currentIndex() + 1 );
+}
+
+/*!
+ \brief Sets elements type
+ \param theElemType elements type
+ \sa getElementType()
+*/
+void SMESHGUI_DimGroupDlg::setElementType( const SMESH::ElementType& theElemType )
+{
+ myCombo->setCurrentIndex( theElemType - 1 );
+}
+
+/*!
+ \brief SLOT called when apply button is pressed performs operation
+ \return TRUE if operation has been completed successfully, FALSE otherwise
+*/
+bool SMESHGUI_DimGroupDlg::onApply()
+{
+ if ( getSMESHGUI()->isActiveStudyLocked())
+ return false;
+
+ // Verify validity of group name
+ if ( getName() == "" )
+ {
+ SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
+ SMESHGUI_GroupOpDlg::tr("EMPTY_NAME"));
+ return false;
+ }
+
+ if ( !isValid( myGroups ) )
+ return false;
+
+ SMESH::SMESH_Mesh_var aMesh = myGroups.first()->GetMesh();
+ QString aName = getName();
+
+ bool aRes = false;
+ try
+ {
+ SMESH::ListOfGroups_var aList = convert( myGroups );
+ SMESH::ElementType anElemType = getElementType();
+ SMESH::SMESH_Group_var aNewGrp =
+ aMesh->CreateDimGroup( aList, anElemType, aName.toLatin1().constData() );
+ if ( !CORBA::is_nil( aNewGrp ) )
+ {
+ aNewGrp->SetColor( getColor() );
+ aRes = true;
+ }
+ }
+ catch( ... )
+ {
+ aRes = false;
+ }
+
+ if ( aRes )
+ {
+ getSMESHGUI()->updateObjBrowser(true);
+ reset();
+ return true;
+ }
+ else
+ {
+ SUIT_MessageBox::critical(this, tr("SMESH_ERROR"),
+ tr("SMESH_OPERATION_FAILED"));
+ return false;
+ }
+}
+
+/*!
+ \brief SLOT, called when selection is changed, updates corresponding GUI controls
+*/
+void SMESHGUI_DimGroupDlg::onSelectionDone()
+{
+ QStringList aNames;
+ getSelectedGroups( myGroups, aNames );
+ myListWg->clear();
+ myListWg->addItems( aNames );
+}
+
+
diff --git a/src/SMESHGUI/SMESHGUI_GroupOpDlg.h b/src/SMESHGUI/SMESHGUI_GroupOpDlg.h
index 289cc953e..fda94dd01 100644
--- a/src/SMESHGUI/SMESHGUI_GroupOpDlg.h
+++ b/src/SMESHGUI/SMESHGUI_GroupOpDlg.h
@@ -37,6 +37,10 @@
#include CORBA_SERVER_HEADER(SMESH_Group)
class QPushButton;
+class QtxColorButton;
+class QComboBox;
+class QListWidget;
+class QGroupBox;
class QLineEdit;
class SMESHGUI;
class LightApp_SelectionMgr;
@@ -52,14 +56,37 @@ class SMESHGUI_EXPORT SMESHGUI_GroupOpDlg : public QDialog
Q_OBJECT
public:
- enum { UNION, INTERSECT, CUT };
+ //enum { UNION, INTERSECT, CUT };
public:
- SMESHGUI_GroupOpDlg( SMESHGUI*, const int );
+ SMESHGUI_GroupOpDlg( SMESHGUI* );
virtual ~SMESHGUI_GroupOpDlg();
void Init();
-
+
+protected slots:
+
+ virtual bool onApply();
+ virtual void onSelectionDone();
+ virtual void setVisible ( bool visible );
+
+protected:
+
+ virtual void reset();
+
+ QString getName() const;
+ void setName( const QString& theName );
+
+ QGroupBox* getArgGrp() const;
+ void setHelpFileName( const QString& theFName );
+ SMESHGUI* getSMESHGUI() const;
+ bool isValid( const QList& theListGrp );
+ bool getSelectedGroups( QList& theOutList,
+ QStringList& theOutNames );
+ SMESH::ListOfGroups* convert( const QList& );
+
+ SALOMEDS::Color getColor() const;
+
private:
void closeEvent( QCloseEvent* );
void enterEvent( QEvent* );
@@ -67,20 +94,15 @@ private:
private slots:
void onOk();
- bool onApply();
void onClose();
void onHelp();
void onDeactivate();
- void onSelectionDone();
- void onFocusChanged();
private:
QWidget* createButtonFrame( QWidget* );
QWidget* createMainFrame ( QWidget* );
- bool isValid();
- void reset();
-
+
private:
QPushButton* myOkBtn;
QPushButton* myApplyBtn;
@@ -88,22 +110,129 @@ private:
QPushButton* myHelpBtn;
QLineEdit* myNameEdit;
- QLineEdit* myEdit1;
- QLineEdit* myEdit2;
- QPushButton* myBtn1;
- QPushButton* myBtn2;
+ QGroupBox* myArgGrp;
+ QtxColorButton* myColorBtn;
SMESHGUI* mySMESHGUI;
LightApp_SelectionMgr* mySelectionMgr;
- int myMode;
SVTK_Selector* mySelector;
- QLineEdit* myFocusWg;
-
- SMESH::SMESH_GroupBase_var myGroup1;
- SMESH::SMESH_GroupBase_var myGroup2;
-
QString myHelpFileName;
};
+/*
+ Class : SMESHGUI_UnionGroupsDlg
+ Description : Perform union of several groups
+*/
+
+class SMESHGUI_EXPORT SMESHGUI_UnionGroupsDlg : public SMESHGUI_GroupOpDlg
+{
+ Q_OBJECT
+
+public:
+
+ SMESHGUI_UnionGroupsDlg( SMESHGUI* );
+ virtual ~SMESHGUI_UnionGroupsDlg();
+
+protected slots:
+ virtual bool onApply();
+ virtual void onSelectionDone();
+
+protected:
+ virtual void reset();
+
+private:
+ QListWidget* myListWg;
+ QList myGroups;
+};
+
+/*
+ Class : SMESHGUI_IntersectGroupsDlg
+ Description : Perform intersection of several groups
+*/
+
+class SMESHGUI_EXPORT SMESHGUI_IntersectGroupsDlg : public SMESHGUI_GroupOpDlg
+{
+ Q_OBJECT
+
+public:
+
+ SMESHGUI_IntersectGroupsDlg( SMESHGUI* );
+ virtual ~SMESHGUI_IntersectGroupsDlg();
+
+protected slots:
+ virtual bool onApply();
+ virtual void onSelectionDone();
+
+protected:
+ virtual void reset();
+
+private:
+ QListWidget* myListWg;
+ QList myGroups;
+};
+
+/*
+ Class : SMESHGUI_CutGroupsDlg
+ Description : Perform cut of several groups
+*/
+
+class SMESHGUI_EXPORT SMESHGUI_CutGroupsDlg : public SMESHGUI_GroupOpDlg
+{
+ Q_OBJECT
+
+public:
+
+ SMESHGUI_CutGroupsDlg( SMESHGUI* );
+ virtual ~SMESHGUI_CutGroupsDlg();
+
+protected slots:
+ virtual bool onApply();
+ virtual void onSelectionDone();
+
+protected:
+ virtual void reset();
+
+private:
+ QPushButton* myBtn1;
+ QPushButton* myBtn2;
+ QListWidget* myListWg1;
+ QListWidget* myListWg2;
+ QList myGroups1;
+ QList myGroups2;
+};
+
+/*
+ Class : SMESHGUI_DimGroupDlg
+ Description : Dialog for creating groups of entities from existing
+ groups of superior dimensions
+*/
+
+class SMESHGUI_EXPORT SMESHGUI_DimGroupDlg : public SMESHGUI_GroupOpDlg
+{
+ Q_OBJECT
+
+public:
+
+ SMESHGUI_DimGroupDlg( SMESHGUI* );
+ virtual ~SMESHGUI_DimGroupDlg();
+
+ SMESH::ElementType getElementType() const;
+ void setElementType( const SMESH::ElementType& theElemType );
+
+protected:
+ virtual void reset();
+
+protected slots:
+ virtual bool onApply();
+ virtual void onSelectionDone();
+
+private:
+ QComboBox* myCombo;
+ QListWidget* myListWg;
+ QList myGroups;
+};
+
#endif // SMESHGUI_GROUPOPDLG_H
+
+
diff --git a/src/SMESHGUI/SMESHGUI_Hypotheses.cxx b/src/SMESHGUI/SMESHGUI_Hypotheses.cxx
index be4bffe15..4ebd58629 100644
--- a/src/SMESHGUI/SMESHGUI_Hypotheses.cxx
+++ b/src/SMESHGUI/SMESHGUI_Hypotheses.cxx
@@ -62,14 +62,18 @@ SMESHGUI_GenericHypothesisCreator::~SMESHGUI_GenericHypothesisCreator()
{
}
+void SMESHGUI_GenericHypothesisCreator::setInitParamsHypothesis(SMESH::SMESH_Hypothesis_ptr hyp)
+{
+ if ( !CORBA::is_nil( hyp ) && hypType() == hyp->GetName() )
+ myInitParamsHypo = SMESH::SMESH_Hypothesis::_duplicate( hyp );
+}
+
void SMESHGUI_GenericHypothesisCreator::create( SMESH::SMESH_Hypothesis_ptr initParamsHyp,
const QString& theHypName,
QWidget* parent)
{
MESSAGE( "Creation of hypothesis with initial params" );
-
- if ( !CORBA::is_nil( initParamsHyp ) && hypType() == initParamsHyp->GetName() )
- myInitParamsHypo = SMESH::SMESH_Hypothesis::_duplicate( initParamsHyp );
+ setInitParamsHypothesis( initParamsHyp );
create( false, theHypName, parent );
}
@@ -248,6 +252,11 @@ QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame()
}
void SMESHGUI_GenericHypothesisCreator::onValueChanged()
+{
+ valueChanged( (QWidget*) sender() );
+}
+
+void SMESHGUI_GenericHypothesisCreator::valueChanged( QWidget* )
{
}
@@ -337,13 +346,29 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_GenericHypothesisCreator::hypothesis() cons
return myHypo;
}
-SMESH::SMESH_Hypothesis_var SMESHGUI_GenericHypothesisCreator::initParamsHypothesis() const
+//================================================================================
+/*!
+ * \brief Return hypothesis containing initial parameters
+ * \param strictly - if true, always return myInitParamsHypo,
+ * else, return myInitParamsHypo only in creation mode and if it
+ * is non-nil
+ */
+//================================================================================
+
+SMESH::SMESH_Hypothesis_var SMESHGUI_GenericHypothesisCreator::initParamsHypothesis(const bool strictly) const
{
- if ( CORBA::is_nil( myInitParamsHypo ))
+ if ( strictly )
+ return myInitParamsHypo;
+ if ( !isCreation() || CORBA::is_nil( myInitParamsHypo ))
return myHypo;
return myInitParamsHypo;
}
+bool SMESHGUI_GenericHypothesisCreator::hasInitParamsHypothesis() const
+{
+ return !CORBA::is_nil( myInitParamsHypo );
+}
+
QString SMESHGUI_GenericHypothesisCreator::hypType() const
{
return myHypType;
diff --git a/src/SMESHGUI/SMESHGUI_Hypotheses.h b/src/SMESHGUI/SMESHGUI_Hypotheses.h
index 20377c1e8..1a1978a41 100644
--- a/src/SMESHGUI/SMESHGUI_Hypotheses.h
+++ b/src/SMESHGUI/SMESHGUI_Hypotheses.h
@@ -55,6 +55,7 @@ public:
void create( bool, const QString&, QWidget* );
void edit( SMESH::SMESH_Hypothesis_ptr,
const QString&, QWidget* );
+ void setInitParamsHypothesis(SMESH::SMESH_Hypothesis_ptr);
virtual bool checkParams() const = 0;
virtual void onReject();
@@ -76,7 +77,8 @@ protected:
typedef QList ListOfWidgets;
SMESH::SMESH_Hypothesis_var hypothesis() const;
- SMESH::SMESH_Hypothesis_var initParamsHypothesis() const;
+ SMESH::SMESH_Hypothesis_var initParamsHypothesis(const bool strict=false) const;
+ bool hasInitParamsHypothesis() const;
const ListOfWidgets& widgets() const;
ListOfWidgets& changeWidgets();
QtxDialog* dlg() const;
@@ -92,6 +94,7 @@ protected:
virtual QWidget* getCustomWidget( const StdParam&,
QWidget*, const int ) const;
virtual bool getParamFromCustomWidget( StdParam&, QWidget* ) const;
+ virtual void valueChanged( QWidget* );
virtual QString caption() const;
virtual QPixmap icon() const;
virtual QString type() const;
diff --git a/src/SMESHGUI/SMESHGUI_MeshOp.cxx b/src/SMESHGUI/SMESHGUI_MeshOp.cxx
index d51170140..ec08a297e 100644
--- a/src/SMESHGUI/SMESHGUI_MeshOp.cxx
+++ b/src/SMESHGUI/SMESHGUI_MeshOp.cxx
@@ -894,13 +894,14 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType,
!myIsMesh :
myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ).count(':') > nbColonsInMeshEntry;
+ // get mesh and geom object
+ SMESH::SMESH_Mesh_var aMeshVar = SMESH::SMESH_Mesh::_nil();
+ GEOM::GEOM_Object_var aGeomVar = GEOM::GEOM_Object::_nil();
+
+ QString anEntry;
if ( isSubMesh )
{
- // get mesh and geom object
- SMESH::SMESH_Mesh_var aMeshVar = SMESH::SMESH_Mesh::_nil();
- GEOM::GEOM_Object_var aGeomVar = GEOM::GEOM_Object::_nil();
-
- QString anEntry = myDlg->selectedObject
+ anEntry = myDlg->selectedObject
( myToCreate ? SMESHGUI_MeshDlg::Mesh : SMESHGUI_MeshDlg::Obj );
if ( _PTR(SObject) pObj = studyDS()->FindObjectID( anEntry.toLatin1().data() ))
{
@@ -921,13 +922,35 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType,
}
}
}
-
- if ( !aMeshVar->_is_nil() && !aGeomVar->_is_nil() )
- return SMESHGUI::GetSMESHGen()->GetHypothesisParameterValues( aHypType.toLatin1().data(),
- aServerLib.toLatin1().data(),
- aMeshVar,
- aGeomVar );
}
+ else // mesh
+ {
+ if ( !myToCreate ) // mesh to edit can be selected
+ {
+ anEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
+ if ( _PTR(SObject) pMesh = studyDS()->FindObjectID( anEntry.toLatin1().data() ))
+ {
+ aMeshVar = SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pMesh )->GetObject() );
+ if ( !aMeshVar->_is_nil() )
+ aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pMesh );
+ }
+ }
+ if ( aGeomVar->_is_nil() ) {
+ anEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
+ if ( _PTR(SObject) pGeom = studyDS()->FindObjectID( anEntry.toLatin1().data() ))
+ {
+ aGeomVar= GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() );
+ }
+ }
+ }
+
+ if ( (!isSubMesh || !aMeshVar->_is_nil()) && !aGeomVar->_is_nil() )
+ return SMESHGUI::GetSMESHGen()->GetHypothesisParameterValues( aHypType.toLatin1().data(),
+ aServerLib.toLatin1().data(),
+ aMeshVar,
+ aGeomVar,
+ /*byMesh = */isSubMesh);
+
return SMESH::SMESH_Hypothesis::_nil();
}
@@ -1039,8 +1062,7 @@ void SMESHGUI_MeshOp::createHypothesis (const int theDim,
// Create hypothesis
if (aCreator) {
- // When create or edit a submesh, try to initialize a new hypothesis
- // with values used to mesh a subshape
+ // Get parameters appropriate to initialize a new hypothesis
SMESH::SMESH_Hypothesis_var initParamHyp =
getInitParamsHypothesis(theTypeName, aData->ServerLibName);
myDlg->setEnabled( false );
@@ -1089,7 +1111,11 @@ void SMESHGUI_MeshOp::onEditHyp( const int theHypType, const int theIndex )
SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator( aHyp->GetName() );
if ( aCreator ) {
+ // Get initial parameters
+ SMESH::SMESH_Hypothesis_var initParamHyp =
+ getInitParamsHypothesis( aHyp->GetName(), aHyp->GetLibName());
myDlg->setEnabled( false );
+ aCreator->setInitParamsHypothesis( initParamHyp );
aCreator->edit( aHyp.in(), aHypItem.second, dlg() );
myDlg->setEnabled( true );
}
@@ -1497,6 +1523,9 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess )
// create sub-mesh
SMESH::SMESH_subMesh_var aSubMeshVar = aMeshVar->GetSubMesh( aGeomVar, aName.toLatin1().data() );
+ _PTR(SObject) aSubMeshSO = SMESH::FindSObject( aSubMeshVar.in() );
+ if ( aSubMeshSO )
+ SMESH::SetName( aSubMeshSO, aName.toLatin1().data() );
for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ )
{
diff --git a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx
index 6744fc747..a6d44e57a 100644
--- a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx
+++ b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx
@@ -314,7 +314,7 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI*
myTitleBoldCheck->setChecked ( f.bold() );
myTitleItalicCheck->setChecked( f.italic() );
- myTitleShadowCheck->setChecked( f.underline() );
+ myTitleShadowCheck->setChecked( f.overline() );
}
QColor labelColor = mgr->colorValue("SMESH", "scalar_bar_label_color",
@@ -332,7 +332,7 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI*
myLabelsBoldCheck ->setChecked( f.bold() );
myLabelsItalicCheck->setChecked( f.italic() );
- myLabelsShadowCheck->setChecked( f.underline() );
+ myLabelsShadowCheck->setChecked( f.overline() );
}
int aNbColors = mgr->integerValue("SMESH", "scalar_bar_num_colors", 64);
diff --git a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx
index 3a9a9ca46..118d2d17c 100644
--- a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx
+++ b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx
@@ -31,6 +31,7 @@
#include "SMESHGUI_VTKUtils.h"
#include "SMESHGUI_MeshUtils.h"
#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_FilterDlg.h"
#include
#include
@@ -81,7 +82,8 @@ SMESHGUI_RemoveElementsDlg
mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
mySMESHGUI(theModule),
- myBusy(false)
+ myBusy(false),
+ myFilterDlg(0)
{
setModal( false );
setAttribute( Qt::WA_DeleteOnClose, true );
@@ -120,10 +122,13 @@ SMESHGUI_RemoveElementsDlg
SelectButtonC1A1->setIcon(image1);
LineEditC1A1 = new QLineEdit(GroupC1);
LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this));
+ QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupC1 );
+ connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
GroupC1Layout->addWidget(TextLabelC1A1);
GroupC1Layout->addWidget(SelectButtonC1A1);
GroupC1Layout->addWidget(LineEditC1A1);
+ GroupC1Layout->addWidget(filterBtn );
/***************************************************************/
GroupButtons = new QGroupBox(this);
@@ -165,6 +170,11 @@ SMESHGUI_RemoveElementsDlg
//=================================================================================
SMESHGUI_RemoveElementsDlg::~SMESHGUI_RemoveElementsDlg()
{
+ if ( myFilterDlg ) {
+ myFilterDlg->setParent( 0 );
+ delete myFilterDlg;
+ myFilterDlg = 0;
+ }
}
//=================================================================================
@@ -253,10 +263,13 @@ void SMESHGUI_RemoveElementsDlg::ClickOnOk()
//=================================================================================
void SMESHGUI_RemoveElementsDlg::ClickOnCancel()
{
+ if (SMESH::GetCurrentVtkView())
+ SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
//mySelectionMgr->clearSelected();
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(ActorSelection);
disconnect(mySelectionMgr, 0, this, 0);
+ mySelectionMgr->clearFilters();
mySMESHGUI->ResetState();
reject();
}
@@ -487,3 +500,19 @@ void SMESHGUI_RemoveElementsDlg::keyPressEvent( QKeyEvent* e )
ClickOnHelp();
}
}
+
+//=================================================================================
+// function : setFilters()
+// purpose : SLOT. Called when "Filter" button pressed.
+//=================================================================================
+void SMESHGUI_RemoveElementsDlg::setFilters()
+{
+ if ( !myFilterDlg )
+ myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
+
+ myFilterDlg->SetSelection();
+ myFilterDlg->SetMesh( myMesh );
+ myFilterDlg->SetSourceWg( LineEditC1A1 );
+
+ myFilterDlg->show();
+}
diff --git a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.h b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.h
index e8797937b..7138acfe5 100644
--- a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.h
+++ b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.h
@@ -43,6 +43,7 @@ class QPushButton;
class QRadioButton;
class SMESHGUI;
+class SMESHGUI_FilterDlg;
class SMESH_Actor;
class SVTK_Selector;
class LightApp_SelectionMgr;
@@ -92,6 +93,8 @@ private:
QString myHelpFileName;
+ SMESHGUI_FilterDlg* myFilterDlg;
+
private slots:
void ClickOnOk();
void ClickOnCancel();
@@ -102,6 +105,7 @@ private slots:
void DeactivateActiveDialog();
void ActivateThisDialog();
void onTextChange( const QString& );
+ void setFilters();
};
#endif // SMESHGUI_REMOVEELEMENTSDLG_H
diff --git a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx
index 796f8be07..bf218290a 100644
--- a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx
+++ b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx
@@ -31,6 +31,7 @@
#include "SMESHGUI_VTKUtils.h"
#include "SMESHGUI_MeshUtils.h"
#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_FilterDlg.h"
#include
#include
@@ -81,7 +82,8 @@ SMESHGUI_RemoveNodesDlg
mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
mySMESHGUI(theModule),
- myBusy(false)
+ myBusy(false),
+ myFilterDlg(0)
{
setModal( false );
setAttribute( Qt::WA_DeleteOnClose, true );
@@ -120,10 +122,13 @@ SMESHGUI_RemoveNodesDlg
SelectButtonC1A1->setIcon(image1);
LineEditC1A1 = new QLineEdit(GroupC1);
LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this));
+ QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupC1 );
+ connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
GroupC1Layout->addWidget(TextLabelC1A1);
GroupC1Layout->addWidget(SelectButtonC1A1);
GroupC1Layout->addWidget(LineEditC1A1);
+ GroupC1Layout->addWidget(filterBtn );
/***************************************************************/
GroupButtons = new QGroupBox(this);
@@ -165,6 +170,11 @@ SMESHGUI_RemoveNodesDlg
//=================================================================================
SMESHGUI_RemoveNodesDlg::~SMESHGUI_RemoveNodesDlg()
{
+ if ( myFilterDlg ) {
+ myFilterDlg->setParent( 0 );
+ delete myFilterDlg;
+ myFilterDlg = 0;
+ }
}
//=================================================================================
@@ -258,10 +268,14 @@ void SMESHGUI_RemoveNodesDlg::ClickOnOk()
void SMESHGUI_RemoveNodesDlg::ClickOnCancel()
{
//mySelectionMgr->clearSelected();
- SMESH::SetPointRepresentation(false);
+ if (SMESH::GetCurrentVtkView()) {
+ SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
+ SMESH::SetPointRepresentation(false);
+ }
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(ActorSelection);
disconnect(mySelectionMgr, 0, this, 0);
+ mySelectionMgr->clearFilters();
mySMESHGUI->ResetState();
reject();
}
@@ -493,3 +507,19 @@ void SMESHGUI_RemoveNodesDlg::keyPressEvent( QKeyEvent* e )
ClickOnHelp();
}
}
+
+//=================================================================================
+// function : setFilters()
+// purpose : SLOT. Called when "Filter" button pressed.
+//=================================================================================
+void SMESHGUI_RemoveNodesDlg::setFilters()
+{
+ if ( !myFilterDlg )
+ myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::NODE );
+
+ myFilterDlg->SetSelection();
+ myFilterDlg->SetMesh( myMesh );
+ myFilterDlg->SetSourceWg( LineEditC1A1 );
+
+ myFilterDlg->show();
+}
diff --git a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.h b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.h
index 90550b2da..e26e963d3 100644
--- a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.h
+++ b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.h
@@ -43,6 +43,7 @@ class QPushButton;
class QRadioButton;
class SMESHGUI;
+class SMESHGUI_FilterDlg;
class SMESH_Actor;
class SVTK_Selector;
class LightApp_SelectionMgr;
@@ -91,6 +92,8 @@ private:
QLineEdit* LineEditC1A1;
QString myHelpFileName;
+
+ SMESHGUI_FilterDlg* myFilterDlg;
private slots:
void ClickOnOk();
@@ -102,6 +105,7 @@ private slots:
void DeactivateActiveDialog();
void ActivateThisDialog();
void onTextChange( const QString& );
+ void setFilters();
};
#endif // SMESHGUI_REMOVENODESDLG_H
diff --git a/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx b/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx
index bcddfdede..15119eca4 100644
--- a/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx
+++ b/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx
@@ -33,6 +33,7 @@
#include "SMESHGUI_MeshUtils.h"
#include "SMESHGUI_IdValidator.h"
#include "SMESHGUI_MeshEditPreview.h"
+#include "SMESHGUI_FilterDlg.h"
#include
#include
@@ -72,6 +73,7 @@
#include
#include
#include
+#include
// IDL includes
#include
@@ -88,7 +90,9 @@
SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
: QDialog( SMESH::GetDesktop( theModule ) ),
mySMESHGUI( theModule ),
- mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
+ mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+ myVectorDefinition(NONE_SELECT),
+ myFilterDlg( 0 )
{
mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( mySMESHGUI ));
@@ -139,6 +143,8 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator);
+ QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+ connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
// Control for the whole mesh selection
CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
@@ -231,13 +237,14 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0);
GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
GroupArgumentsLayout->addWidget(LineEditElements, 0, 2);
- GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 3);
- GroupArgumentsLayout->addWidget(GroupAxis, 2, 0, 1, 3);
- GroupArgumentsLayout->addWidget(GroupAngleBox, 3, 0, 1, 3);
+ GroupArgumentsLayout->addWidget(filterBtn, 0, 3);
+ GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 4);
+ GroupArgumentsLayout->addWidget(GroupAxis, 2, 0, 1, 4);
+ GroupArgumentsLayout->addWidget(GroupAngleBox, 3, 0, 1, 4);
GroupArgumentsLayout->addWidget(TextLabelTolerance, 4, 0, 1, 2);
- GroupArgumentsLayout->addWidget(SpinBox_Tolerance, 4, 2);
- GroupArgumentsLayout->addWidget(CheckBoxPreview, 5, 0, 1, 3);
- GroupArgumentsLayout->addWidget(MakeGroupsCheck, 6, 0, 1, 3);
+ GroupArgumentsLayout->addWidget(SpinBox_Tolerance, 4, 2, 1, 2);
+ GroupArgumentsLayout->addWidget(CheckBoxPreview, 5, 0, 1, 4);
+ GroupArgumentsLayout->addWidget(MakeGroupsCheck, 6, 0, 1, 4);
/***************************************************************/
GroupButtons = new QGroupBox(this);
@@ -305,6 +312,12 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
Init();
+ /*Create menu to vector selection*/
+ SelectVectorMenu = new QMenu(this);
+ myMenuActions[SelectVectorMenu->addAction( tr( "MEN_POINT_SELECT" ) )] = POINT_SELECT;
+ myMenuActions[SelectVectorMenu->addAction( tr( "MEN_FACE_SELECT" ) )] = FACE_SELECT;
+ connect( SelectVectorMenu, SIGNAL( triggered( QAction* ) ), SLOT( onSelectVectorMenu( QAction* ) ) );
+
/* signals and slots connections */
connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()));
connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
@@ -314,7 +327,7 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
connect(SelectElementsButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
connect(SelectPointButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
- connect(SelectVectorButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
+ connect(SelectVectorButton, SIGNAL(clicked()), this, SLOT(onSelectVectorButton()));
connect(SpinBox_X, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
connect(SpinBox_Y, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
@@ -348,6 +361,11 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
SMESHGUI_RevolutionDlg::~SMESHGUI_RevolutionDlg()
{
delete mySimulation;
+ if ( myFilterDlg ) {
+ myFilterDlg->setParent( 0 );
+ delete myFilterDlg;
+ myFilterDlg = 0;
+ }
}
//=================================================================================
@@ -515,7 +533,10 @@ void SMESHGUI_RevolutionDlg::ClickOnCancel()
disconnect(mySelectionMgr, 0, this, 0);
mySelectionMgr->clearFilters();
//mySelectionMgr->clearSelected();
- SMESH::SetPointRepresentation(false);
+ if (SMESH::GetCurrentVtkView()) {
+ SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
+ SMESH::SetPointRepresentation(false);
+ }
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(ActorSelection);
mySMESHGUI->ResetState();
@@ -729,30 +750,57 @@ void SMESHGUI_RevolutionDlg::SelectionIntoArgument()
myNbOkElements = true;
} else {
- aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
- if (aNbUnits != 1)
- return;
SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
if (!aMesh)
return;
- const SMDS_MeshNode * n = aMesh->FindNode(aString.toInt());
- if (!n)
+ bool isNodeSelected = (myEditCurrentArgument == (QWidget*)SpinBox_X ||
+ (myEditCurrentArgument == (QWidget*)SpinBox_DX &&
+ myVectorDefinition==POINT_SELECT));
+
+ bool isFaceSelected = (myEditCurrentArgument == (QWidget*)SpinBox_DX &&
+ myVectorDefinition==FACE_SELECT);
+
+ if(isNodeSelected) {
+ aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
+ }
+ else if(isFaceSelected){
+ aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
+ }
+
+ if (aNbUnits != 1)
return;
- double x = n->X();
- double y = n->Y();
- double z = n->Z();
+ if(isNodeSelected) {
+ const SMDS_MeshNode * n = aMesh->FindNode(aString.toInt());
+ if (!n)
+ return;
- if (myEditCurrentArgument == (QWidget*)SpinBox_X) {
- SpinBox_X->SetValue(x);
- SpinBox_Y->SetValue(y);
- SpinBox_Z->SetValue(z);
- } else if (myEditCurrentArgument == (QWidget*)SpinBox_DX) {
- SpinBox_DX->SetValue(x - SpinBox_X->GetValue());
- SpinBox_DY->SetValue(y - SpinBox_Y->GetValue());
- SpinBox_DZ->SetValue(z - SpinBox_Z->GetValue());
+ double x = n->X();
+ double y = n->Y();
+ double z = n->Z();
+
+ if (myEditCurrentArgument == (QWidget*)SpinBox_X) {
+ SpinBox_X->SetValue(x);
+ SpinBox_Y->SetValue(y);
+ SpinBox_Z->SetValue(z);
+ } else if (myEditCurrentArgument == (QWidget*)SpinBox_DX) {
+ SpinBox_DX->SetValue(x - SpinBox_X->GetValue());
+ SpinBox_DY->SetValue(y - SpinBox_Y->GetValue());
+ SpinBox_DZ->SetValue(z - SpinBox_Z->GetValue());
+ }
+ }
+ else if(isFaceSelected){
+ const SMDS_MeshFace* face = dynamic_cast(aMesh->FindElement(aString.toInt()));
+ if (!face)
+ return;
+
+ gp_XYZ aNormale = SMESH::getNormale(face);
+ SpinBox_DX->SetValue(aNormale.X());
+ SpinBox_DY->SetValue(aNormale.Y());
+ SpinBox_DZ->SetValue(aNormale.Z());
+
}
}
@@ -808,12 +856,6 @@ void SMESHGUI_RevolutionDlg::SetEditCurrentArgument()
SMESH::SetPointRepresentation(true);
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(NodeSelection);
- } else if (send == SelectVectorButton) {
- myEditCurrentArgument = (QWidget*)SpinBox_DX;
- SMESH::SetPointRepresentation(true);
- if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
- aViewWindow->SetSelectionMode(NodeSelection);
- } else {
}
myEditCurrentArgument->setFocus();
@@ -1051,3 +1093,64 @@ void SMESHGUI_RevolutionDlg::onDisplaySimulation(bool toDisplayPreview)
mySimulation->SetVisibility(false);
}
}
+
+//=================================================================================
+// function : onSelectVectorButton()
+// purpose : [slot]
+//=================================================================================
+void SMESHGUI_RevolutionDlg::onSelectVectorButton(){
+ if(SelectVectorMenu) {
+ SelectVectorMenu->exec( QCursor::pos() );
+ }
+}
+
+//=================================================================================
+// function : onSelectVectorMenu()
+// purpose : [slot]
+//=================================================================================
+void SMESHGUI_RevolutionDlg::onSelectVectorMenu( QAction* action){
+ if(!action)
+ return;
+
+ switch(myMenuActions[action]) {
+ case POINT_SELECT:
+ SMESH::SetPointRepresentation(true);
+ if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+ aViewWindow->SetSelectionMode(NodeSelection);
+ break;
+
+ case FACE_SELECT:
+ SMESH::SetPointRepresentation(false);
+ if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+ aViewWindow->SetSelectionMode(FaceSelection);
+ break;
+ }
+
+ myVectorDefinition = myMenuActions[action];
+ myEditCurrentArgument = (QWidget*)SpinBox_DX;
+ myEditCurrentArgument->setFocus();
+ connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+ SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : setFilters()
+// purpose : SLOT. Called when "Filter" button pressed.
+//=================================================================================
+void SMESHGUI_RevolutionDlg::setFilters()
+{
+ if ( !myFilterDlg )
+ {
+ QList types;
+ types.append( SMESH::EDGE );
+ types.append( SMESH::FACE );
+ myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, types );
+ }
+ myFilterDlg->Init( GetConstructorId() ? SMESH::FACE : SMESH::EDGE );
+
+ myFilterDlg->SetSelection();
+ myFilterDlg->SetMesh( myMesh );
+ myFilterDlg->SetSourceWg( LineEditElements );
+
+ myFilterDlg->show();
+}
diff --git a/src/SMESHGUI/SMESHGUI_RevolutionDlg.h b/src/SMESHGUI/SMESHGUI_RevolutionDlg.h
index ecd9a3bfd..3502596f1 100644
--- a/src/SMESHGUI/SMESHGUI_RevolutionDlg.h
+++ b/src/SMESHGUI/SMESHGUI_RevolutionDlg.h
@@ -31,6 +31,7 @@
// Qt includes
#include
+#include
// IDL includes
#include
@@ -47,12 +48,15 @@ class QSpinBox;
class SMESHGUI_IdValidator;
class SMESHGUI_SpinBox;
class SMESHGUI;
+class SMESHGUI_FilterDlg;
class SMESH_Actor;
class SVTK_Selector;
class LightApp_SelectionMgr;
class SMESH_LogicalFilter;
class SALOME_Actor;
class SMESHGUI_MeshEditPreview;
+class QMenu;
+class QAction;
//=================================================================================
// class : SMESHGUI_RevolutionDlg
@@ -67,6 +71,8 @@ public:
~SMESHGUI_RevolutionDlg();
private:
+ enum {NONE_SELECT, POINT_SELECT, FACE_SELECT};
+
void Init( bool = true);
void closeEvent( QCloseEvent* );
void enterEvent( QEvent* ); /* mouse enter the QWidget */
@@ -135,9 +141,16 @@ private:
QSpinBox* SpinBox_NbSteps;
QLabel* TextLabelTolerance;
SMESHGUI_SpinBox* SpinBox_Tolerance;
+
+ QMenu* SelectVectorMenu;
+ QMap myMenuActions;
+ int myVectorDefinition;
+
QString myHelpFileName;
+ SMESHGUI_FilterDlg* myFilterDlg;
+
private slots:
void ConstructorsClicked( int );
void ClickOnOk();
@@ -153,6 +166,9 @@ private slots:
void onVectorChanged();
void toDisplaySimulation();
void onDisplaySimulation( bool );
+ void onSelectVectorMenu( QAction* );
+ void onSelectVectorButton();
+ void setFilters();
};
#endif // SMESHGUI_REVOLUTIONDLG_H
diff --git a/src/SMESHGUI/SMESHGUI_RotationDlg.cxx b/src/SMESHGUI/SMESHGUI_RotationDlg.cxx
index 09ee60688..a2f5460f5 100644
--- a/src/SMESHGUI/SMESHGUI_RotationDlg.cxx
+++ b/src/SMESHGUI/SMESHGUI_RotationDlg.cxx
@@ -32,6 +32,7 @@
#include "SMESHGUI_VTKUtils.h"
#include "SMESHGUI_MeshUtils.h"
#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_FilterDlg.h"
#include
#include
@@ -89,7 +90,8 @@ enum { MOVE_ELEMS_BUTTON = 0, COPY_ELEMS_BUTTON, MAKE_MESH_BUTTON }; //!< action
SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule )
: QDialog( SMESH::GetDesktop( theModule ) ),
mySMESHGUI( theModule ),
- mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
+ mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+ myFilterDlg(0)
{
QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_MESH_ROTATION")));
QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
@@ -130,6 +132,8 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule )
SelectElementsButton->setIcon(image1);
LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator);
+ QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+ connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
// Control for the whole mesh selection
CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
@@ -209,7 +213,8 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule )
GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0);
GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
- GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 2);
+ GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 1);
+ GroupArgumentsLayout->addWidget(filterBtn, 0, 3);
GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 4);
GroupArgumentsLayout->addWidget(GroupAxis, 2, 0, 1, 4);
GroupArgumentsLayout->addWidget(TextLabelAngle, 3, 0, 1, 2);
@@ -310,6 +315,11 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule )
//=================================================================================
SMESHGUI_RotationDlg::~SMESHGUI_RotationDlg()
{
+ if ( myFilterDlg ) {
+ myFilterDlg->setParent( 0 );
+ delete myFilterDlg;
+ myFilterDlg = 0;
+ }
}
//=================================================================================
@@ -431,7 +441,10 @@ void SMESHGUI_RotationDlg::ClickOnCancel()
disconnect(mySelectionMgr, 0, this, 0);
mySelectionMgr->clearFilters();
//mySelectionMgr->clearSelected();
- SMESH::SetPointRepresentation(false);
+ if (SMESH::GetCurrentVtkView()) {
+ SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
+ SMESH::SetPointRepresentation(false);
+ }
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(ActorSelection);
mySMESHGUI->ResetState();
@@ -909,3 +922,19 @@ void SMESHGUI_RotationDlg::keyPressEvent( QKeyEvent* e )
ClickOnHelp();
}
}
+
+//=================================================================================
+// function : setFilters()
+// purpose : SLOT. Called when "Filter" button pressed.
+//=================================================================================
+void SMESHGUI_RotationDlg::setFilters()
+{
+ if ( !myFilterDlg )
+ myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
+
+ myFilterDlg->SetSelection();
+ myFilterDlg->SetMesh( myMesh );
+ myFilterDlg->SetSourceWg( LineEditElements );
+
+ myFilterDlg->show();
+}
diff --git a/src/SMESHGUI/SMESHGUI_RotationDlg.h b/src/SMESHGUI/SMESHGUI_RotationDlg.h
index eefe467f2..de192b80b 100644
--- a/src/SMESHGUI/SMESHGUI_RotationDlg.h
+++ b/src/SMESHGUI/SMESHGUI_RotationDlg.h
@@ -47,6 +47,7 @@ class SMESHGUI;
class SMESH_Actor;
class SMESHGUI_IdValidator;
class SMESHGUI_SpinBox;
+class SMESHGUI_FilterDlg;
class SVTK_Selector;
class LightApp_SelectionMgr;
class SMESH_LogicalFilter;
@@ -127,6 +128,8 @@ private:
QString myHelpFileName;
+ SMESHGUI_FilterDlg* myFilterDlg;
+
private slots:
void ClickOnOk();
void ClickOnCancel();
@@ -140,6 +143,7 @@ private slots:
void onSelectMesh( bool );
void onVectorChanged();
void onActionClicked( int );
+ void setFilters();
};
#endif // SMESHGUI_ROTATIONDLG_H
diff --git a/src/SMESHGUI/SMESHGUI_Selection.cxx b/src/SMESHGUI/SMESHGUI_Selection.cxx
index e7686db20..e0e63d4cc 100644
--- a/src/SMESHGUI/SMESHGUI_Selection.cxx
+++ b/src/SMESHGUI/SMESHGUI_Selection.cxx
@@ -116,6 +116,7 @@ QVariant SMESHGUI_Selection::parameter( const int ind, const QString& p ) const
else if ( p=="hasReference" ) val = QVariant( hasReference( ind ) );
else if ( p=="isImported" ) val = QVariant( isImported( ind ) );
else if ( p=="facesOrientationMode" ) val = QVariant( facesOrientationMode( ind ) );
+ else if ( p=="groupType" ) val = QVariant( groupType( ind ) );
if( val.isValid() )
return val;
@@ -239,6 +240,7 @@ QString SMESHGUI_Selection::controlMode( int ind ) const
case SMESH_Actor::eLength2D: return "eLength2D";
case SMESH_Actor::eFreeEdges: return "eFreeEdges";
case SMESH_Actor::eFreeBorders: return "eFreeBorders";
+ case SMESH_Actor::eFreeFaces: return "eFreeFaces";
case SMESH_Actor::eMultiConnection: return "eMultiConnection";
case SMESH_Actor::eMultiConnection2D: return "eMultiConnection2D";
case SMESH_Actor::eArea: return "eArea";
@@ -523,3 +525,27 @@ bool SMESHGUI_Selection::isImported( const int ind ) const
*/
return res;
}
+
+//=======================================================================
+//function : groupType
+//purpose :
+//=======================================================================
+
+QString SMESHGUI_Selection::groupType( int ind ) const
+{
+ QString e = entry( ind );
+ _PTR(SObject) SO = SMESH::GetActiveStudyDocument()->FindObjectID( e.toLatin1().constData() );
+ QString type;
+ if( SO )
+ {
+ CORBA::Object_var obj = SMESH::SObjectToObject( SO );
+
+ SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( obj );
+ SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow( obj );
+ if( !aGroup->_is_nil() )
+ type = QString( "Group" );
+ else if ( !aGroupOnGeom->_is_nil() )
+ type = QString( "GroupOnGeom" );
+ }
+ return type;
+}
diff --git a/src/SMESHGUI/SMESHGUI_Selection.h b/src/SMESHGUI/SMESHGUI_Selection.h
index 8822b65fc..72ed58cb4 100644
--- a/src/SMESHGUI/SMESHGUI_Selection.h
+++ b/src/SMESHGUI/SMESHGUI_Selection.h
@@ -65,6 +65,7 @@ public:
virtual QList entityMode( int ) const;
virtual QString controlMode( int ) const;
virtual QString facesOrientationMode( int ) const;
+ virtual QString groupType( int ) const;
SMESH_Actor* getActor( int ) const;
diff --git a/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx b/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx
index 9ff91bc15..e38bf7713 100644
--- a/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx
+++ b/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx
@@ -32,6 +32,7 @@
#include "SMESHGUI_MeshUtils.h"
#include "SMESHGUI_SpinBox.h"
#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_FilterDlg.h"
#include
#include
@@ -89,7 +90,8 @@
SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule )
: QDialog( SMESH::GetDesktop( theModule ) ),
mySMESHGUI( theModule ),
- mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
+ mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+ myFilterDlg(0)
{
QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_SMOOTHING")));
QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
@@ -133,6 +135,8 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule )
LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator);
+ QPushButton* filterElemBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+ connect(filterElemBtn, SIGNAL(clicked()), this, SLOT(setElemFilters()));
// Control for the whole mesh selection
CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
@@ -145,6 +149,8 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule )
LineEditNodes = new QLineEdit(GroupArguments);
LineEditNodes->setValidator(myIdValidator);
+ QPushButton* filterNodeBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+ connect(filterNodeBtn, SIGNAL(clicked()), this, SLOT(setNodeFilters()));
// Controls for method selection
TextLabelMethod = new QLabel(tr("METHOD"), GroupArguments);
@@ -167,17 +173,19 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule )
GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0);
GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
GroupArgumentsLayout->addWidget(LineEditElements, 0, 2);
- GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 3);
+ GroupArgumentsLayout->addWidget(filterElemBtn, 0, 3);
+ GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 4);
GroupArgumentsLayout->addWidget(TextLabelNodes, 2, 0);
GroupArgumentsLayout->addWidget(SelectNodesButton, 2, 1);
GroupArgumentsLayout->addWidget(LineEditNodes, 2, 2);
+ GroupArgumentsLayout->addWidget(filterNodeBtn, 2, 3);
GroupArgumentsLayout->addWidget(TextLabelMethod, 3, 0);
- GroupArgumentsLayout->addWidget(ComboBoxMethod, 3, 2);
+ GroupArgumentsLayout->addWidget(ComboBoxMethod, 3, 2, 1, 2);
GroupArgumentsLayout->addWidget(TextLabelLimit, 4, 0);
- GroupArgumentsLayout->addWidget(SpinBox_IterationLimit, 4, 2);
+ GroupArgumentsLayout->addWidget(SpinBox_IterationLimit, 4, 2, 1, 2);
GroupArgumentsLayout->addWidget(TextLabelAspectRatio, 5, 0);
- GroupArgumentsLayout->addWidget(SpinBox_AspectRatio, 5, 2);
- GroupArgumentsLayout->addWidget(CheckBoxParametric, 6, 0, 1, 3);
+ GroupArgumentsLayout->addWidget(SpinBox_AspectRatio, 5, 2, 1, 2);
+ GroupArgumentsLayout->addWidget(CheckBoxParametric, 6, 0, 1, 4);
/***************************************************************/
GroupButtons = new QGroupBox(this);
@@ -273,6 +281,10 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule )
SMESHGUI_SmoothingDlg::~SMESHGUI_SmoothingDlg()
{
// no need to delete child widgets, Qt does it all for us
+ if ( myFilterDlg != 0 ) {
+ myFilterDlg->setParent( 0 );
+ delete myFilterDlg;
+ }
}
//=================================================================================
@@ -382,8 +394,11 @@ void SMESHGUI_SmoothingDlg::ClickOnCancel()
disconnect(mySelectionMgr, 0, this, 0);
mySelectionMgr->clearFilters();
//mySelectionMgr->clearSelected();
- SMESH::SetPickable(); // ???
- SMESH::SetPointRepresentation(false);
+ if (SMESH::GetCurrentVtkView()) {
+ SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
+ SMESH::SetPointRepresentation(false);
+ SMESH::SetPickable();
+ }
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(ActorSelection);
mySMESHGUI->ResetState();
@@ -494,9 +509,13 @@ void SMESHGUI_SmoothingDlg::SelectionIntoArgument()
QString aString = "";
myBusy = true;
- if (myEditCurrentArgument == (QWidget*)LineEditElements) {
- LineEditElements->setText(aString);
- myNbOkElements = 0;
+ if (myEditCurrentArgument == LineEditElements ||
+ myEditCurrentArgument == LineEditNodes) {
+ myEditCurrentArgument->setText(aString);
+ if (myEditCurrentArgument == LineEditElements)
+ myNbOkElements = 0;
+ else
+ myNbOkNodes = 0;
buttonOk->setEnabled(false);
buttonApply->setEnabled(false);
myActor = 0;
@@ -591,9 +610,9 @@ void SMESHGUI_SmoothingDlg::SelectionIntoArgument()
// OK
if (myEditCurrentArgument == LineEditElements)
- myNbOkElements = true;
+ myNbOkElements = aNbUnits;
else if (myEditCurrentArgument == LineEditNodes)
- myNbOkNodes = true;
+ myNbOkNodes = aNbUnits;
if (myNbOkElements && (myNbOkNodes || LineEditNodes->text().trimmed().isEmpty())) {
buttonOk->setEnabled(true);
@@ -719,8 +738,10 @@ void SMESHGUI_SmoothingDlg::onSelectMesh (bool toSelectMesh)
else
TextLabelElements->setText(tr("SMESH_ID_ELEMENTS"));
- if (myEditCurrentArgument != LineEditElements) {
+ if (myEditCurrentArgument != LineEditElements &&
+ myEditCurrentArgument != LineEditNodes) {
LineEditElements->clear();
+ LineEditNodes->clear();
return;
}
@@ -732,14 +753,15 @@ void SMESHGUI_SmoothingDlg::onSelectMesh (bool toSelectMesh)
aViewWindow->SetSelectionMode(ActorSelection);
// mySelectionMgr->setSelectionModes(ActorSelection);
mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
- LineEditElements->setReadOnly(true);
- LineEditElements->setValidator(0);
+ myEditCurrentArgument->setReadOnly(true);
+ myEditCurrentArgument->setValidator(0);
} else {
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
- aViewWindow->SetSelectionMode(FaceSelection);
- LineEditElements->setReadOnly(false);
+ aViewWindow->SetSelectionMode(myEditCurrentArgument == LineEditElements ? FaceSelection
+ : NodeSelection );
+ myEditCurrentArgument->setReadOnly(false);
LineEditElements->setValidator(myIdValidator);
- onTextChange(LineEditElements->text());
+ onTextChange(myEditCurrentArgument->text());
}
SelectionIntoArgument();
@@ -760,3 +782,43 @@ void SMESHGUI_SmoothingDlg::keyPressEvent( QKeyEvent* e )
ClickOnHelp();
}
}
+
+//=================================================================================
+// function : setFilters()
+// purpose : activate filter dialog
+//=================================================================================
+void SMESHGUI_SmoothingDlg::setFilters( const bool theIsElem )
+{
+ if ( !myFilterDlg )
+ {
+ QList types;
+ types.append( SMESH::NODE );
+ types.append( SMESH::ALL );
+ myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, types );
+ }
+ myFilterDlg->Init( theIsElem ? SMESH::ALL : SMESH::NODE );
+
+ myFilterDlg->SetSelection();
+ myFilterDlg->SetMesh( myMesh );
+ myFilterDlg->SetSourceWg( theIsElem ? LineEditElements : LineEditNodes );
+
+ myFilterDlg->show();
+}
+
+//=================================================================================
+// function : setElemFilters()
+// purpose : SLOT. Called when element "Filter" button pressed.
+//=================================================================================
+void SMESHGUI_SmoothingDlg::setElemFilters()
+{
+ setFilters( true );
+}
+
+//=================================================================================
+// function : setNodeFilters()
+// purpose : SLOT. Called when node "Filter" button pressed.
+//=================================================================================
+void SMESHGUI_SmoothingDlg::setNodeFilters()
+{
+ setFilters( false );
+}
diff --git a/src/SMESHGUI/SMESHGUI_SmoothingDlg.h b/src/SMESHGUI/SMESHGUI_SmoothingDlg.h
index d63bdd88a..c01dfc1c7 100644
--- a/src/SMESHGUI/SMESHGUI_SmoothingDlg.h
+++ b/src/SMESHGUI/SMESHGUI_SmoothingDlg.h
@@ -44,9 +44,10 @@ class QRadioButton;
class QComboBox;
class QCheckBox;
class QSpinBox;
+class SMESHGUI;
class SMESHGUI_IdValidator;
class SMESHGUI_SpinBox;
-class SMESHGUI;
+class SMESHGUI_FilterDlg;
class SMESH_Actor;
class SVTK_Selector;
class LightApp_SelectionMgr;
@@ -70,6 +71,7 @@ private:
void enterEvent( QEvent* ); /* mouse enter the QWidget */
void hideEvent( QHideEvent* ); /* ESC key */
void keyPressEvent( QKeyEvent* );
+ void setFilters( const bool theIsElem );
SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */
SMESHGUI_IdValidator* myIdValidator;
@@ -111,6 +113,8 @@ private:
QString myHelpFileName;
+ SMESHGUI_FilterDlg* myFilterDlg;
+
private slots:
void ClickOnOk();
void ClickOnCancel();
@@ -122,6 +126,8 @@ private slots:
void ActivateThisDialog();
void onTextChange( const QString& );
void onSelectMesh( bool );
+ void setElemFilters();
+ void setNodeFilters();
};
#endif // SMESHGUI_SMOOTHINGDLG_H
diff --git a/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx b/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx
index 2d4559317..7f0c6d0fe 100644
--- a/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx
+++ b/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx
@@ -32,6 +32,7 @@
#include "SMESHGUI_VTKUtils.h"
#include "SMESHGUI_MeshUtils.h"
#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_FilterDlg.h"
#include
#include
@@ -90,7 +91,8 @@ enum { MOVE_ELEMS_BUTTON = 0, COPY_ELEMS_BUTTON, MAKE_MESH_BUTTON }; //!< action
SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule )
: QDialog( SMESH::GetDesktop( theModule ) ),
mySMESHGUI( theModule ),
- mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
+ mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+ myFilterDlg(0)
{
QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SMESH_SYMMETRY_POINT")));
QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SMESH_SYMMETRY_AXIS")));
@@ -141,6 +143,8 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule )
SelectElementsButton->setIcon(image3);
LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator);
+ QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+ connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
// Control for the whole mesh selection
CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
@@ -218,7 +222,8 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule )
// layout
GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0);
GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
- GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 2);
+ GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 1);
+ GroupArgumentsLayout->addWidget(filterBtn, 0, 3);
GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 4);
GroupArgumentsLayout->addWidget(GroupMirror, 2, 0, 1, 4);
GroupArgumentsLayout->addWidget(ActionBox, 3, 0, 3, 3);
@@ -317,6 +322,10 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule )
//=================================================================================
SMESHGUI_SymmetryDlg::~SMESHGUI_SymmetryDlg()
{
+ if ( myFilterDlg != 0 ) {
+ myFilterDlg->setParent( 0 );
+ delete myFilterDlg;
+ }
}
//=================================================================================
@@ -520,7 +529,10 @@ void SMESHGUI_SymmetryDlg::ClickOnCancel()
disconnect(mySelectionMgr, 0, this, 0);
mySelectionMgr->clearFilters();
//mySelectionMgr->clearSelected();
- SMESH::SetPointRepresentation(false);
+ if (SMESH::GetCurrentVtkView()) {
+ SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
+ SMESH::SetPointRepresentation(false);
+ }
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(ActorSelection);
mySMESHGUI->ResetState();
@@ -1007,3 +1019,19 @@ void SMESHGUI_SymmetryDlg::keyPressEvent( QKeyEvent* e )
ClickOnHelp();
}
}
+
+//=================================================================================
+// function : setFilters()
+// purpose : SLOT. Called when "Filter" button pressed.
+//=================================================================================
+void SMESHGUI_SymmetryDlg::setFilters()
+{
+ if ( !myFilterDlg )
+ myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
+
+ myFilterDlg->SetSelection();
+ myFilterDlg->SetMesh( myMesh );
+ myFilterDlg->SetSourceWg( LineEditElements );
+
+ myFilterDlg->show();
+}
diff --git a/src/SMESHGUI/SMESHGUI_SymmetryDlg.h b/src/SMESHGUI/SMESHGUI_SymmetryDlg.h
index ed6b08c9d..fc18a65be 100644
--- a/src/SMESHGUI/SMESHGUI_SymmetryDlg.h
+++ b/src/SMESHGUI/SMESHGUI_SymmetryDlg.h
@@ -43,9 +43,10 @@ class QLineEdit;
class QPushButton;
class QRadioButton;
class QCheckBox;
+class SMESHGUI;
class SMESHGUI_IdValidator;
class SMESHGUI_SpinBox;
-class SMESHGUI;
+class SMESHGUI_FilterDlg;
class SMESH_Actor;
class SVTK_Selector;
class LightApp_SelectionMgr;
@@ -128,6 +129,8 @@ private:
QString myHelpFileName;
+ SMESHGUI_FilterDlg* myFilterDlg;
+
private slots:
void ConstructorsClicked( int );
void ClickOnOk();
@@ -142,6 +145,7 @@ private slots:
void onSelectMesh( bool );
void onVectorChanged();
void onActionClicked( int );
+ void setFilters();
};
#endif // SMESHGUI_SYMMETRYDLG_H
diff --git a/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx b/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx
index eb5ad0eb3..b148a5315 100644
--- a/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx
+++ b/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx
@@ -32,6 +32,7 @@
#include "SMESHGUI_VTKUtils.h"
#include "SMESHGUI_MeshUtils.h"
#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_FilterDlg.h"
#include
#include
@@ -107,7 +108,8 @@ private:
SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule )
: QDialog( SMESH::GetDesktop( theModule ) ),
mySMESHGUI( theModule ),
- mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
+ mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+ myFilterDlg(0)
{
QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SMESH_TRANSLATION_POINTS")));
QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SMESH_TRANSLATION_VECTOR")));
@@ -153,6 +155,8 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule )
SelectElementsButton->setIcon(image2);
LineEditElements = new QLineEdit(GroupArguments);
LineEditElements->setValidator(myIdValidator);
+ QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+ connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
// Control for the whole mesh selection
CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
@@ -208,7 +212,8 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule )
// layout
GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0);
GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
- GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 6);
+ GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 5);
+ GroupArgumentsLayout->addWidget(filterBtn, 0, 7);
GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 8);
GroupArgumentsLayout->addWidget(TextLabel1, 2, 0);
GroupArgumentsLayout->addWidget(SelectButton1, 2, 1);
@@ -318,6 +323,11 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule )
//=================================================================================
SMESHGUI_TranslationDlg::~SMESHGUI_TranslationDlg()
{
+ if ( myFilterDlg ) {
+ myFilterDlg->setParent( 0 );
+ delete myFilterDlg;
+ myFilterDlg = 0;
+ }
}
//=================================================================================
@@ -504,7 +514,10 @@ void SMESHGUI_TranslationDlg::ClickOnCancel()
disconnect(mySelectionMgr, 0, this, 0);
mySelectionMgr->clearFilters();
//mySelectionMgr->clearSelected();
- SMESH::SetPointRepresentation(false);
+ if (SMESH::GetCurrentVtkView()) {
+ SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
+ SMESH::SetPointRepresentation(false);
+ }
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode( ActorSelection );
mySMESHGUI->ResetState();
@@ -957,3 +970,19 @@ void SMESHGUI_TranslationDlg::keyPressEvent( QKeyEvent* e )
ClickOnHelp();
}
}
+
+//=================================================================================
+// function : setFilters()
+// purpose : SLOT. Called when "Filter" button pressed.
+//=================================================================================
+void SMESHGUI_TranslationDlg::setFilters()
+{
+ if ( !myFilterDlg )
+ myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
+
+ myFilterDlg->SetSelection();
+ myFilterDlg->SetMesh( myMesh );
+ myFilterDlg->SetSourceWg( LineEditElements );
+
+ myFilterDlg->show();
+}
diff --git a/src/SMESHGUI/SMESHGUI_TranslationDlg.h b/src/SMESHGUI/SMESHGUI_TranslationDlg.h
index d9324720d..c551faeee 100644
--- a/src/SMESHGUI/SMESHGUI_TranslationDlg.h
+++ b/src/SMESHGUI/SMESHGUI_TranslationDlg.h
@@ -46,6 +46,7 @@ class QCheckBox;
class SMESHGUI;
class SMESHGUI_IdValidator;
class SMESHGUI_SpinBox;
+class SMESHGUI_FilterDlg;
class SMESH_Actor;
class SVTK_Selector;
class LightApp_SelectionMgr;
@@ -124,6 +125,8 @@ private:
QLineEdit* LineEditNewMesh;
QString myHelpFileName;
+
+ SMESHGUI_FilterDlg* myFilterDlg;
private slots:
void ConstructorsClicked( int );
@@ -138,6 +141,7 @@ private slots:
void onTextChange( const QString& );
void onSelectMesh( bool );
void onActionClicked( int );
+ void setFilters();
};
#endif // SMESHGUI_TRANSLATIONDLG_H
diff --git a/src/SMESHGUI/SMESHGUI_Utils.cxx b/src/SMESHGUI/SMESHGUI_Utils.cxx
index 1bfe56991..33eb25b96 100644
--- a/src/SMESHGUI/SMESHGUI_Utils.cxx
+++ b/src/SMESHGUI/SMESHGUI_Utils.cxx
@@ -25,9 +25,11 @@
// SMESH includes
//
#include "SMESHGUI_Utils.h"
-
#include "SMESHGUI.h"
+#include
+#include
+
// SALOME GUI includes
#include
#include
@@ -41,6 +43,10 @@
#include
+// OCC includes
+#include
+#include
+
namespace SMESH
{
SUIT_Desktop*
@@ -131,12 +137,7 @@ namespace SMESH
_PTR(Study) aStudy = GetActiveStudyDocument();
if (aStudy->GetProperties()->IsLocked())
return;
- _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
- _PTR(GenericAttribute) anAttr =
- aBuilder->FindOrCreateAttribute(theSObject, "AttributeName");
- _PTR(AttributeName) aName = anAttr;
- if (aName)
- aName->SetValue(theName.toLatin1().data());
+ SMESHGUI::GetSMESHGen()->SetName(theSObject->GetIOR().c_str(), theName.toLatin1().data());
}
void SetValue (_PTR(SObject) theSObject, const QString& theValue)
@@ -305,4 +306,35 @@ namespace SMESH
arg(theHelpFileName));
}
}
+
+ //=======================================================================
+ /**
+ Return normale to a given face
+ */
+ //=======================================================================
+ gp_XYZ getNormale( const SMDS_MeshFace* theFace )
+ {
+ gp_XYZ n;
+ int aNbNode = theFace->NbNodes();
+ TColgp_Array1OfXYZ anArrOfXYZ(1,4);
+ SMDS_ElemIteratorPtr aNodeItr = theFace->nodesIterator();
+ int i = 1;
+ for ( ; aNodeItr->more() && i <= 4; i++ ) {
+ SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next();
+ anArrOfXYZ.SetValue(i, gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) );
+ }
+
+ gp_XYZ q1 = anArrOfXYZ.Value(2) - anArrOfXYZ.Value(1);
+ gp_XYZ q2 = anArrOfXYZ.Value(3) - anArrOfXYZ.Value(1);
+ n = q1 ^ q2;
+ if ( aNbNode > 3 ) {
+ gp_XYZ q3 = anArrOfXYZ.Value(4) - anArrOfXYZ.Value(1);
+ n += q2 ^ q3;
+ }
+ double len = n.Modulus();
+ if ( len > 0 )
+ n /= len;
+ return n;
+ }
+
} // end of namespace SMESH
diff --git a/src/SMESHGUI/SMESHGUI_Utils.h b/src/SMESHGUI/SMESHGUI_Utils.h
index f534da8f7..77f26e3e1 100644
--- a/src/SMESHGUI/SMESHGUI_Utils.h
+++ b/src/SMESHGUI/SMESHGUI_Utils.h
@@ -39,6 +39,9 @@
#include
#include
+//OCC includes
+#include
+
class SUIT_ViewWindow;
class SUIT_Desktop;
class SUIT_Study;
@@ -53,6 +56,8 @@ class SalomeApp_Study;
class SalomeApp_Module;
class LightApp_SelectionMgr;
+class SMDS_MeshFace;
+
namespace SMESH
{
SMESHGUI_EXPORT
@@ -158,6 +163,15 @@ SMESHGUI_EXPORT
SMESHGUI_EXPORT
void ShowHelpFile( const QString& );
+
+ /*!
+ * \brief Return the normal to a face
+ * \param theFace - input face
+ * \retval gp_XYZ - normal to a face
+ */
+SMESHGUI_EXPORT
+ gp_XYZ getNormale( const SMDS_MeshFace* theFace );
+
}
#endif // SMESHGUI_UTILS_H
diff --git a/src/SMESHGUI/SMESH_images.ts b/src/SMESHGUI/SMESH_images.ts
index 910dea132..0319ce689 100644
--- a/src/SMESHGUI/SMESH_images.ts
+++ b/src/SMESHGUI/SMESH_images.ts
@@ -57,6 +57,10 @@
ICON_COMPUTE
mesh_compute.png
+
+ ICON_PRECOMPUTE
+ mesh_precompute.png
+
ICON_CONNECTION
mesh_multi_edges.png
@@ -237,10 +241,18 @@
ICON_FREE_EDGE
mesh_free_edges.png
-
+
ICON_FREE_EDGE_2D
mesh_free_edges_2d.png
+
+ ICON_FREE_NODE
+ mesh_free_nodes.png
+
+
+ ICON_FREE_FACES
+ mesh_free_faces.png
+
ICON_HYPO
mesh_hypo_length.png
@@ -425,5 +437,9 @@
ICON_CLEAR_MESH
mesh_clear.png
+
+ ICON_UNDERLYING_ELEMS
+ mesh_extractGroup.png
+
diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts
index 6f78f00e4..3b17d35f9 100644
--- a/src/SMESHGUI/SMESH_msg_en.ts
+++ b/src/SMESHGUI/SMESH_msg_en.ts
@@ -177,6 +177,10 @@
MEN_COMPUTE
Compute
+
+ MEN_PRECOMPUTE
+ Preview
+
MEN_CONNECTION
Borders at Multi-Connection
@@ -269,6 +273,10 @@
MEN_EDIT_GROUP
Edit Group
+
+ MEN_EDIT_GEOMGROUP_AS_GROUP
+ Edit Group as Standalone
+
MEN_EDIT_HYPO
Edit Hypothesis
@@ -321,6 +329,14 @@
MEN_FREE_EDGE
Free Edges
+
+ MEN_FREE_NODE
+ Free Nodes
+
+
+ MEN_FREE_FACES
+ Free Faces
+
MEN_GLOBAL_HYPO
Global Hypothesis
@@ -609,6 +625,10 @@
MEN_UN_GROUP
Union Groups
+
+ MEN_UNDERLYING_ELEMS
+ Group of underlying entities
+
MEN_UPDATE
Update
@@ -1035,6 +1055,10 @@ so that the application may crash. Do you wish to continue visualization?SMESH_EDIT_GROUP_TITLE
Edit Group
+
+ SMESH_EDIT_GEOMGROUP_AS_GROUP_TITLE
+ Edit Group as Standalone
+
SMESH_EDIT_HYPOTHESES
Hypotheses Assignation
@@ -1935,6 +1959,10 @@ Consider saving your work before application crash
STB_COMPUTE
Compute
+
+ STB_PRECOMPUTE
+ Preview
+
STB_CONNECTION
Borders at Multi-Connection
@@ -2015,6 +2043,10 @@ Consider saving your work before application crash
STB_EDIT_GROUP
Edit Group
+
+ STB_EDIT_GEOMGROUP_AS_GROUP
+ Edit Group as Standalone
+
STB_EDIT_HYPO
Edit Hypothesis
@@ -2059,6 +2091,16 @@ Consider saving your work before application crash
STB_FREE_EDGE
Free Edges
+
+ STB_FREE_NODE
+ Free Nodes
+
+
+
+
+ STB_FREE_FACES
+ Free Faces
+
STB_GLOBAL_HYPO
Global Hypothesis
@@ -2299,6 +2341,10 @@ Consider saving your work before application crash
STB_UN_GROUP
Union Groups
+
+ STB_UNDERLYING_ELEMS
+ Create groups of entities from existing groups of superior dimensions
+
STB_UPDATE
Update
@@ -2395,6 +2441,10 @@ Consider saving your work before application crash
TOP_COMPUTE
Compute
+
+ TOP_PRECOMPUTE
+ Preview
+
TOP_CONNECTION
Borders at Multi-Connection
@@ -2475,6 +2525,10 @@ Consider saving your work before application crash
TOP_EDIT_GROUP
Edit Group
+
+ TOP_EDIT_GEOMGROUP_AS_GROUP
+ Edit Group as Standalone
+
TOP_EDIT_HYPO
Edit Hypothesis
@@ -2519,6 +2573,16 @@ Consider saving your work before application crash
TOP_FREE_EDGE
Free Edges
+
+ TOP_FREE_NODE
+ Free Nodes
+
+
+
+
+ TOP_FREE_FACES
+ Free Faces
+
TOP_GLOBAL_HYPO
Global Hypothesis
@@ -2759,6 +2823,10 @@ Consider saving your work before application crash
TOP_UN_GROUP
Union Groups
+
+ TOP_UNDERLYING_ELEMS
+ Create groups of entities from existing groups of superior dimensions
+
TOP_UPDATE
Update
@@ -2843,6 +2911,14 @@ Please, create VTK viewer and try again
PREF_AUTO_GROUPS
Automatically create groups for MED export
+
+ PREF_GROUP_SEGMENT_LENGTH
+ Segment length
+
+
+ PREF_SEGMENT_LENGTH
+ Segmentation of diagonal of boundary box of geometry
+
PREF_AUTO_UPDATE
Automatic update
@@ -3120,6 +3196,38 @@ Please, create VTK viewer and try again
Show bad Mesh
+
+ SMESHGUI_PrecomputeDlg
+
+ CAPTION
+ Preview and Compute mesh
+
+
+ PREVIEW
+ Preview
+
+
+ PREVIEW_1
+ 1D Mesh
+
+
+ PREVIEW_2
+ 2D Mesh
+
+
+ COMPUTE
+ Compute
+
+
+
+ SMESHGUI_PrecomputeOp
+
+ CLEAR_SUBMESH_QUESTION
+ A temporary submeshes on the selected geometry
+ created during preview operation.
+ Do you want to remove all this submeshes?
+
+
SMESHGUI_ConvToQuadDlg
@@ -3395,8 +3503,8 @@ Please select a groups and try again
Please select valid object and try again
- CURRENT_GROUP
- Current Group
+ CURRENT_DIALOG
+ Current Dialog
EDGES_TLT
@@ -3685,6 +3793,16 @@ Please enter correct value and try again
FREE_EDGES
Free edges
+
+ FREE_NODES
+ Free nodes
+
+
+
+
+ FREE_FACES
+ Free faces
+
ID
ID
@@ -3697,6 +3815,10 @@ Please enter correct value and try again
LENGTH
Length
+
+ LENGTH2D
+ Length 2D
+
LESS_THAN
Less than
@@ -3716,6 +3838,11 @@ Please enter correct value and try again
MULTIEDGES_ERROR
Threshold value of borders at multi-connections can not be equal 1
+Please enter correct value and try again
+
+
+ GROUPCOLOR_ERROR
+ Color of group can not be undefied
Please enter correct value and try again
@@ -3770,6 +3897,66 @@ Please enter correct value and try again
WARPING
Warping
+
+ LINEAR
+ Linear
+
+
+ GROUP_COLOR
+ Color of Group
+
+
+ ELEMENTS
+ Elements
+
+
+ GEOM_TYPE
+ Geomtry type
+
+
+ GEOM_TYPE_0
+
+
+
+ GEOM_TYPE_0
+ Point
+
+
+ GEOM_TYPE_1
+ Edge
+
+
+ GEOM_TYPE_2
+ Triangle
+
+
+ GEOM_TYPE_3
+ Quadrangle
+
+
+ GEOM_TYPE_4
+ Polygon
+
+
+ GEOM_TYPE_5
+ Tetrahedron
+
+
+ GEOM_TYPE_6
+ Pyramid
+
+
+ GEOM_TYPE_7
+ Hexahedron
+
+
+ GEOM_TYPE_8
+ Pentahedron
+
+
+ GEOM_TYPE_9
+ Polyhedra
+
SMESHGUI_GroupOpDlg
@@ -3777,10 +3964,6 @@ Please enter correct value and try again
ARGUMENTS
Arguments
-
- CUT_OF_TWO_GROUPS
- Cut of two groups
-
DIFF_MESHES
Arguments of operation are not correctly specified
@@ -3803,14 +3986,6 @@ Please specify non-empty name and try again
Arguments of operation are not specified
Please specify them and try again
-
- INTERSECTION_OF_TWO_GROUPS
- Intersection of two groups
-
-
- MAIN_OBJECT
- Main object
-
NAME
Name
@@ -3836,6 +4011,62 @@ Please specify them and try again
Union of two groups
+
+ SMESHGUI_UnionGroupsDlg
+
+ UNION_OF_GROUPS
+ Union of groups
+
+
+
+ SMESHGUI_DimGroupDlg
+
+ CREATE_GROUP_OF_UNDERLYING_ELEMS
+ Create group of underlying entities
+
+
+ ELEMENTS_TYPE
+ Elements type
+
+
+ NODE
+ Node
+
+
+ EDGE
+ Edge
+
+
+ FACE
+ Face
+
+
+ VOLUME
+ Volume
+
+
+
+ SMESHGUI_IntersectGroupsDlg
+
+ INTERSECTION_OF_GROUPS
+ Intersection of groups
+
+
+
+ SMESHGUI_CutGroupsDlg
+
+ CUT_OF_GROUPS
+ Cut of groups
+
+
+ MAIN_OBJECT
+ Main object
+
+
+ TOOL_OBJECT
+ Tool object
+
+
SMESHGUI_MakeNodeAtPointDlg
@@ -4251,6 +4482,14 @@ It is impossible to read point coordinates from file
TOTAL_ANGLE
Total Angle
+
+ MEN_POINT_SELECT
+ Select Point
+
+
+ MEN_FACE_SELECT
+ Select Plane
+
SMESHGUI_SewingDlg
diff --git a/src/SMESH_I/Makefile.am b/src/SMESH_I/Makefile.am
index 243d207b0..35200fa1c 100644
--- a/src/SMESH_I/Makefile.am
+++ b/src/SMESH_I/Makefile.am
@@ -24,7 +24,6 @@
# Author : Paul RASCLE, EDF
# Modified by : Alexander BORODIN (OCN) - autotools usage
# Module : SMESH
-# $Header$
#
include $(top_srcdir)/adm_local/unix/make_common_starter.am
@@ -120,6 +119,7 @@ libSMESHEngine_la_LDFLAGS = \
-lSalomeGenericObj \
$(MED_LDFLAGS) \
-lMEDWrapper_V2_2 \
+ -lSalomeIDLMED \
$(CAS_LDPATH) \
-lTKCDF \
-lTKBO \
diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx
index 4340ab41b..0a7e57e86 100644
--- a/src/SMESH_I/SMESH_2smeshpy.cxx
+++ b/src/SMESH_I/SMESH_2smeshpy.cxx
@@ -20,11 +20,7 @@
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-// File : SMESH_2D_Algo_i.hxx
-// Author : Paul RASCLE, EDF
-// Module : SMESH
-// $Header$
-
+//
// File : SMESH_2smeshpy.cxx
// Created : Fri Nov 18 13:20:10 2005
// Author : Edward AGAPOV (eap)
@@ -45,8 +41,10 @@ IMPLEMENT_STANDARD_HANDLE (_pyObject ,Standard_Transient);
IMPLEMENT_STANDARD_HANDLE (_pyCommand ,Standard_Transient);
IMPLEMENT_STANDARD_HANDLE (_pyGen ,_pyObject);
IMPLEMENT_STANDARD_HANDLE (_pyMesh ,_pyObject);
+IMPLEMENT_STANDARD_HANDLE (_pySubMesh ,_pyObject);
IMPLEMENT_STANDARD_HANDLE (_pyMeshEditor ,_pyObject);
IMPLEMENT_STANDARD_HANDLE (_pyHypothesis ,_pyObject);
+IMPLEMENT_STANDARD_HANDLE (_pyFilterManager ,_pyObject);
IMPLEMENT_STANDARD_HANDLE (_pyAlgorithm ,_pyHypothesis);
IMPLEMENT_STANDARD_HANDLE (_pyComplexParamHypo,_pyHypothesis);
IMPLEMENT_STANDARD_HANDLE (_pyNumberOfSegmentsHyp,_pyHypothesis);
@@ -55,8 +53,10 @@ IMPLEMENT_STANDARD_RTTIEXT(_pyObject ,Standard_Transient);
IMPLEMENT_STANDARD_RTTIEXT(_pyCommand ,Standard_Transient);
IMPLEMENT_STANDARD_RTTIEXT(_pyGen ,_pyObject);
IMPLEMENT_STANDARD_RTTIEXT(_pyMesh ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pySubMesh ,_pyObject);
IMPLEMENT_STANDARD_RTTIEXT(_pyMeshEditor ,_pyObject);
IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesis ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyFilterManager ,_pyObject);
IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm ,_pyHypothesis);
IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis);
IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis);
@@ -119,9 +119,10 @@ namespace {
TCollection_AsciiString
SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
- Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod)
+ Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
+ Resource_DataMapOfAsciiStringAsciiString& theObjectNames)
{
- theGen = new _pyGen( theEntry2AccessorMethod );
+ theGen = new _pyGen( theEntry2AccessorMethod, theObjectNames );
// split theScript into separate commands
int from = 1, end = theScript.Length(), to;
@@ -132,11 +133,13 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
theGen->AddCommand( theScript.SubString( from, to - 1 ));
from = to + 1;
}
+
// finish conversion
theGen->Flush();
#ifdef DUMP_CONVERSION
MESSAGE_BEGIN ( std::endl << " ######## RESULT ######## " << std::endl<< std::endl );
#endif
+
// reorder commands after conversion
list< Handle(_pyCommand) >::iterator cmd;
bool orderChanges;
@@ -172,9 +175,11 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
*/
//================================================================================
-_pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod)
+_pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
+ Resource_DataMapOfAsciiStringAsciiString& theObjectNames)
: _pyObject( new _pyCommand( TPythonDump::SMESHGenName(), 0 )),
- myID2AccessorMethod( theEntry2AccessorMethod )
+ myID2AccessorMethod( theEntry2AccessorMethod ),
+ myObjectNames( theObjectNames )
{
myNbCommands = 0;
myHasPattern = false;
@@ -220,18 +225,43 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
this->Process( aCommand );
return aCommand;
}
+
+ // SMESH_subMesh method?
+ map< _pyID, Handle(_pySubMesh) >::iterator id_subMesh = mySubMeshes.find( objID );
+ if ( id_subMesh != mySubMeshes.end() ) {
+ id_subMesh->second->Process( aCommand );
+ return aCommand;
+ }
+
// SMESH_Mesh method?
map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( objID );
if ( id_mesh != myMeshes.end() ) {
+ // check for mesh editor object
if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation
_pyID editorID = aCommand->GetResultValue();
Handle(_pyMeshEditor) editor = new _pyMeshEditor( aCommand );
myMeshEditors.insert( make_pair( editorID, editor ));
return aCommand;
+ }
+ // check for SubMesh objects
+ else if ( aCommand->GetMethod() == "GetSubMesh" ) { // SubMesh creation
+ _pyID subMeshID = aCommand->GetResultValue();
+ Handle(_pySubMesh) subMesh = new _pySubMesh( aCommand );
+ mySubMeshes.insert( make_pair( subMeshID, subMesh ));
}
id_mesh->second->Process( aCommand );
return aCommand;
}
+
+ //SMESH_FilterManager method?
+ if ( theCommand.Search( "aFilterManager" ) != -1 ) {
+ if ( theCommand.Search( "CreateFilterManager" ) != -1 )
+ myFilterManager = new _pyFilterManager( aCommand );
+ else if ( !myFilterManager.IsNull() )
+ myFilterManager->Process( aCommand );
+ return aCommand;
+ }
+
// SMESH_MeshEditor method?
map< _pyID, Handle(_pyMeshEditor) >::iterator id_editor = myMeshEditors.find( objID );
if ( id_editor != myMeshEditors.end() ) {
@@ -296,6 +326,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
// Compute( mesh, geom )
// mesh creation
TCollection_AsciiString method = theCommand->GetMethod();
+
if ( method == "CreateMesh" || method == "CreateEmptyMesh")
{
Handle(_pyMesh) mesh = new _pyMesh( theCommand );
@@ -320,6 +351,15 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
// CreateHypothesis()
if ( method == "CreateHypothesis" )
{
+ // issue 199929, remove standard library name (default parameter)
+ const TCollection_AsciiString & aLibName = theCommand->GetArg( 2 );
+ if ( aLibName.Search( "StdMeshersEngine" ) != -1 ) {
+ // keep first argument
+ TCollection_AsciiString arg = theCommand->GetArg( 1 );
+ theCommand->RemoveArgs();
+ theCommand->SetArg( 1, arg );
+ }
+
myHypos.push_back( _pyHypothesis::NewHypothesis( theCommand ));
return;
}
@@ -385,6 +425,12 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
void _pyGen::Flush()
{
+ // create empty command
+ myLastCommand = new _pyCommand();
+
+ if ( !myFilterManager.IsNull() )
+ myFilterManager->Flush();
+
map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.begin();
for ( ; id_mesh != myMeshes.end(); ++id_mesh )
if ( ! id_mesh->second.IsNull() )
@@ -398,6 +444,14 @@ void _pyGen::Flush()
if ( !(*hyp)->IsWrapped() )
(*hyp)->GetCreationCmd()->SetObject( SMESH_2smeshpy::GenName() );
}
+
+ map< _pyID, Handle(_pySubMesh) >::iterator id_subMesh = mySubMeshes.begin();
+ for ( ; id_subMesh != mySubMeshes.end(); ++id_subMesh )
+ if ( ! id_subMesh->second.IsNull() )
+ id_subMesh->second->Flush();
+
+ myLastCommand->SetOrderNb( ++myNbCommands );
+ myCommands.push_back( myLastCommand );
}
//================================================================================
@@ -474,12 +528,32 @@ Handle(_pyHypothesis) _pyGen::FindAlgo( const _pyID& theGeom, const _pyID& theMe
if ( !hyp->IsNull() &&
(*hyp)->IsAlgo() &&
theHypothesis->CanBeCreatedBy( (*hyp)->GetAlgoType() ) &&
- (*hyp)->GetGeom() == theGeom &&
+ (*hyp)->GetGeom() == theGeom &&
(*hyp)->GetMesh() == theMesh )
return *hyp;
return 0;
}
+//================================================================================
+/*!
+ * \brief Find subMesh by ID (entry)
+ * \param theSubMeshID - The subMesh ID
+ * \retval Handle(_pySubMesh) - The found subMesh
+ */
+//================================================================================
+
+Handle(_pySubMesh) _pyGen::FindSubMesh( const _pyID& theSubMeshID )
+{
+ map< _pyID, Handle(_pySubMesh) >::iterator id_subMesh = mySubMeshes.begin();
+ for ( ; id_subMesh != mySubMeshes.end(); ++id_subMesh ) {
+ Handle(_pySubMesh) sm = id_subMesh->second;
+ if ( !id_subMesh->second.IsNull() && theSubMeshID == id_subMesh->second->GetID() )
+ return sm;
+ }
+ return Handle(_pySubMesh)();
+}
+
+
//================================================================================
/*!
* \brief Change order of commands in the script
@@ -515,20 +589,57 @@ void _pyGen::ExchangeCommands( Handle(_pyCommand) theCmd1, Handle(_pyCommand) th
void _pyGen::SetCommandAfter( Handle(_pyCommand) theCmd, Handle(_pyCommand) theAfterCmd )
{
-#ifdef _DEBUG_
-//cout << "SET\t" << theAfterCmd->GetString() << endl << "BEFORE\t" << theCmd->GetString() << endl<::iterator pos;
pos = find( myCommands.begin(), myCommands.end(), theCmd );
myCommands.erase( pos );
- pos = find( myCommands.begin(), myCommands.end(), theAfterCmd );
- myCommands.insert( ++pos, theCmd );
+ pos = find( myCommands.begin(), myCommands.end(), theOtherCmd );
+ myCommands.insert( (theIsAfter ? ++pos : pos), theCmd );
int i = 1;
for ( pos = myCommands.begin(); pos != myCommands.end(); ++pos)
(*pos)->SetOrderNb( i++ );
}
+//================================================================================
+/*!
+ * \brief Set command be last in list of commands
+ * \param theCmd - Command to be last
+ */
+//================================================================================
+
+Handle(_pyCommand)& _pyGen::GetLastCommand()
+{
+ return myLastCommand;
+}
+
//================================================================================
/*!
* \brief Set method to access to object wrapped with python class
@@ -542,6 +653,28 @@ void _pyGen::SetAccessorMethod(const _pyID& theID, const char* theMethod )
myID2AccessorMethod.Bind( theID, (char*) theMethod );
}
+//================================================================================
+/*!
+ * \brief Generated new ID for object and assign with existing name
+ * \param theID - ID of existing object
+ */
+//================================================================================
+
+_pyID _pyGen::GenerateNewID( const _pyID& theID )
+{
+ int index = 1;
+ _pyID aNewID;
+ do {
+ aNewID = theID + _pyID( ":" ) + _pyID( index++ );
+ }
+ while ( myObjectNames.IsBound( aNewID ) );
+
+ myObjectNames.Bind( aNewID, myObjectNames.IsBound( theID )
+ ? (myObjectNames.Find( theID ) + _pyID( "_" ) + _pyID( index-1 ))
+ : _pyID( "A" ) + aNewID );
+ return aNewID;
+}
+
//================================================================================
/*!
* \brief Find out type of geom group
@@ -665,7 +798,11 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
const TCollection_AsciiString method = theCommand->GetMethod();
// ----------------------------------------------------------------------
if ( method == "GetSubMesh" ) {
- mySubmeshes.push_back( theCommand );
+ Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetResultValue() );
+ if ( !subMesh.IsNull() ) {
+ subMesh->SetCreator( this );
+ mySubmeshes.push_back( subMesh );
+ }
}
// ----------------------------------------------------------------------
else if ( method == "AddHypothesis" ) { // mesh.AddHypothesis(geom, HYPO )
@@ -688,7 +825,13 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
theCommand->SetArg( 1, grp );
}
else {
- AddMeshAccess( theCommand );
+ _pyID type = theCommand->GetArg( 1 );
+ _pyID name = theCommand->GetArg( 2 );
+ theCommand->SetMethod( "GroupOnGeom" );
+ theCommand->RemoveArgs();
+ theCommand->SetArg( 1, grp );
+ theCommand->SetArg( 2, name );
+ theCommand->SetArg( 3, type );
}
}
// ----------------------------------------------------------------------
@@ -766,7 +909,7 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand )
"GetNodeInverseElements","GetShapeID","GetShapeIDForElem","GetElemNbNodes",
"GetElemNode","IsMediumNode","IsMediumNodeOfAnyElem","ElemNbEdges","ElemNbFaces",
"IsPoly","IsQuadratic","BaryCenter","GetHypothesisList", "SetAutoColor", "GetAutoColor",
- "Clear"
+ "Clear", "ConvertToStandalone"
,"" }; // <- mark of end
sameMethods.Insert( names );
}
@@ -782,20 +925,43 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand )
void _pyMesh::Flush()
{
- list < Handle(_pyCommand) >::iterator cmd, cmd2;
+ list < Handle(_pyCommand) >::iterator cmd;
// try to convert algo addition like this:
// mesh.AddHypothesis(geom, ALGO ) --> ALGO = mesh.Algo()
for ( cmd = myAddHypCmds.begin(); cmd != myAddHypCmds.end(); ++cmd )
{
Handle(_pyCommand) addCmd = *cmd;
+
_pyID algoID = addCmd->GetArg( 2 );
Handle(_pyHypothesis) algo = theGen->FindHyp( algoID );
if ( algo.IsNull() || !algo->IsAlgo() )
continue;
- // try to convert
+
+ // check and create new algorithm instance if it is already wrapped
+ if ( algo->IsWrapped() ) {
+ _pyID localAlgoID = theGen->GenerateNewID( algoID );
+ TCollection_AsciiString aNewCmdStr = localAlgoID +
+ TCollection_AsciiString( " = " ) + theGen->GetID() +
+ TCollection_AsciiString( ".CreateHypothesis( \"" ) + algo->GetAlgoType() +
+ TCollection_AsciiString( "\" )" );
+
+ Handle(_pyCommand) newCmd = theGen->AddCommand( aNewCmdStr );
+ Handle(_pyAlgorithm) newAlgo = Handle(_pyAlgorithm)::DownCast(theGen->FindHyp( localAlgoID ));
+ if ( !newAlgo.IsNull() ) {
+ newAlgo->Assign( algo, this->GetID() );
+ newAlgo->SetCreationCmd( newCmd );
+ algo = newAlgo;
+ // set algorithm creation
+ theGen->SetCommandBefore( newCmd, addCmd );
+ }
+ else
+ newCmd->Clear();
+ }
_pyID geom = addCmd->GetArg( 1 );
bool isLocalAlgo = ( geom != GetGeom() );
+
+ // try to convert
if ( algo->Addition2Creation( addCmd, this->GetID() )) // OK
{
// wrapped algo is created atfer mesh creation
@@ -806,12 +972,14 @@ void _pyMesh::Flush()
addCmd->SetArg( addCmd->GetNbArgs() + 1,
TCollection_AsciiString( "geom=" ) + geom );
// sm = mesh.GetSubMesh(geom, name) --> sm = ALGO.GetSubMesh()
- for ( cmd2 = mySubmeshes.begin(); cmd2 != mySubmeshes.end(); ++cmd2 ) {
- Handle(_pyCommand) subCmd = *cmd2;
+ list < Handle(_pySubMesh) >::iterator smIt;
+ for ( smIt = mySubmeshes.begin(); smIt != mySubmeshes.end(); ++smIt ) {
+ Handle(_pySubMesh) subMesh = *smIt;
+ Handle(_pyCommand) subCmd = subMesh->GetCreationCmd();
if ( geom == subCmd->GetArg( 1 )) {
subCmd->SetObject( algo->GetID() );
subCmd->RemoveArgs();
- addCmd->AddDependantCmd( subCmd );
+ subMesh->SetCreator( algo );
}
}
}
@@ -1014,6 +1182,13 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th
// i.e. convertion result will be "locallength = regular1d.LocalLength()"
hyp->AddArgMethod( "SetLength" );
}
+ else if ( hypType == "MaxLength" ) {
+ // set algo's method creating hyp, and algo type
+ hyp->SetConvMethodAndType( "MaxSize", "Regular_1D");
+ // set method whose 1 arg will become the 1-st arg of hyp creation command
+ // i.e. convertion result will be "maxsize = regular1d.MaxSize()"
+ hyp->AddArgMethod( "SetLength" );
+ }
else if ( hypType == "NumberOfSegments" ) {
hyp = new _pyNumberOfSegmentsHyp( theCreationCmd );
hyp->SetConvMethodAndType( "NumberOfSegments", "Regular_1D");
@@ -1188,6 +1363,8 @@ bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd,
algo = theGen->FindAlgo( myGeom, theMesh, this );
if ( algo.IsNull() )
return false;
+ // attach hypothesis creation command to be after algo creation command
+ // because it can be new created instance of algorithm
algo->GetCreationCmd()->AddDependantCmd( theCmd );
}
myIsWrapped = true;
@@ -1206,7 +1383,10 @@ bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd,
}
// set a new creation command
GetCreationCmd()->Clear();
+ // replace creation command by wrapped instance
+ // please note, that hypothesis attaches to algo creation command (see upper)
SetCreationCmd( theCmd );
+
// clear commands setting arg values
list < Handle(_pyCommand) >::iterator argCmd = myArgCommands.begin();
@@ -1297,6 +1477,30 @@ void _pyHypothesis::ClearAllCommands()
( *cmd )->Clear();
}
+
+//================================================================================
+/*!
+ * \brief Assign fields of theOther to me except myIsWrapped
+ */
+//================================================================================
+
+void _pyHypothesis::Assign( const Handle(_pyHypothesis)& theOther,
+ const _pyID& theMesh )
+{
+ myIsWrapped = false;
+ myMesh = theMesh;
+
+ // myCreationCmd = theOther->myCreationCmd;
+ myIsAlgo = theOther->myIsAlgo;
+ myGeom = theOther->myGeom;
+ myType2CreationMethod = theOther->myType2CreationMethod;
+ myArgs = theOther->myArgs;
+ myArgMethods = theOther->myArgMethods;
+ myNbArgsByMethod = theOther->myNbArgsByMethod;
+ myArgCommands = theOther->myArgCommands;
+ myUnknownCommands = theOther->myUnknownCommands;
+}
+
//================================================================================
/*!
* \brief Remember hypothesis parameter values
@@ -1386,9 +1590,9 @@ void _pyLayerDistributionHypo::Process( const Handle(_pyCommand)& theCommand)
//================================================================================
/*!
* \brief
- * \param theAdditionCmd -
- * \param theMesh -
- * \retval bool -
+ * \param theAdditionCmd - command to be converted
+ * \param theMesh - mesh instance
+ * \retval bool - status
*/
//================================================================================
@@ -2071,3 +2275,78 @@ _pyID _pyObject::FatherID(const _pyID & childID)
return childID.SubString( 1, colPos-1 );
return "";
}
+
+//================================================================================
+/*!
+ * \brief FilterManager creates only if at least one command invoked
+ */
+//================================================================================
+
+_pyFilterManager::_pyFilterManager(const Handle(_pyCommand)& theCreationCmd):
+ _pyObject( theCreationCmd ),
+ myCmdCount( 0 )
+{
+}
+
+//================================================================================
+/*!
+ * \brief count invoked commands
+ */
+//================================================================================
+
+void _pyFilterManager::Process( const Handle(_pyCommand)& /*theCommand*/)
+{
+ myCmdCount++;
+}
+
+//================================================================================
+/*!
+ * \brief Clear creatin command if no commands invoked
+ */
+//================================================================================
+
+void _pyFilterManager::Flush()
+{
+ if ( !myCmdCount )
+ GetCreationCmd()->Clear();
+}
+
+
+//================================================================================
+/*!
+ * \brief SubMesh creation can be moved to the end of engine commands
+ */
+//================================================================================
+
+_pySubMesh::_pySubMesh(const Handle(_pyCommand)& theCreationCmd):
+ _pyObject( theCreationCmd ),
+ myCmdCount( 0 )
+{
+}
+
+//================================================================================
+/*!
+ * \brief count invoked commands
+ */
+//================================================================================
+
+void _pySubMesh::Process( const Handle(_pyCommand)& theCommand )
+{
+ myCmdCount++;
+ GetCreationCmd()->AddDependantCmd( theCommand );
+}
+
+//================================================================================
+/*!
+ * \brief Clear creatin command if no commands invoked
+ */
+//================================================================================
+
+void _pySubMesh::Flush()
+{
+ if ( !myCmdCount ) // move to the end of all commands
+ theGen->GetLastCommand()->AddDependantCmd( GetCreationCmd() );
+ else if ( !myCreator.IsNull() )
+ // move to be just after creator
+ myCreator->GetCreationCmd()->AddDependantCmd( GetCreationCmd() );
+}
diff --git a/src/SMESH_I/SMESH_2smeshpy.hxx b/src/SMESH_I/SMESH_2smeshpy.hxx
index bbe368e72..eac87deca 100644
--- a/src/SMESH_I/SMESH_2smeshpy.hxx
+++ b/src/SMESH_I/SMESH_2smeshpy.hxx
@@ -65,15 +65,19 @@ class _pyCommand;
class _pyObject;
class _pyGen;
class _pyMesh;
+class _pySubMesh;
class _pyHypothesis;
class _pyAlgorithm;
+class _pyFilterManager;
DEFINE_STANDARD_HANDLE (_pyCommand ,Standard_Transient);
DEFINE_STANDARD_HANDLE (_pyObject ,Standard_Transient);
DEFINE_STANDARD_HANDLE (_pyGen ,_pyObject);
DEFINE_STANDARD_HANDLE (_pyMesh ,_pyObject);
+DEFINE_STANDARD_HANDLE (_pySubMesh ,_pyObject);
DEFINE_STANDARD_HANDLE (_pyMeshEditor,_pyObject);
DEFINE_STANDARD_HANDLE (_pyHypothesis,_pyObject);
+DEFINE_STANDARD_HANDLE (_pyFilterManager,_pyObject);
DEFINE_STANDARD_HANDLE (_pyAlgorithm ,_pyHypothesis);
typedef TCollection_AsciiString _pyID;
@@ -173,7 +177,8 @@ public:
class _pyGen: public _pyObject
{
public:
- _pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod);
+ _pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
+ Resource_DataMapOfAsciiStringAsciiString& theObjectNames);
//~_pyGen();
Handle(_pyCommand) AddCommand( const TCollection_AsciiString& theCommand );
void Process( const Handle(_pyCommand)& theCommand );
@@ -181,21 +186,35 @@ public:
Handle(_pyHypothesis) FindHyp( const _pyID& theHypID );
Handle(_pyHypothesis) FindAlgo( const _pyID& theGeom, const _pyID& theMesh,
const Handle(_pyHypothesis)& theHypothesis);
+ Handle(_pySubMesh) FindSubMesh( const _pyID& theSubMeshID );
void ExchangeCommands( Handle(_pyCommand) theCmd1, Handle(_pyCommand) theCmd2 );
void SetCommandAfter( Handle(_pyCommand) theCmd, Handle(_pyCommand) theAfterCmd );
+ void SetCommandBefore( Handle(_pyCommand) theCmd, Handle(_pyCommand) theBeforeCmd );
+ Handle(_pyCommand)& GetLastCommand();
std::list< Handle(_pyCommand) >& GetCommands() { return myCommands; }
void SetAccessorMethod(const _pyID& theID, const char* theMethod );
bool AddMeshAccessorMethod( Handle(_pyCommand) theCmd ) const;
bool AddAlgoAccessorMethod( Handle(_pyCommand) theCmd ) const;
const char* AccessorMethod() const;
+ _pyID GenerateNewID( const _pyID& theID );
+
+private:
+ void setNeighbourCommand( Handle(_pyCommand)& theCmd,
+ Handle(_pyCommand)& theOtherCmd,
+ const bool theIsAfter );
+
private:
std::map< _pyID, Handle(_pyMesh) > myMeshes;
+ std::map< _pyID, Handle(_pySubMesh) > mySubMeshes;
std::map< _pyID, Handle(_pyMeshEditor) > myMeshEditors;
std::list< Handle(_pyHypothesis) > myHypos;
std::list< Handle(_pyCommand) > myCommands;
int myNbCommands;
bool myHasPattern;
Resource_DataMapOfAsciiStringAsciiString& myID2AccessorMethod;
+ Resource_DataMapOfAsciiStringAsciiString& myObjectNames;
+ Handle(_pyCommand) myLastCommand;
+ Handle(_pyFilterManager) myFilterManager;
DEFINE_STANDARD_RTTI (_pyGen)
};
@@ -210,7 +229,7 @@ class _pyMesh: public _pyObject
{
std::list< Handle(_pyHypothesis) > myHypos;
std::list< Handle(_pyCommand) > myAddHypCmds;
- std::list< Handle(_pyCommand) > mySubmeshes;
+ std::list< Handle(_pySubMesh) > mySubmeshes;
bool myHasEditor;
public:
_pyMesh(const Handle(_pyCommand) creationCmd);
@@ -299,12 +318,14 @@ public:
{ return myType2CreationMethod.find( algoType ) != myType2CreationMethod.end(); }
const TCollection_AsciiString& GetCreationMethod(const TCollection_AsciiString& algoType) const
{ return myType2CreationMethod.find( algoType )->second; }
- bool IsWrappable(const _pyID& theMesh) { return !myIsWrapped && myMesh == theMesh; }
+ virtual bool IsWrappable(const _pyID& theMesh) { return !myIsWrapped && myMesh == theMesh; }
virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
const _pyID& theMesh);
static Handle(_pyHypothesis) NewHypothesis( const Handle(_pyCommand)& theCreationCmd);
void Process( const Handle(_pyCommand)& theCommand);
void Flush();
+ virtual void Assign( const Handle(_pyHypothesis)& theOther,
+ const _pyID& theMesh );
DEFINE_STANDARD_RTTI (_pyHypothesis)
};
@@ -321,6 +342,7 @@ public:
virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
const _pyID& theMesh);
const char* AccessorMethod() const { return "GetAlgorithm()"; }
+ virtual bool IsWrappable(const _pyID& theMesh) { return !myIsWrapped; }
DEFINE_STANDARD_RTTI (_pyAlgorithm)
};
@@ -392,4 +414,40 @@ public:
};
DEFINE_STANDARD_HANDLE (_pySegmentLengthAroundVertexHyp, _pyHypothesis);
+// -------------------------------------------------------------------------------------
+/*!
+ * \brief FilterManager creates only if at least one command invoked
+ */
+// -------------------------------------------------------------------------------------
+class _pyFilterManager: public _pyObject
+{
+public:
+ _pyFilterManager(const Handle(_pyCommand)& theCreationCmd);
+ void Process( const Handle(_pyCommand)& theCommand);
+ virtual void Flush();
+
+ DEFINE_STANDARD_RTTI (_pyFilterManager)
+private:
+ int myCmdCount;
+};
+
+// -------------------------------------------------------------------------------------
+/*!
+ * \brief SubMesh creation can be moved to the end of engine commands
+ */
+// -------------------------------------------------------------------------------------
+class _pySubMesh: public _pyObject
+{
+public:
+ _pySubMesh(const Handle(_pyCommand)& theCreationCmd);
+ void Process( const Handle(_pyCommand)& theCommand);
+ virtual void Flush();
+ void SetCreator( const Handle(_pyObject)& theCreator ) { myCreator = theCreator; }
+
+ DEFINE_STANDARD_RTTI (_pyFilterManager)
+private:
+ int myCmdCount;
+ Handle(_pyObject) myCreator;
+};
+
#endif
diff --git a/src/SMESH_I/SMESH_DumpPython.cxx b/src/SMESH_I/SMESH_DumpPython.cxx
index e7a7a2952..ad409b786 100644
--- a/src/SMESH_I/SMESH_DumpPython.cxx
+++ b/src/SMESH_I/SMESH_DumpPython.cxx
@@ -61,10 +61,10 @@ namespace SMESH
{
if(--myCounter == 0){
SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
+ std::string aString = myStream.str();
+ TCollection_AsciiString aCollection(Standard_CString(aString.c_str()));
SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
- if(!aStudy->_is_nil()){
- std::string aString = myStream.str();
- TCollection_AsciiString aCollection(Standard_CString(aString.c_str()));
+ if(!aStudy->_is_nil() && !aCollection.IsEmpty()){
aSMESHGen->AddToPythonScript(aStudy->StudyId(),aCollection);
if(MYDEBUG) MESSAGE(aString);
}
@@ -226,6 +226,7 @@ namespace SMESH
case FT_Area: myStream<< "aArea"; break;
case FT_FreeBorders: myStream<< "aFreeBorders"; break;
case FT_FreeEdges: myStream<< "aFreeEdges"; break;
+ case FT_FreeNodes: myStream<< "aFreeNodes"; break;
case FT_MultiConnection: myStream<< "aMultiConnection"; break;
case FT_MultiConnection2D:myStream<< "aMultiConnection2D";break;
case FT_Length: myStream<< "aLength"; break;
@@ -686,7 +687,7 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
// Some objects are wrapped with python classes and
// Resource_DataMapOfAsciiStringAsciiString holds methods returning wrapped objects
Resource_DataMapOfAsciiStringAsciiString anEntry2AccessorMethod;
- aScript = SMESH_2smeshpy::ConvertScript( aScript, anEntry2AccessorMethod );
+ aScript = SMESH_2smeshpy::ConvertScript( aScript, anEntry2AccessorMethod, theObjectNames );
// Find entries to be replaced by names
Handle(TColStd_HSequenceOfInteger) aSeq = FindEntries(aScript);
@@ -834,8 +835,6 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
// Set object names
anUpdatedScript += "\n\t## set object names";
- anUpdatedScript += helper + " \n\tisGUIMode = " + isPublished;
- anUpdatedScript += "\n\tif isGUIMode and salome.sg.hasDesktop():";
// anUpdatedScript += "\n\t\tsmeshgui = salome.ImportComponentGUI(\"SMESH\")";
// anUpdatedScript += "\n\t\tsmeshgui.Init(theStudy._get_StudyId())";
// anUpdatedScript += "\n";
@@ -854,13 +853,14 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
aName = theObjectNames.Find(anEntry);
aGUIName = theNames.Find(anEntry);
mapEntries.Bind(anEntry, aName);
- anUpdatedScript += helper + "\n\t\t" + aSmeshpy + ".SetName(" + aName;
+ anUpdatedScript += helper + "\n\t" + aSMESHGen + ".SetName(" + aName;
if ( anEntry2AccessorMethod.IsBound( anEntry ) )
anUpdatedScript += helper + "." + anEntry2AccessorMethod( anEntry );
anUpdatedScript += helper + ", '" + aGUIName + "')";
}
}
- anUpdatedScript += "\n\n\t\tsalome.sg.updateObjBrowser(0)";
+ anUpdatedScript += "\n\tif salome.sg.hasDesktop():";
+ anUpdatedScript += "\n\t\tsalome.sg.updateObjBrowser(0)";
// -----------------------------------------------------------------
// store visual properties of displayed objects
@@ -876,7 +876,6 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
CORBA::string_free(script);
}
}
-
anUpdatedScript += "\n\n\tpass\n";
// -----------------------------------------------------------------
diff --git a/src/SMESH_I/SMESH_Filter_i.cxx b/src/SMESH_I/SMESH_Filter_i.cxx
index 9c352a483..189e6cbcc 100644
--- a/src/SMESH_I/SMESH_Filter_i.cxx
+++ b/src/SMESH_I/SMESH_Filter_i.cxx
@@ -1281,6 +1281,36 @@ FunctorType FreeEdges_i::GetFunctorType()
return SMESH::FT_FreeEdges;
}
+/*
+ Class : FreeFaces_i
+ Description : Predicate for free faces
+*/
+FreeFaces_i::FreeFaces_i()
+{
+ myPredicatePtr.reset(new Controls::FreeFaces());
+ myFunctorPtr = myPredicatePtr;
+}
+
+FunctorType FreeFaces_i::GetFunctorType()
+{
+ return SMESH::FT_FreeFaces;
+}
+
+/*
+ Class : FreeNodes_i
+ Description : Predicate for free nodes
+*/
+FreeNodes_i::FreeNodes_i()
+{
+ myPredicatePtr.reset(new Controls::FreeNodes());
+ myFunctorPtr = myPredicatePtr;
+}
+
+FunctorType FreeNodes_i::GetFunctorType()
+{
+ return SMESH::FT_FreeNodes;
+}
+
/*
Class : RangeOfIds_i
Description : Predicate for Range of Ids.
@@ -1329,6 +1359,94 @@ FunctorType RangeOfIds_i::GetFunctorType()
return SMESH::FT_RangeOfIds;
}
+/*
+ Class : LinearOrQuadratic_i
+ Description : Predicate to verify whether a mesh element is linear
+*/
+LinearOrQuadratic_i::LinearOrQuadratic_i()
+{
+ myLinearOrQuadraticPtr.reset(new Controls::LinearOrQuadratic());
+ myFunctorPtr = myPredicatePtr = myLinearOrQuadraticPtr;
+}
+
+void LinearOrQuadratic_i::SetElementType(ElementType theType)
+{
+ myLinearOrQuadraticPtr->SetType(SMDSAbs_ElementType(theType));
+ TPythonDump()<SetColorStr(
+ TCollection_AsciiString( (Standard_CString)theColor ) );
+ TPythonDump()<GetColorStr( aStr );
+ return CORBA::string_dup( aStr.ToCString() );
+}
+
+void GroupColor_i::SetElementType(ElementType theType)
+{
+ myGroupColorPtr->SetType(SMDSAbs_ElementType(theType));
+ TPythonDump()<SetType(SMDSAbs_ElementType(theType));
+ TPythonDump()<SetGeomType(SMDSAbs_GeometryType(theType));
+ TPythonDump()<GetGeomType();;
+}
+
+FunctorType ElemGeomType_i::GetFunctorType()
+{
+ return SMESH::FT_ElemGeomType;
+}
+
/*
Class : Comparator_i
Description : Base class for comparators
@@ -1761,6 +1879,22 @@ FreeEdges_ptr FilterManager_i::CreateFreeEdges()
return anObj._retn();
}
+FreeFaces_ptr FilterManager_i::CreateFreeFaces()
+{
+ SMESH::FreeFaces_i* aServant = new SMESH::FreeFaces_i();
+ SMESH::FreeFaces_var anObj = aServant->_this();
+ TPythonDump()<_this();
+ TPythonDump()<_this();
+ TPythonDump()<_this();
+ TPythonDump()<_this();
+ TPythonDump()<length();
theCriteria->length( i + 1 );
@@ -2141,6 +2298,33 @@ static inline bool getCriteria( Predicate_i* thePred,
theCriteria[ theCriteria->length() - 1 ].BinaryOp = aFType;
return getCriteria( aPred2, theCriteria );
}
+ case FT_GroupColor:
+ {
+ CORBA::ULong i = theCriteria->length();
+ theCriteria->length( i + 1 );
+
+ theCriteria[ i ] = createCriterion();
+
+ GroupColor_i* aPred = dynamic_cast( thePred );
+ theCriteria[ i ].Type = aFType;
+ theCriteria[ i ].TypeOfElement = aPred->GetElementType();
+ theCriteria[ i ].ThresholdStr = aPred->GetColorStr();
+
+ return true;
+ }
+ case FT_ElemGeomType:
+ {
+ CORBA::ULong i = theCriteria->length();
+ theCriteria->length( i + 1 );
+
+ theCriteria[ i ] = createCriterion();
+
+ ElemGeomType_i* aPred = dynamic_cast( thePred );
+ theCriteria[ i ].Type = aFType;
+ theCriteria[ i ].TypeOfElement = aPred->GetElementType();
+ theCriteria[ i ].Threshold = (double)aPred->GetGeometryType();
+ return true;
+ }
case FT_Undefined:
return false;
@@ -2255,6 +2439,12 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
case SMESH::FT_FreeEdges:
aPredicate = aFilterMgr->CreateFreeEdges();
break;
+ case SMESH::FT_FreeFaces:
+ aPredicate = aFilterMgr->CreateFreeFaces();
+ break;
+ case SMESH::FT_FreeNodes:
+ aPredicate = aFilterMgr->CreateFreeNodes();
+ break;
case SMESH::FT_BelongToGeom:
{
SMESH::BelongToGeom_ptr tmpPred = aFilterMgr->CreateBelongToGeom();
@@ -2302,6 +2492,29 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
aPredicate = aFilterMgr->CreateBadOrientedVolume();
}
break;
+ case SMESH::FT_LinearOrQuadratic:
+ {
+ SMESH::LinearOrQuadratic_ptr tmpPred = aFilterMgr->CreateLinearOrQuadratic();
+ tmpPred->SetElementType( aTypeOfElem );
+ aPredicate = tmpPred;
+ break;
+ }
+ case SMESH::FT_GroupColor:
+ {
+ SMESH::GroupColor_ptr tmpPred = aFilterMgr->CreateGroupColor();
+ tmpPred->SetElementType( aTypeOfElem );
+ tmpPred->SetColorStr( aThresholdStr );
+ aPredicate = tmpPred;
+ break;
+ }
+ case SMESH::FT_ElemGeomType:
+ {
+ SMESH::ElemGeomType_ptr tmpPred = aFilterMgr->CreateElemGeomType();
+ tmpPred->SetElementType( aTypeOfElem );
+ tmpPred->SetGeometryType( (GeometryType)(aThreshold + 0.5) );
+ aPredicate = tmpPred;
+ break;
+ }
default:
continue;
@@ -2513,16 +2726,21 @@ static inline LDOMString toString( CORBA::Long theType )
case FT_RangeOfIds : return "Range of IDs";
case FT_FreeBorders : return "Free borders";
case FT_FreeEdges : return "Free edges";
+ case FT_FreeFaces : return "Free faces";
+ case FT_FreeNodes : return "Free nodes";
case FT_MultiConnection : return "Borders at multi-connections";
case FT_MultiConnection2D: return "Borders at multi-connections 2D";
case FT_Length : return "Length";
- case FT_Length2D : return "Length2D";
+ case FT_Length2D : return "Length 2D";
case FT_LessThan : return "Less than";
case FT_MoreThan : return "More than";
case FT_EqualTo : return "Equal to";
case FT_LogicalNOT : return "Not";
case FT_LogicalAND : return "And";
case FT_LogicalOR : return "Or";
+ case FT_GroupColor : return "Color of Group";
+ case FT_LinearOrQuadratic : return "Linear or Quadratic";
+ case FT_ElemGeomType : return "Element geomtry type";
case FT_Undefined : return "";
default : return "";
}
@@ -2548,6 +2766,8 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
else if ( theStr.equals( "Lying on Geom" ) ) return FT_LyingOnGeom;
else if ( theStr.equals( "Free borders" ) ) return FT_FreeBorders;
else if ( theStr.equals( "Free edges" ) ) return FT_FreeEdges;
+ else if ( theStr.equals( "Free faces" ) ) return FT_FreeFaces;
+ else if ( theStr.equals( "Free nodes" ) ) return FT_FreeNodes;
else if ( theStr.equals( "Borders at multi-connections" ) ) return FT_MultiConnection;
// else if ( theStr.equals( "Borders at multi-connections 2D" ) ) return FT_MultiConnection2D;
else if ( theStr.equals( "Length" ) ) return FT_Length;
@@ -2560,6 +2780,9 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
else if ( theStr.equals( "Not" ) ) return FT_LogicalNOT;
else if ( theStr.equals( "And" ) ) return FT_LogicalAND;
else if ( theStr.equals( "Or" ) ) return FT_LogicalOR;
+ else if ( theStr.equals( "Color of Group" ) ) return FT_GroupColor;
+ else if ( theStr.equals( "Linear or Quadratic" ) ) return FT_LinearOrQuadratic;
+ else if ( theStr.equals( "Element geomtry type" ) ) return FT_ElemGeomType;
else if ( theStr.equals( "" ) ) return FT_Undefined;
else return FT_Undefined;
}
@@ -2832,7 +3055,7 @@ Filter_ptr FilterLibrary_i::Copy( const char* theFilterName )
}
else
aCriterion.ThresholdStr = str.GetString();
-
+
aCriteria.push_back( aCriterion );
}
diff --git a/src/SMESH_I/SMESH_Filter_i.hxx b/src/SMESH_I/SMESH_Filter_i.hxx
index c5b0bacbd..3b654e880 100644
--- a/src/SMESH_I/SMESH_Filter_i.hxx
+++ b/src/SMESH_I/SMESH_Filter_i.hxx
@@ -520,6 +520,32 @@ namespace SMESH
Controls::FreeEdgesPtr myFreeEdgesPtr;
};
+
+ /*
+ Class : FreeFaces_i
+ Description : Predicate for free faces
+ */
+ class SMESH_I_EXPORT FreeFaces_i: public virtual POA_SMESH::FreeFaces,
+ public virtual Predicate_i
+ {
+ public:
+ FreeFaces_i();
+ FunctorType GetFunctorType();
+ };
+
+
+ /*
+ Class : FreeNodes_i
+ Description : Predicate for free nodes
+ */
+ class SMESH_I_EXPORT FreeNodes_i: public virtual POA_SMESH::FreeNodes,
+ public virtual Predicate_i
+ {
+ public:
+ FreeNodes_i();
+ FunctorType GetFunctorType();
+ };
+
/*
Class : RangeOfIds_i
@@ -540,6 +566,60 @@ namespace SMESH
protected:
Controls::RangeOfIdsPtr myRangeOfIdsPtr;
};
+
+ /*
+ Class : LinearOrQuadratic_i
+ Description : Verify whether a mesh element is linear
+ */
+ class SMESH_I_EXPORT LinearOrQuadratic_i: public virtual POA_SMESH::LinearOrQuadratic,
+ public virtual Predicate_i
+ {
+ public:
+ LinearOrQuadratic_i();
+ FunctorType GetFunctorType();
+ void SetElementType( ElementType theType );
+
+ private:
+ Controls::LinearOrQuadraticPtr myLinearOrQuadraticPtr;
+ };
+
+ /*
+ Class : GroupColor_i
+ Description : Functor for check color of group to whic mesh element belongs to
+ */
+ class SMESH_I_EXPORT GroupColor_i: public virtual POA_SMESH::GroupColor,
+ public virtual Predicate_i
+ {
+ public:
+ GroupColor_i();
+ FunctorType GetFunctorType();
+
+ void SetElementType( ElementType theType );
+ void SetColorStr( const char* theColor );
+ char* GetColorStr();
+
+ private:
+ Controls::GroupColorPtr myGroupColorPtr;
+ };
+
+ /*
+ Class : ElemGeomType_i
+ Description : Functor for check element geometry type
+ */
+ class SMESH_I_EXPORT ElemGeomType_i: public virtual POA_SMESH::ElemGeomType,
+ public virtual Predicate_i
+ {
+ public:
+ ElemGeomType_i();
+ FunctorType GetFunctorType();
+
+ void SetElementType ( ElementType theType );
+ void SetGeometryType( GeometryType theType );
+ GeometryType GetGeometryType() const;
+
+ private:
+ Controls::ElemGeomTypePtr myElemGeomTypePtr;
+ };
/*
Class : Comparator_i
@@ -815,11 +895,18 @@ namespace SMESH
FreeBorders_ptr CreateFreeBorders();
FreeEdges_ptr CreateFreeEdges();
+ FreeNodes_ptr CreateFreeNodes();
+ FreeFaces_ptr CreateFreeFaces();
RangeOfIds_ptr CreateRangeOfIds();
BadOrientedVolume_ptr CreateBadOrientedVolume();
+ LinearOrQuadratic_ptr CreateLinearOrQuadratic();
+ GroupColor_ptr CreateGroupColor();
+
+ ElemGeomType_ptr CreateElemGeomType();
+
LessThan_ptr CreateLessThan();
MoreThan_ptr CreateMoreThan();
EqualTo_ptr CreateEqualTo();
diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx
index be5e68111..4cb5b667b 100644
--- a/src/SMESH_I/SMESH_Gen_i.cxx
+++ b/src/SMESH_I/SMESH_Gen_i.cxx
@@ -23,7 +23,6 @@
// File : SMESH_Gen_i.cxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-// $Header$
//
#include
#include
@@ -133,6 +132,9 @@ SALOME_NamingService* SMESH_Gen_i::myNS = NULL;
SALOME_LifeCycleCORBA* SMESH_Gen_i::myLCC = NULL;
SMESH_Gen_i* SMESH_Gen_i::mySMESHGen = NULL;
+
+const int nbElemPerDiagonal = 10;
+
//=============================================================================
/*!
* GetServant [ static ]
@@ -640,14 +642,15 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypNam
//================================================================================
/*!
- * \brief Return hypothesis of given type holding parameter values of the existing mesh
- * \param theHypType - hypothesis type name
- * \param theLibName - plugin library name
- * \param theMesh - The mesh of interest
- * \param theGeom - The shape to get parameter values from
- * \retval SMESH::SMESH_Hypothesis_ptr - The returned hypothesis may be the one existing
- * in a study and used to compute the mesh, or a temporary one created just to pass
- * parameter values
+ * \brief Return a hypothesis holding parameter values corresponding either to the mesh
+ * existing on the given geometry or to size of the geometry.
+ * \param theHypType - hypothesis type name
+ * \param theLibName - plugin library name
+ * \param theMesh - The mesh of interest
+ * \param theGeom - The shape to get parameter values from
+ * \retval SMESH::SMESH_Hypothesis_ptr - The returned hypothesis may be the one existing
+ * in a study and used to compute the mesh, or a temporary one created just to pass
+ * parameter values
*/
//================================================================================
@@ -655,11 +658,12 @@ SMESH::SMESH_Hypothesis_ptr
SMESH_Gen_i::GetHypothesisParameterValues (const char* theHypType,
const char* theLibName,
SMESH::SMESH_Mesh_ptr theMesh,
- GEOM::GEOM_Object_ptr theGeom)
- throw ( SALOME::SALOME_Exception )
+ GEOM::GEOM_Object_ptr theGeom,
+ CORBA::Boolean byMesh)
+ throw ( SALOME::SALOME_Exception )
{
Unexpect aCatch(SALOME_SalomeException);
- if ( CORBA::is_nil( theMesh ) )
+ if ( CORBA::is_nil( theMesh ) && byMesh )
THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference", SALOME::BAD_PARAM );
if ( CORBA::is_nil( theGeom ) )
THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM );
@@ -671,11 +675,11 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char* theHypType,
// get mesh and shape
SMESH_Mesh_i* meshServant = SMESH::DownCast( theMesh );
TopoDS_Shape shape = GeomObjectToShape( theGeom );
- if ( !meshServant || shape.IsNull() )
+ if ( !meshServant && byMesh || shape.IsNull() )
return SMESH::SMESH_Hypothesis::_nil();
- ::SMESH_Mesh& mesh = meshServant->GetImpl();
+ ::SMESH_Mesh* mesh = meshServant ? &meshServant->GetImpl() : (::SMESH_Mesh*)0;
- if ( mesh.NbNodes() == 0 ) // empty mesh
+ if ( byMesh && mesh->NbNodes() == 0 ) // empty mesh
return SMESH::SMESH_Hypothesis::_nil();
// create a temporary hypothesis to know its dimention
@@ -685,37 +689,64 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char* theHypType,
return SMESH::SMESH_Hypothesis::_nil();
::SMESH_Hypothesis* hyp = hypServant->GetImpl();
- // look for a hypothesis of theHypType used to mesh the shape
- if ( myGen.GetShapeDim( shape ) == hyp->GetDim() )
- {
- // check local shape
- SMESH::ListOfHypothesis_var aHypList = theMesh->GetHypothesisList( theGeom );
- int nbLocalHyps = aHypList->length();
- for ( int i = 0; i < nbLocalHyps; i++ )
- if ( strcmp( theHypType, aHypList[i]->GetName() ) == 0 ) // FOUND local!
- return SMESH::SMESH_Hypothesis::_duplicate( aHypList[i] );
- // check super shapes
- TopTools_ListIteratorOfListOfShape itShape( mesh.GetAncestors( shape ));
- while ( nbLocalHyps == 0 && itShape.More() ) {
- GEOM::GEOM_Object_ptr geomObj = ShapeToGeomObject( itShape.Value() );
- if ( ! CORBA::is_nil( geomObj )) {
- SMESH::ListOfHypothesis_var aHypList = theMesh->GetHypothesisList( geomObj );
- nbLocalHyps = aHypList->length();
- for ( int i = 0; i < nbLocalHyps; i++ )
- if ( strcmp( theHypType, aHypList[i]->GetName() ) == 0 ) // FOUND global!
- return SMESH::SMESH_Hypothesis::_duplicate( aHypList[i] );
+ if ( byMesh ) {
+ // look for a hypothesis of theHypType used to mesh the shape
+ if ( myGen.GetShapeDim( shape ) == hyp->GetDim() )
+ {
+ // check local shape
+ SMESH::ListOfHypothesis_var aHypList = theMesh->GetHypothesisList( theGeom );
+ int nbLocalHyps = aHypList->length();
+ for ( int i = 0; i < nbLocalHyps; i++ )
+ if ( strcmp( theHypType, aHypList[i]->GetName() ) == 0 ) // FOUND local!
+ return SMESH::SMESH_Hypothesis::_duplicate( aHypList[i] );
+ // check super shapes
+ TopTools_ListIteratorOfListOfShape itShape( mesh->GetAncestors( shape ));
+ while ( nbLocalHyps == 0 && itShape.More() ) {
+ GEOM::GEOM_Object_ptr geomObj = ShapeToGeomObject( itShape.Value() );
+ if ( ! CORBA::is_nil( geomObj )) {
+ SMESH::ListOfHypothesis_var aHypList = theMesh->GetHypothesisList( geomObj );
+ nbLocalHyps = aHypList->length();
+ for ( int i = 0; i < nbLocalHyps; i++ )
+ if ( strcmp( theHypType, aHypList[i]->GetName() ) == 0 ) // FOUND global!
+ return SMESH::SMESH_Hypothesis::_duplicate( aHypList[i] );
+ }
+ itShape.Next();
}
- itShape.Next();
+ }
+
+ // let the temporary hypothesis find out some how parameter values by mesh
+ if ( hyp->SetParametersByMesh( mesh, shape ))
+ return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp );
+ }
+ else {
+ double diagonal = 0;
+ if ( mesh )
+ diagonal = mesh->GetShapeDiagonalSize();
+ else
+ diagonal = ::SMESH_Mesh::GetShapeDiagonalSize( shape );
+ double elemSize = diagonal / myGen.GetBoundaryBoxSegmentation();
+ if ( elemSize > 0 ) {
+ // let the temporary hypothesis initialize it's values
+ if ( hyp->SetParametersByElementSize( elemSize, mesh ))
+ return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp );
}
}
- // let the temporary hypothesis find out some how parameter values
- if ( hyp->SetParametersByMesh( &mesh, shape ))
- return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp );
-
return SMESH::SMESH_Hypothesis::_nil();
}
+//=============================================================================
+/*!
+ * Sets number of segments per diagonal of boundary box of geometry by which
+ * default segment length of appropriate 1D hypotheses is defined
+ */
+//=============================================================================
+
+void SMESH_Gen_i::SetBoundaryBoxSegmentation( CORBA::Long theNbSegments )
+{
+ myGen.SetBoundaryBoxSegmentation( int( theNbSegments ));
+}
+
//=============================================================================
/*!
* SMESH_Gen_i::CreateMesh
@@ -1363,6 +1394,193 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
return false;
}
+//=============================================================================
+/*!
+ * SMESH_Gen_i::Precompute
+ *
+ * Compute mesh as preview till indicated dimension on shape
+ */
+//=============================================================================
+
+SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Object_ptr theShapeObject,
+ SMESH::Dimension theDimension,
+ SMESH::long_array& theShapesId)
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Precompute" );
+
+ if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh())
+ THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
+ SALOME::BAD_PARAM );
+
+ if ( CORBA::is_nil( theMesh ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
+ SALOME::BAD_PARAM );
+
+ SMESH::MeshPreviewStruct_var result = new SMESH::MeshPreviewStruct;
+ try {
+ // get mesh servant
+ SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() );
+ ASSERT( meshServant );
+ if ( meshServant ) {
+ // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
+ meshServant->CheckGeomGroupModif();
+ // get local TopoDS_Shape
+ TopoDS_Shape myLocShape;
+ if(theMesh->HasShapeToMesh())
+ myLocShape = GeomObjectToShape( theShapeObject );
+ else
+ return result._retn();;
+
+ // call implementation compute
+ ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
+ TSetOfInt shapeIds;
+ ::MeshDimension aDim = (MeshDimension)theDimension;
+ if ( myGen.Compute( myLocMesh, myLocShape, false, aDim, &shapeIds ) )
+ {
+ int nbShapeId = shapeIds.size();
+ theShapesId.length( nbShapeId );
+ // iterates on shapes and collect mesh entities into mesh preview
+ TSetOfInt::const_iterator idIt = shapeIds.begin();
+ TSetOfInt::const_iterator idEnd = shapeIds.end();
+ std::map< int, int > mapOfShIdNb;
+ std::set< SMESH_TLink > setOfEdge;
+ std::list< SMDSAbs_ElementType > listOfElemType;
+ typedef map TNode2LocalIDMap;
+ typedef TNode2LocalIDMap::iterator TNodeLocalID;
+ TNode2LocalIDMap mapNode2LocalID;
+ list< TNodeLocalID > connectivity;
+ int i, nbConnNodes = 0;
+ std::set< const SMESH_subMesh* > setOfVSubMesh;
+ // iterates on shapes
+ for ( ; idIt != idEnd; idIt++ )
+ {
+ if ( mapOfShIdNb.find( *idIt ) != mapOfShIdNb.end() )
+ continue;
+ SMESH_subMesh* sm = myLocMesh.GetSubMeshContaining(*idIt);
+ if ( !sm || !sm->IsMeshComputed() )
+ continue;
+
+ const TopoDS_Shape& aSh = sm->GetSubShape();
+ const int shDim = myGen.GetShapeDim( aSh );
+ if ( shDim < 1 || shDim > theDimension )
+ continue;
+
+ mapOfShIdNb[ *idIt ] = 0;
+ theShapesId[ mapOfShIdNb.size() - 1 ] = *idIt;
+
+ SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
+ if ( !smDS ) continue;
+
+ if ( theDimension == SMESH::DIM_2D )
+ {
+ SMDS_ElemIteratorPtr faceIt = smDS->GetElements();
+ while ( faceIt->more() )
+ {
+ const SMDS_MeshElement* face = faceIt->next();
+ int aNbNode = face->NbNodes();
+ if ( aNbNode > 4 )
+ aNbNode /= 2; // do not take into account additional middle nodes
+
+ SMDS_MeshNode* node1 = (SMDS_MeshNode*)face->GetNode( 1 );
+ for ( int nIndx = 1; nIndx <= aNbNode; nIndx++ )
+ {
+ SMDS_MeshNode* node2 = (SMDS_MeshNode*)face->GetNode( nIndx < aNbNode ? nIndx+1 : 1 );
+ if ( setOfEdge.insert( SMESH_TLink ( node1, node2 ) ).second )
+ {
+ listOfElemType.push_back( SMDSAbs_Edge );
+ connectivity.push_back
+ ( mapNode2LocalID.insert( make_pair( node1, ++nbConnNodes)).first );
+ connectivity.push_back
+ ( mapNode2LocalID.insert( make_pair( node2, ++nbConnNodes)).first );
+ }
+ node1 = node2;
+ }
+ }
+ }
+ else if ( theDimension == SMESH::DIM_1D )
+ {
+ SMDS_NodeIteratorPtr nodeIt = smDS->GetNodes();
+ while ( nodeIt->more() )
+ {
+ listOfElemType.push_back( SMDSAbs_Node );
+ connectivity.push_back
+ ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first );
+ }
+ // add corner nodes by first vertex from edge
+ SMESH_subMeshIteratorPtr edgeSmIt =
+ sm->getDependsOnIterator(/*includeSelf*/false,
+ /*complexShapeFirst*/false);
+ while ( edgeSmIt->more() )
+ {
+ SMESH_subMesh* vertexSM = edgeSmIt->next();
+ // check that vertex is not already treated
+ if ( !setOfVSubMesh.insert( vertexSM ).second )
+ continue;
+ if ( vertexSM->GetSubShape().ShapeType() != TopAbs_VERTEX )
+ continue;
+
+ const SMESHDS_SubMesh* vertexSmDS = vertexSM->GetSubMeshDS();
+ SMDS_NodeIteratorPtr nodeIt = vertexSmDS->GetNodes();
+ while ( nodeIt->more() )
+ {
+ listOfElemType.push_back( SMDSAbs_Node );
+ connectivity.push_back
+ ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first );
+ }
+ }
+ }
+ }
+
+ // fill node coords and assign local ids to the nodes
+ int nbNodes = mapNode2LocalID.size();
+ result->nodesXYZ.length( nbNodes );
+ TNodeLocalID node2ID = mapNode2LocalID.begin();
+ for ( i = 0; i < nbNodes; ++i, ++node2ID ) {
+ node2ID->second = i;
+ const SMDS_MeshNode* node = (const SMDS_MeshNode*) node2ID->first;
+ result->nodesXYZ[i].x = node->X();
+ result->nodesXYZ[i].y = node->Y();
+ result->nodesXYZ[i].z = node->Z();
+ }
+ // fill connectivity
+ result->elementConnectivities.length( nbConnNodes );
+ list< TNodeLocalID >::iterator connIt = connectivity.begin();
+ for ( i = 0; i < nbConnNodes; ++i, ++connIt ) {
+ result->elementConnectivities[i] = (*connIt)->second;
+ }
+
+ // fill element types
+ result->elementTypes.length( listOfElemType.size() );
+ std::list< SMDSAbs_ElementType >::const_iterator typeIt = listOfElemType.begin();
+ std::list< SMDSAbs_ElementType >::const_iterator typeEnd = listOfElemType.end();
+ for ( i = 0; typeIt != typeEnd; ++i, ++typeIt )
+ {
+ SMDSAbs_ElementType elemType = *typeIt;
+ result->elementTypes[i].SMDS_ElementType = (SMESH::ElementType)elemType;
+ result->elementTypes[i].isPoly = false;
+ result->elementTypes[i].nbNodesInElement = elemType == SMDSAbs_Edge ? 2 : 1;
+ }
+
+ // correct number of shapes
+ theShapesId.length( mapOfShIdNb.size() );
+ }
+ }
+ }
+ catch ( std::bad_alloc ) {
+ INFOS( "Precompute(): lack of memory" );
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ INFOS( "Precompute(): catch exception "<< S_ex.what() );
+ }
+ catch ( ... ) {
+ INFOS( "Precompute(): unknown exception " );
+ }
+ return result._retn();
+}
+
//================================================================================
/*!
* \brief Return geometrical object the given element is built on
@@ -3537,9 +3755,9 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
// "Nodes on Faces" - ID of node on face
// "Face U positions" - U parameter of node on face
// "Face V positions" - V parameter of node on face
- char* aEid_DSName = "Nodes on Edges";
- char* aEu_DSName = "Edge positions";
- char* aFu_DSName = "Face U positions";
+ const char* aEid_DSName = "Nodes on Edges";
+ const char* aEu_DSName = "Edge positions";
+ const char* aFu_DSName = "Face U positions";
//char* aFid_DSName = "Nodes on Faces";
//char* aFv_DSName = "Face V positions";
@@ -3957,6 +4175,25 @@ CORBA::Long SMESH_Gen_i::GetObjectId(CORBA::Object_ptr theObject)
return 0;
}
+//=============================================================================
+/*!
+ * SMESH_Gen_i::SetName
+ *
+ * Set a new object name
+ */
+//=============================================================================
+void SMESH_Gen_i::SetName(const char* theIOR,
+ const char* theName)
+{
+ if ( theIOR && strcmp( theIOR, "" ) ) {
+ CORBA::Object_var anObject = GetORB()->string_to_object( theIOR );
+ SALOMEDS::SObject_var aSO = ObjectToSObject( myCurrentStudy, anObject );
+ if ( !aSO->_is_nil() ) {
+ SetName( aSO, theName );
+ }
+ }
+}
+
//=============================================================================
/*!
* SMESHEngine_factory
diff --git a/src/SMESH_I/SMESH_Gen_i.hxx b/src/SMESH_I/SMESH_Gen_i.hxx
index 452065cd6..defaaf37d 100644
--- a/src/SMESH_I/SMESH_Gen_i.hxx
+++ b/src/SMESH_I/SMESH_Gen_i.hxx
@@ -23,7 +23,6 @@
// File : SMESH_Gen_i.hxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-// $Header$
//
#ifndef _SMESH_GEN_I_HXX_
#define _SMESH_GEN_I_HXX_
@@ -175,6 +174,10 @@ public:
// *****************************************
// Interface methods
// *****************************************
+ // Set a new Mesh object name
+ void SetName(const char* theIOR,
+ const char* theName);
+
//GEOM::GEOM_Gen_ptr SetGeomEngine( const char* containerLoc );
void SetGeomEngine( GEOM::GEOM_Gen_ptr geomcompo );
@@ -197,9 +200,16 @@ public:
SMESH::SMESH_Hypothesis_ptr GetHypothesisParameterValues (const char* theHypType,
const char* theLibName,
SMESH::SMESH_Mesh_ptr theMesh,
- GEOM::GEOM_Object_ptr theGeom)
+ GEOM::GEOM_Object_ptr theGeom,
+ CORBA::Boolean byMesh)
throw ( SALOME::SALOME_Exception );
+ /*!
+ * Sets number of segments per diagonal of boundary box of geometry by which
+ * default segment length of appropriate 1D hypotheses is defined
+ */
+ void SetBoundaryBoxSegmentation( CORBA::Long theNbSegments );
+
// Create empty mesh on a shape
SMESH::SMESH_Mesh_ptr CreateMesh( GEOM::GEOM_Object_ptr theShapeObject )
throw ( SALOME::SALOME_Exception );
@@ -236,6 +246,17 @@ public:
CORBA::Boolean IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh,
GEOM::GEOM_Object_ptr theShapeObject )
throw ( SALOME::SALOME_Exception );
+
+ /*!
+ * Calculate Mesh as preview till indicated dimension on shape
+ * First, verify list of hypothesis associated with the subShape.
+ * Return mesh preview structure
+ */
+ SMESH::MeshPreviewStruct* Precompute( SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Object_ptr theSubObject,
+ SMESH::Dimension theDimension,
+ SMESH::long_array& theShapesId )
+ throw ( SALOME::SALOME_Exception );
// Returns errors of hypotheses definintion
SMESH::algo_error_array* GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh,
diff --git a/src/SMESH_I/SMESH_Group_i.cxx b/src/SMESH_I/SMESH_Group_i.cxx
index f818def66..045e691b9 100644
--- a/src/SMESH_I/SMESH_Group_i.cxx
+++ b/src/SMESH_I/SMESH_Group_i.cxx
@@ -23,7 +23,6 @@
// File : SMESH_Group_i.cxx
// Author : Sergey ANIKIN, OCC
// Module : SMESH
-// $Header$
//
#include "SMESH_Group_i.hxx"
#include "SMESH_Mesh_i.hxx"
@@ -118,20 +117,24 @@ SMESHDS_GroupBase* SMESH_GroupBase_i::GetGroupDS() const
void SMESH_GroupBase_i::SetName( const char* theName )
{
- // Update Python script
- TPythonDump() << _this() << ".SetName( '" << theName << "' )";
-
// Perform renaming
::SMESH_Group* aGroup = GetSmeshGroup();
- if (aGroup) {
- aGroup->SetName(theName);
-
- // Update group name in a study
- SMESH_Gen_i* aGen = myMeshServant->GetGen();
- aGen->SetName( aGen->ObjectToSObject( aGen->GetCurrentStudy(), _this() ), theName );
+ if (!aGroup) {
+ MESSAGE("can't set name of a vague group");
return;
}
- MESSAGE("can't set name of a vague group");
+
+ if ( aGroup->GetName() && !strcmp( aGroup->GetName(), theName ) )
+ return; // nothing to rename
+
+ aGroup->SetName(theName);
+
+ // Update group name in a study
+ SMESH_Gen_i* aGen = myMeshServant->GetGen();
+ aGen->SetName( aGen->ObjectToSObject( aGen->GetCurrentStudy(), _this() ), theName );
+
+ // Update Python script
+ TPythonDump() << _this() << ".SetName( '" << theName << "' )";
}
//=============================================================================
diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx
index 3e9a3fca7..9592ab843 100644
--- a/src/SMESH_I/SMESH_MeshEditor_i.cxx
+++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx
@@ -23,8 +23,7 @@
// File : SMESH_MeshEditor_i.cxx
// Author : Nicolas REJNERI
// Module : SMESH
-// $Header$
-//
+
#include "SMESH_MeshEditor_i.hxx"
#include "SMDS_MeshEdge.hxx"
@@ -3603,9 +3602,9 @@ SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
//=======================================================================
//function : DumpGroupsList
-//purpose :
+//purpose :
//=======================================================================
-void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
+void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
const SMESH::ListOfGroups * theGroupList)
{
bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
@@ -3613,3 +3612,139 @@ void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
theDumpPython << theGroupList << " = ";
}
}
+
+//================================================================================
+/*!
+ \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+ \param theNodes - identifiers of nodes to be doubled
+ \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
+ nodes. If list of element identifiers is empty then nodes are doubled but
+ they not assigned to elements
+ \return TRUE if operation has been completed successfully, FALSE otherwise
+ \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
+*/
+//================================================================================
+
+CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
+ const SMESH::long_array& theModifiedElems )
+{
+ initData();
+
+ ::SMESH_MeshEditor aMeshEditor( myMesh );
+ list< int > aListOfNodes;
+ int i, n;
+ for ( i = 0, n = theNodes.length(); i < n; i++ )
+ aListOfNodes.push_back( theNodes[ i ] );
+
+ list< int > aListOfElems;
+ for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
+ aListOfElems.push_back( theModifiedElems[ i ] );
+
+ bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems );
+
+ storeResult( aMeshEditor) ;
+
+ return aResult;
+}
+
+//================================================================================
+/*!
+ \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+ This method provided for convenience works as DoubleNodes() described above.
+ \param theNodeId - identifier of node to be doubled.
+ \param theModifiedElems - identifiers of elements to be updated.
+ \return TRUE if operation has been completed successfully, FALSE otherwise
+ \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
+*/
+//================================================================================
+
+CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
+ const SMESH::long_array& theModifiedElems )
+{
+ SMESH::long_array_var aNodes = new SMESH::long_array;
+ aNodes->length( 1 );
+ aNodes[ 0 ] = theNodeId;
+ return DoubleNodes( aNodes, theModifiedElems );
+}
+
+//================================================================================
+/*!
+ \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+ This method provided for convenience works as DoubleNodes() described above.
+ \param theNodes - group of nodes to be doubled.
+ \param theModifiedElems - group of elements to be updated.
+ \return TRUE if operation has been completed successfully, FALSE otherwise
+ \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
+*/
+//================================================================================
+
+CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(
+ SMESH::SMESH_GroupBase_ptr theNodes,
+ SMESH::SMESH_GroupBase_ptr theModifiedElems )
+{
+ if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
+ return false;
+
+ SMESH::long_array_var aNodes = theNodes->GetListOfID();
+ SMESH::long_array_var aModifiedElems;
+ if ( !CORBA::is_nil( theModifiedElems ) )
+ aModifiedElems = theModifiedElems->GetListOfID();
+ else
+ {
+ aModifiedElems = new SMESH::long_array;
+ aModifiedElems->length( 0 );
+ }
+
+ return DoubleNodes( aNodes, aModifiedElems );
+}
+
+//================================================================================
+/*!
+ \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+ This method provided for convenience works as DoubleNodes() described above.
+ \param theNodes - list of groups of nodes to be doubled
+ \param theModifiedElems - list of groups of elements to be updated.
+ \return TRUE if operation has been completed successfully, FALSE otherwise
+ \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
+*/
+//================================================================================
+
+CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(
+ const SMESH::ListOfGroups& theNodes,
+ const SMESH::ListOfGroups& theModifiedElems )
+{
+ initData();
+
+ ::SMESH_MeshEditor aMeshEditor( myMesh );
+
+ std::list< int > aNodes;
+ int i, n, j, m;
+ for ( i = 0, n = theNodes.length(); i < n; i++ )
+ {
+ SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
+ if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
+ {
+ SMESH::long_array_var aCurr = aGrp->GetListOfID();
+ for ( j = 0, m = aCurr->length(); j < m; j++ )
+ aNodes.push_back( aCurr[ j ] );
+ }
+ }
+
+ std::list< int > anElems;
+ for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
+ {
+ SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
+ if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
+ {
+ SMESH::long_array_var aCurr = aGrp->GetListOfID();
+ for ( j = 0, m = aCurr->length(); j < m; j++ )
+ anElems.push_back( aCurr[ j ] );
+ }
+ }
+
+ bool aResult = aMeshEditor.DoubleNodes( aNodes, anElems );
+
+ storeResult( aMeshEditor) ;
+
+ return aResult;
+}
diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx
index 609acfdce..eff6e21e4 100644
--- a/src/SMESH_I/SMESH_MeshEditor_i.hxx
+++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx
@@ -23,7 +23,6 @@
// File : SMESH_MeshEditor_i.hxx
// Author : Nicolas REJNERI
// Module : SMESH
-// $Header$
//
#ifndef _SMESH_MESHEDITOR_I_HXX_
#define _SMESH_MESHEDIOTR_I_HXX_
@@ -418,7 +417,18 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
* \retval int - mesh ID
*/
int GetMeshId() const { return myMesh->GetId(); }
+
+ CORBA::Boolean DoubleNodes( const SMESH::long_array& theNodes,
+ const SMESH::long_array& theModifiedElems );
+ CORBA::Boolean DoubleNode( CORBA::Long theNodeId,
+ const SMESH::long_array& theModifiedElems );
+
+ CORBA::Boolean DoubleNodeGroup( SMESH::SMESH_GroupBase_ptr theNodes,
+ SMESH::SMESH_GroupBase_ptr theModifiedElems );
+
+ CORBA::Boolean DoubleNodeGroups( const SMESH::ListOfGroups& theNodes,
+ const SMESH::ListOfGroups& theModifiedElems);
private: //!< private methods
diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx
index cc5e79fbb..f38ecd1fc 100644
--- a/src/SMESH_I/SMESH_Mesh_i.cxx
+++ b/src/SMESH_I/SMESH_Mesh_i.cxx
@@ -23,7 +23,6 @@
// File : SMESH_Mesh_i.cxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-// $Header$
//
#include "SMESH_Mesh_i.hxx"
@@ -208,6 +207,24 @@ void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
TPythonDump() << _this() << ".Clear()";
}
+//================================================================================
+/*!
+ * \brief Remove all nodes and elements for indicated shape
+ */
+//================================================================================
+
+void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
+ throw (SALOME::SALOME_Exception)
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ try {
+ _impl->ClearSubMesh( ShapeID );
+ }
+ catch(SALOME_Exception & S_ex) {
+ THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+ }
+}
+
//=============================================================================
/*!
*
@@ -921,6 +938,85 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr the
}
}
+//=============================================================================
+/*!
+ \brief Union list of groups. New group is created. All mesh elements that are
+ present in initial groups are added to the new one.
+ \param theGroups list of groups
+ \param theName name of group to be created
+ \return pointer on the group
+*/
+//=============================================================================
+SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
+ const char* theName )
+throw (SALOME::SALOME_Exception)
+{
+ if ( !theName )
+ return SMESH::SMESH_Group::_nil();
+
+ try
+ {
+ NCollection_Map< int > anIds;
+ SMESH::ElementType aType = SMESH::ALL;
+ for ( int g = 0, n = theGroups.length(); g < n; g++ )
+ {
+ SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
+ if ( CORBA::is_nil( aGrp ) )
+ continue;
+
+ // check type
+ SMESH::ElementType aCurrType = aGrp->GetType();
+ if ( aType == SMESH::ALL )
+ aType = aCurrType;
+ else
+ {
+ if ( aType != aCurrType )
+ return SMESH::SMESH_Group::_nil();
+ }
+
+ // unite ids
+ SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
+ for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
+ {
+ int aCurrId = aCurrIds[ i ];
+ anIds.Add( aCurrId );
+ }
+ }
+
+ // Create group
+ SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
+ if ( aResGrp->_is_nil() )
+ return SMESH::SMESH_Group::_nil();
+
+ // Create array of identifiers
+ SMESH::long_array_var aResIds = new SMESH::long_array;
+ aResIds->length( anIds.Extent() );
+
+ NCollection_Map< int >::Iterator anIter( anIds );
+ for ( int i = 0; anIter.More(); anIter.Next(), i++ )
+ {
+ aResIds[ i ] = anIter.Value();
+ }
+ aResGrp->Add( aResIds );
+
+ // Clear python lines, created by CreateGroup() and Add()
+ SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+ _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
+ _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
+
+ // Update Python script
+
+ TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
+ << &theGroups << ", '" << theName << "' )";
+
+ return aResGrp._retn();
+ }
+ catch( ... )
+ {
+ return SMESH::SMESH_Group::_nil();
+ }
+}
+
//=============================================================================
/*! IntersectGroups
* New group is created. All mesh elements that are
@@ -975,6 +1071,100 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr
return aResGrp._retn();
}
+//=============================================================================
+/*!
+ \brief Intersect list of groups. New group is created. All mesh elements that
+ are present in all initial groups simultaneously are added to the new one.
+ \param theGroups list of groups
+ \param theName name of group to be created
+ \return pointer on the group
+*/
+//=============================================================================
+SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
+ const SMESH::ListOfGroups& theGroups, const char* theName )
+throw (SALOME::SALOME_Exception)
+{
+ if ( !theName )
+ return SMESH::SMESH_Group::_nil();
+
+ try
+ {
+ NCollection_DataMap< int, int > anIdToCount;
+ SMESH::ElementType aType = SMESH::ALL;
+ for ( int g = 0, n = theGroups.length(); g < n; g++ )
+ {
+ SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
+ if ( CORBA::is_nil( aGrp ) )
+ continue;
+
+ // check type
+ SMESH::ElementType aCurrType = aGrp->GetType();
+ if ( aType == SMESH::ALL )
+ aType = aCurrType;
+ else
+ {
+ if ( aType != aCurrType )
+ return SMESH::SMESH_Group::_nil();
+ }
+
+ // calculates number of occurance ids in groups
+ SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
+ for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
+ {
+ int aCurrId = aCurrIds[ i ];
+ if ( !anIdToCount.IsBound( aCurrId ) )
+ anIdToCount.Bind( aCurrId, 1 );
+ else
+ anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
+ }
+ }
+
+ // create map of ids
+ int nbGrp = theGroups.length();
+ NCollection_Map< int > anIds;
+ NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
+ for ( ; anIter.More(); anIter.Next() )
+ {
+ int aCurrId = anIter.Key();
+ int aCurrNb = anIter.Value();
+ if ( aCurrNb == nbGrp )
+ anIds.Add( aCurrId );
+ }
+
+ // Create group
+ SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
+ if ( aResGrp->_is_nil() )
+ return SMESH::SMESH_Group::_nil();
+
+ // Create array of identifiers
+ SMESH::long_array_var aResIds = new SMESH::long_array;
+ aResIds->length( anIds.Extent() );
+
+ NCollection_Map< int >::Iterator aListIter( anIds );
+ for ( int i = 0; aListIter.More(); aListIter.Next(), i++ )
+ {
+ aResIds[ i ] = aListIter.Value();
+ }
+ aResGrp->Add( aResIds );
+
+ // Clear python lines, created by CreateGroup() and Add()
+ SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+ _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
+ _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
+
+ // Update Python script
+
+ TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
+ << &theGroups << ", '" << theName << "' )";
+
+ return aResGrp._retn();
+ }
+ catch( ... )
+ {
+ return SMESH::SMESH_Group::_nil();
+ }
+}
+
//=============================================================================
/*! CutGroups
* New group is created. All mesh elements that are present in
@@ -1003,7 +1193,6 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGr
for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
aMap2.Add( anIds2[ i2 ] );
-
TColStd_SequenceOfInteger aSeq;
for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
if ( !aMap2.Contains( anIds1[ i1 ] ) )
@@ -1030,6 +1219,281 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGr
return aResGrp._retn();
}
+//=============================================================================
+/*!
+ \brief Cut lists of groups. New group is created. All mesh elements that are
+ present in main groups but do not present in tool groups are added to the new one
+ \param theMainGroups list of main groups
+ \param theToolGroups list of tool groups
+ \param theName name of group to be created
+ \return pointer on the group
+*/
+//=============================================================================
+SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
+ const SMESH::ListOfGroups& theMainGroups,
+ const SMESH::ListOfGroups& theToolGroups,
+ const char* theName )
+ throw (SALOME::SALOME_Exception)
+{
+ if ( !theName )
+ return SMESH::SMESH_Group::_nil();
+
+ try
+ {
+ NCollection_Map< int > aToolIds;
+ SMESH::ElementType aType = SMESH::ALL;
+ int g, n;
+ // iterate through tool groups
+ for ( g = 0, n = theToolGroups.length(); g < n; g++ )
+ {
+ SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
+ if ( CORBA::is_nil( aGrp ) )
+ continue;
+
+ // check type
+ SMESH::ElementType aCurrType = aGrp->GetType();
+ if ( aType == SMESH::ALL )
+ aType = aCurrType;
+ else
+ {
+ if ( aType != aCurrType )
+ return SMESH::SMESH_Group::_nil();
+ }
+
+ // unite tool ids
+ SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
+ for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
+ {
+ int aCurrId = aCurrIds[ i ];
+ aToolIds.Add( aCurrId );
+ }
+ }
+
+ NCollection_Map< int > anIds; // result
+
+ // Iterate through main group
+ for ( g = 0, n = theMainGroups.length(); g < n; g++ )
+ {
+ SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
+ if ( CORBA::is_nil( aGrp ) )
+ continue;
+
+ // check type
+ SMESH::ElementType aCurrType = aGrp->GetType();
+ if ( aType == SMESH::ALL )
+ aType = aCurrType;
+ else
+ {
+ if ( aType != aCurrType )
+ return SMESH::SMESH_Group::_nil();
+ }
+
+ // unite tool ids
+ SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
+ for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
+ {
+ int aCurrId = aCurrIds[ i ];
+ if ( !aToolIds.Contains( aCurrId ) )
+ anIds.Add( aCurrId );
+ }
+ }
+
+ // Create group
+ SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
+ if ( aResGrp->_is_nil() )
+ return SMESH::SMESH_Group::_nil();
+
+ // Create array of identifiers
+ SMESH::long_array_var aResIds = new SMESH::long_array;
+ aResIds->length( anIds.Extent() );
+
+ NCollection_Map< int >::Iterator anIter( anIds );
+ for ( int i = 0; anIter.More(); anIter.Next(), i++ )
+ {
+ aResIds[ i ] = anIter.Value();
+ }
+ aResGrp->Add( aResIds );
+
+ // Clear python lines, created by CreateGroup() and Add()
+ SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+ _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
+ _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
+
+ // Update Python script
+
+ TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
+ << &theMainGroups << ", " << &theToolGroups << ", '"
+ << theName << "' )";
+
+ return aResGrp._retn();
+ }
+ catch( ... )
+ {
+ return SMESH::SMESH_Group::_nil();
+ }
+}
+
+//=============================================================================
+/*!
+ \brief Create groups of entities from existing groups of superior dimensions
+ System
+ 1) extract all nodes from each group,
+ 2) combine all elements of specified dimension laying on these nodes.
+ \param theGroups list of source groups
+ \param theElemType dimension of elements
+ \param theName name of new group
+ \return pointer on new group
+*/
+//=============================================================================
+SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
+ const SMESH::ListOfGroups& theGroups,
+ SMESH::ElementType theElemType,
+ const char* theName )
+ throw (SALOME::SALOME_Exception)
+{
+ SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+
+ if ( !theName || !aMeshDS )
+ return SMESH::SMESH_Group::_nil();
+
+ SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
+
+ try
+ {
+ // Create map of nodes from all groups
+
+ NCollection_Map< int > aNodeMap;
+
+ for ( int g = 0, n = theGroups.length(); g < n; g++ )
+ {
+ SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
+ if ( CORBA::is_nil( aGrp ) )
+ continue;
+
+ SMESH::ElementType aType = aGrp->GetType();
+ if ( aType == SMESH::ALL )
+ continue;
+ else if ( aType == SMESH::NODE )
+ {
+ SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
+ for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
+ {
+ int aCurrId = aCurrIds[ i ];
+ const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
+ if ( aNode )
+ aNodeMap.Add( aNode->GetID() );
+ }
+ }
+ else
+ {
+ SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
+ for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
+ {
+ int aCurrId = aCurrIds[ i ];
+ const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
+ if ( !anElem )
+ continue;
+ SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
+ while( aNodeIter->more() )
+ {
+ const SMDS_MeshNode* aNode =
+ dynamic_cast( aNodeIter->next() );
+ if ( aNode )
+ aNodeMap.Add( aNode->GetID() );
+ }
+ }
+ }
+ }
+
+ // Get result identifiers
+
+ NCollection_Map< int > aResultIds;
+ if ( theElemType == SMESH::NODE )
+ {
+ NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
+ for ( ; aNodeIter.More(); aNodeIter.Next() )
+ aResultIds.Add( aNodeIter.Value() );
+ }
+ else
+ {
+ // Create list of elements of given dimension constructed on the nodes
+ NCollection_Map< int > anElemList;
+ NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
+ for ( ; aNodeIter.More(); aNodeIter.Next() )
+ {
+ const SMDS_MeshElement* aNode =
+ dynamic_cast( aMeshDS->FindNode( aNodeIter.Value() ) );
+ if ( !aNode )
+ continue;
+
+ SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
+ while( anElemIter->more() )
+ {
+ const SMDS_MeshElement* anElem =
+ dynamic_cast( anElemIter->next() );
+ if ( anElem && anElem->GetType() == anElemType )
+ anElemList.Add( anElem->GetID() );
+ }
+ }
+
+ // check whether all nodes of elements are present in nodes map
+ NCollection_Map< int >::Iterator anIter( anElemList );
+ for ( ; anIter.More(); anIter.Next() )
+ {
+ const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() );
+ if ( !anElem )
+ continue;
+
+ bool isOk = true;
+ SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
+ while( aNodeIter->more() )
+ {
+ const SMDS_MeshNode* aNode =
+ dynamic_cast( aNodeIter->next() );
+ if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) )
+ {
+ isOk = false;
+ break;
+ }
+ }
+ if ( isOk )
+ aResultIds.Add( anElem->GetID() );
+ }
+ }
+
+ // Create group
+
+ SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
+ if ( aResGrp->_is_nil() )
+ return SMESH::SMESH_Group::_nil();
+
+ // Create array of identifiers
+ SMESH::long_array_var aResIds = new SMESH::long_array;
+ aResIds->length( aResultIds.Extent() );
+
+ NCollection_Map< int >::Iterator aResIter( aResultIds );
+ for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
+ aResIds[ i ] = aResIter.Value();
+ aResGrp->Add( aResIds );
+
+ // Remove strings corresponding to group creation
+ SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+ _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
+ _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
+
+ // Update Python script
+
+ TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
+ << &theGroups << ", " << theElemType << ", '" << theName << "' )";
+
+ return aResGrp._retn();
+ }
+ catch( ... )
+ {
+ return SMESH::SMESH_Group::_nil();
+ }
+}
+
//================================================================================
/*!
* \brief Return group items of a group present in a study
@@ -1163,6 +1627,74 @@ void SMESH_Mesh_i::CheckGeomGroupModif()
}
}
+//=============================================================================
+/*!
+ * \brief Create standalone group instead if group on geometry
+ *
+ */
+//=============================================================================
+
+SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
+{
+ SMESH::SMESH_Group_var aGroup;
+ if ( theGroup->_is_nil() )
+ return aGroup._retn();
+
+ Unexpect aCatch(SALOME_SalomeException);
+
+ SMESH_GroupBase_i* aGroupToRem =
+ dynamic_cast( SMESH_Gen_i::GetServant( theGroup ).in() );
+ if ( !aGroupToRem )
+ return aGroup._retn();
+
+ int anId = aGroupToRem->GetLocalID();
+ if ( !_impl->ConvertToStandalone( anId ) )
+ return aGroup._retn();
+
+ SMESH_GroupBase_i* aGroupImpl;
+ aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
+
+
+ // remove old instance of group from own map
+ _mapGroups.erase( anId );
+
+ SALOMEDS::StudyBuilder_var builder;
+ SALOMEDS::SObject_var aGroupSO;
+ SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+ if ( !aStudy->_is_nil() ) {
+ builder = aStudy->NewBuilder();
+ aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
+ if ( !aGroupSO->_is_nil() ) {
+
+ // remove reference to geometry
+ SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
+ for ( ; chItr->More(); chItr->Next() )
+ // Remove group's child SObject
+ builder->RemoveObject( chItr->Value() );
+
+ // Update Python script
+ TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
+ << aGroupSO << " )";
+ }
+ }
+
+ // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
+ SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
+ aGroupImpl->Register();
+ // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
+
+ // remember new group in own map
+ aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
+ _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
+
+ // register CORBA object for persistence
+ //int nextId = _gen_i->RegisterObject( aGroup );
+ //if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
+ builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
+
+ return aGroup._retn();
+}
+
//=============================================================================
/*!
*
@@ -1522,22 +2054,14 @@ void SMESH_Mesh_i::ExportToMED (const char* file,
{
Unexpect aCatch(SALOME_SalomeException);
- // Update Python script
- TPythonDump() << _this() << ".ExportToMED( '"
- << file << "', " << auto_groups << ", " << theVersion << " )";
-
// Perform Export
PrepareForWriting(file);
- char* aMeshName = "Mesh";
+ const char* aMeshName = "Mesh";
SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
if ( !aStudy->_is_nil() ) {
SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
if ( !aMeshSO->_is_nil() ) {
aMeshName = aMeshSO->GetName();
- //SCRUTE(file);
- //SCRUTE(aMeshName);
- //SCRUTE(aMeshSO->GetID());
-
// asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
if ( !aStudy->GetProperties()->IsLocked() )
{
@@ -1556,6 +2080,16 @@ void SMESH_Mesh_i::ExportToMED (const char* file,
}
}
}
+ // Update Python script
+ // set name of mesh before export
+ TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
+
+ // check names of groups
+ checkGroupNames();
+
+ TPythonDump() << _this() << ".ExportToMED( '"
+ << file << "', " << auto_groups << ", " << theVersion << " )";
+
_impl->ExportMED( file, aMeshName, auto_groups, theVersion );
}
@@ -1572,6 +2106,8 @@ void SMESH_Mesh_i::ExportDAT (const char *file)
Unexpect aCatch(SALOME_SalomeException);
// Update Python script
+ // check names of groups
+ checkGroupNames();
TPythonDump() << _this() << ".ExportDAT( '" << file << "' )";
// Perform Export
@@ -1585,6 +2121,8 @@ void SMESH_Mesh_i::ExportUNV (const char *file)
Unexpect aCatch(SALOME_SalomeException);
// Update Python script
+ // check names of groups
+ checkGroupNames();
TPythonDump() << _this() << ".ExportUNV( '" << file << "' )";
// Perform Export
@@ -1598,6 +2136,8 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
Unexpect aCatch(SALOME_SalomeException);
// Update Python script
+ // check names of groups
+ checkGroupNames();
TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )";
// Perform Export
@@ -2534,3 +3074,41 @@ SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
}
return res._retn();
}
+
+//=============================================================================
+/*!
+ * \brief Check and correct names of mesh groups
+ */
+//=============================================================================
+
+void SMESH_Mesh_i::checkGroupNames()
+{
+ int nbGrp = NbGroups();
+ if ( !nbGrp )
+ return;
+
+ SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+ if ( aStudy->_is_nil() )
+ return; // nothing to do
+
+ SMESH::ListOfGroups* grpList = 0;
+ // avoid dump of "GetGroups"
+ {
+ // store python dump into a local variable inside local scope
+ SMESH::TPythonDump pDump; // do not delete this line of code
+ grpList = GetGroups();
+ }
+
+ for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
+ SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
+ if ( !aGrp )
+ continue;
+ SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
+ if ( aGrpSO->_is_nil() )
+ continue;
+ // correct name of the mesh group if necessary
+ const char* guiName = aGrpSO->GetName();
+ if ( strcmp(guiName, aGrp->GetName()) )
+ aGrp->SetName( guiName );
+ }
+}
diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx
index c820281e5..a0cd6a7d9 100644
--- a/src/SMESH_I/SMESH_Mesh_i.hxx
+++ b/src/SMESH_I/SMESH_Mesh_i.hxx
@@ -23,7 +23,6 @@
// File : SMESH_Mesh_i.hxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-// $Header$
//
#ifndef _SMESH_MESH_I_HXX_
#define _SMESH_MESH_I_HXX_
@@ -76,6 +75,9 @@ public:
void Clear()
throw (SALOME::SALOME_Exception);
+ void ClearSubMesh(CORBA::Long ShapeID)
+ throw (SALOME::SALOME_Exception);
+
SMESH::Hypothesis_Status AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
SMESH::SMESH_Hypothesis_ptr anHyp)
throw (SALOME::SALOME_Exception);
@@ -117,17 +119,38 @@ public:
SMESH::SMESH_GroupBase_ptr theGroup2,
const char* theName )
throw (SALOME::SALOME_Exception);
+
+ SMESH::SMESH_Group_ptr UnionListOfGroups( const SMESH::ListOfGroups& theGroups,
+ const char* theName)
+ throw (SALOME::SALOME_Exception);
SMESH::SMESH_Group_ptr IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
SMESH::SMESH_GroupBase_ptr theGroup2,
const char* theName )
throw (SALOME::SALOME_Exception);
+
+ SMESH::SMESH_Group_ptr IntersectListOfGroups( const SMESH::ListOfGroups& theGroups,
+ const char* theName )
+ throw (SALOME::SALOME_Exception);
SMESH::SMESH_Group_ptr CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
SMESH::SMESH_GroupBase_ptr theGroup2,
- const char* theName )
+ const char* theName )
throw (SALOME::SALOME_Exception);
+ SMESH::SMESH_Group_ptr CutListOfGroups( const SMESH::ListOfGroups& theMainGroups,
+ const SMESH::ListOfGroups& theToolGroups,
+ const char* theName )
+ throw (SALOME::SALOME_Exception);
+
+ SMESH::SMESH_Group_ptr CreateDimGroup( const SMESH::ListOfGroups& theGroups,
+ SMESH::ElementType theElemType,
+ const char* theName )
+ throw (SALOME::SALOME_Exception);
+
+
+ SMESH::SMESH_Group_ptr ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGeomGroup );
+
// SMESH::string_array* GetLog(CORBA::Boolean clearAfterGet)
// throw (SALOME::SALOME_Exception);
@@ -448,6 +471,12 @@ public:
std::map _mapSubMesh_i; //NRI
std::map _mapSubMesh; //NRI
+private:
+ /*!
+ * Check and correct names of mesh groups
+ */
+ void checkGroupNames();
+
private:
static int myIdGenerator;
diff --git a/src/SMESH_I/SMESH_PythonDump.hxx b/src/SMESH_I/SMESH_PythonDump.hxx
index c1a2be4e1..1ea9f59ff 100644
--- a/src/SMESH_I/SMESH_PythonDump.hxx
+++ b/src/SMESH_I/SMESH_PythonDump.hxx
@@ -55,14 +55,15 @@ public:
*/
static TCollection_AsciiString
ConvertScript(const TCollection_AsciiString& theScript,
- Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod);
+ Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
+ Resource_DataMapOfAsciiStringAsciiString& theObjectNames);
/*!
* \brief Return the name of the python file wrapping IDL API
* \retval TCollection_AsciiString - The file name
*/
- static char* SmeshpyName() { return "smesh"; }
- static char* GenName() { return "smesh.smesh"; }
+ static const char* SmeshpyName() { return "smesh"; }
+ static const char* GenName() { return "smesh.smesh"; }
};
namespace SMESH
@@ -152,8 +153,8 @@ namespace SMESH
TPythonDump&
operator<<(const SMESH::ListOfGroups * theList);
- static char* SMESHGenName() { return "smeshgen"; }
- static char* MeshEditorName() { return "mesh_editor"; }
+ static const char* SMESHGenName() { return "smeshgen"; }
+ static const char* MeshEditorName() { return "mesh_editor"; }
/*!
* \brief Return marker of long string literal beginning
diff --git a/src/SMESH_SWIG/Makefile.am b/src/SMESH_SWIG/Makefile.am
index 0f2b6cb14..7b6ef9fe4 100644
--- a/src/SMESH_SWIG/Makefile.am
+++ b/src/SMESH_SWIG/Makefile.am
@@ -23,7 +23,6 @@
# Author : Nicolas REJNERI, Paul RASCLE
# Modified by : Alexander BORODIN (OCN) - autotools usage
# Module : SMESH
-# $Header$
#
include $(top_srcdir)/adm_local/unix/make_common_starter.am
@@ -58,6 +57,8 @@ dist_salomescript_DATA= \
ex24_cylinder.py \
ex29_refine.py \
ex30_tepal.py \
+ ex30_groupsOp.py \
+ ex31_dimGroup.py \
SMESH_test.py\
SMESH_test0.py\
SMESH_test1.py \
diff --git a/src/SMESH_SWIG/ex30_groupsOp.py b/src/SMESH_SWIG/ex30_groupsOp.py
new file mode 100755
index 000000000..af892e7ff
--- /dev/null
+++ b/src/SMESH_SWIG/ex30_groupsOp.py
@@ -0,0 +1,73 @@
+
+import sys
+import salome
+import geompy
+import math
+import SALOMEDS
+import SMESH
+import smesh
+
+salome.salome_init()
+aStudyId = salome.myStudy._get_StudyId()
+
+geompy.init_geom(salome.myStudy)
+global Face_1
+Face_1 = geompy.MakeFaceHW(100, 100, 1)
+geompy.addToStudy( Face_1, "Face_1" )
+
+#smesh.smesh.SetCurrentStudy(aStudyId)
+import StdMeshers
+pattern = smesh.GetPattern()
+Mesh_1 = smesh.Mesh(Face_1)
+Regular_1D = Mesh_1.Segment()
+Nb_Segments_1 = Regular_1D.NumberOfSegments(10)
+Nb_Segments_1.SetDistrType( 0 )
+Quadrangle_2D = Mesh_1.Quadrangle()
+isDone = Mesh_1.Compute()
+
+# groups creation
+
+aListOfElems = [ 52, 53, 54, 55, 56, 57,
+ 62, 63, 64, 65, 66, 67,
+ 72, 73, 74, 75, 76, 77,
+ 82, 83, 84, 85, 86, 87 ]
+
+aRedGroup = Mesh_1.GetMesh().CreateGroup( smesh.FACE, "Red" )
+aRedGroup.Add( aListOfElems );
+aRedGroup.SetColor( SALOMEDS.Color( 1, 0, 0 ) )
+
+aListOfElems = [ 55, 56, 57, 58, 59,
+ 65, 66, 67, 68, 69,
+ 75, 76, 77, 78, 79,
+ 85, 86, 87, 88, 89,
+ 95, 96, 97, 98, 99,
+ 105, 106, 107, 108, 109,
+ 115, 116, 117, 118, 119,
+ 125, 126, 127, 128, 129 ]
+
+aGreenGroup = Mesh_1.GetMesh().CreateGroup( smesh.FACE, "Green" )
+aGreenGroup.Add( aListOfElems );
+aGreenGroup.SetColor( SALOMEDS.Color( 0, 1, 0 ) )
+
+aListOfElems = [ 63, 64, 65, 66, 67, 68,
+ 73, 74, 75, 76, 77, 78,
+ 83, 84, 85, 86, 87, 88,
+ 93, 94, 95, 96, 97, 98,
+ 103, 104, 105, 106, 107, 108,
+ 113, 114, 115, 116, 117, 118 ]
+
+aBlueGroup = Mesh_1.GetMesh().CreateGroup( smesh.FACE, "Blue" )
+aBlueGroup.Add( aListOfElems );
+aBlueGroup.SetColor( SALOMEDS.Color( 0, 0, 1 ) )
+
+# UnionListOfGroups()
+aUnGrp = Mesh_1.UnionListOfGroups([aRedGroup, aGreenGroup, aBlueGroup], "UnionGrp" )
+
+# IntersectListOfGroups()
+aIntGrp=Mesh_1.IntersectListOfGroups([aRedGroup, aGreenGroup, aBlueGroup], "IntGrp" )
+
+# CutListOfGroups()
+aCutGrp=Mesh_1.CutListOfGroups([aRedGroup],[aGreenGroup,aBlueGroup],"CutGrp")
+
+salome.sg.updateObjBrowser( 1 )
+
diff --git a/src/SMESH_SWIG/ex31_dimGroup.py b/src/SMESH_SWIG/ex31_dimGroup.py
new file mode 100755
index 000000000..13cd9cf26
--- /dev/null
+++ b/src/SMESH_SWIG/ex31_dimGroup.py
@@ -0,0 +1,47 @@
+import sys
+import salome
+import geompy
+import math
+import SALOMEDS
+import SMESH
+import smesh
+
+salome.salome_init()
+aStudyId = salome.myStudy._get_StudyId()
+
+geompy.init_geom(salome.myStudy)
+
+geompy.init_geom(salome.myStudy)
+global Box_1
+Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
+geompy.addToStudy( Box_1, "Box_1" )
+
+#smesh.smesh.SetCurrentStudy(theStudy)
+import StdMeshers
+Mesh_1 = smesh.Mesh(Box_1)
+Regular_1D = Mesh_1.Segment()
+Nb_Segments_1 = Regular_1D.NumberOfSegments(10)
+Nb_Segments_1.SetDistrType( 0 )
+Quadrangle_2D = Mesh_1.Quadrangle()
+Hexa_3D = Mesh_1.Hexahedron()
+isDone = Mesh_1.Compute()
+
+### CreateDimGroup()
+
+aListOf3d_1=range(721,821)
+
+aGrp3D_1=Mesh_1.GetMesh().CreateGroup( smesh.VOLUME, "Src 3D 1" )
+aGrp3D_1.Add( aListOf3d_1 )
+
+aListOf3d_2=range(821, 921)
+aGrp3D_2=Mesh_1.GetMesh().CreateGroup( smesh.VOLUME, "Src 3D 2" )
+aGrp3D_2.Add( aListOf3d_2 )
+
+aGrp2D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], smesh.FACE, "Faces" )
+
+aGrp1D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], smesh.EDGE, "Edges" )
+
+aGrp0D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], smesh.NODE, "Nodes" )
+
+salome.sg.updateObjBrowser( 1 )
+
diff --git a/src/SMESH_SWIG/smeshDC.py b/src/SMESH_SWIG/smeshDC.py
index db8a34ccd..e956e3c43 100644
--- a/src/SMESH_SWIG/smeshDC.py
+++ b/src/SMESH_SWIG/smeshDC.py
@@ -175,18 +175,6 @@ def GetName(obj):
attr = sobj.FindAttribute("AttributeName")[1]
return attr.Value()
-## Sets a name to the object
-def SetName(obj, name):
- if isinstance( obj, Mesh ):
- obj = obj.GetMesh()
- elif isinstance( obj, Mesh_Algorithm ):
- obj = obj.GetAlgorithm()
- ior = salome.orb.object_to_string(obj)
- sobj = salome.myStudy.FindObjectIOR(ior)
- if not sobj is None:
- attr = sobj.FindAttribute("AttributeName")[1]
- attr.SetValue(name)
-
## Prints error message if a hypothesis was not assigned.
def TreatHypoStatus(status, hypName, geomName, isAlgo):
if isAlgo:
@@ -317,6 +305,19 @@ class smeshDC(SMESH._objref_SMESH_Gen):
# From SMESH_Gen interface:
# ------------------------
+ ## Sets the given name to the object
+ # @param obj the object to rename
+ # @param name a new object name
+ # @ingroup l1_auxiliary
+ def SetName(self, obj, name):
+ print "obj_name = ", name
+ if isinstance( obj, Mesh ):
+ obj = obj.GetMesh()
+ elif isinstance( obj, Mesh_Algorithm ):
+ obj = obj.GetAlgorithm()
+ ior = salome.orb.object_to_string(obj)
+ SMESH._objref_SMESH_Gen.SetName(self, ior, name)
+
## Sets the current mode
# @ingroup l1_auxiliary
def SetEmbeddedMode( self,theMode ):
@@ -406,6 +407,13 @@ class smeshDC(SMESH._objref_SMESH_Gen):
def GetPattern(self):
return SMESH._objref_SMESH_Gen.GetPattern(self)
+ ## Sets number of segments per diagonal of boundary box of geometry by which
+ # default segment length of appropriate 1D hypotheses is defined.
+ # Default value is 10
+ # @ingroup l1_auxiliary
+ def SetBoundaryBoxSegmentation(self, nbSegments):
+ SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
+
# Filtering. Auxiliary functions:
# ------------------------------
@@ -477,7 +485,8 @@ class smeshDC(SMESH._objref_SMESH_Gen):
else:
print "Error: The treshold should be a string."
return None
- elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_BadOrientedVolume]:
+ elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_BadOrientedVolume, FT_FreeNodes,
+ FT_FreeFaces, FT_ElemGeomType, FT_GroupColor]:
# At this point the treshold is unnecessary
if aTreshold == FT_LogicalNOT:
aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
@@ -560,6 +569,12 @@ class smeshDC(SMESH._objref_SMESH_Gen):
else:
print "Error: given parameter is not numerucal functor type."
+ ## Creates hypothesis
+ # @param
+ # @param
+ # @return created hypothesis instance
+ def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
+ return SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
import omniORB
#Registering the new proxy for SMESH_Gen
@@ -603,9 +618,9 @@ class Mesh:
else:
self.mesh = self.smeshpyD.CreateEmptyMesh()
if name != 0:
- SetName(self.mesh, name)
+ self.smeshpyD.SetName(self.mesh, name)
elif obj != 0:
- SetName(self.mesh, GetName(obj))
+ self.smeshpyD.SetName(self.mesh, GetName(obj))
if not self.geom:
self.geom = self.mesh.GetShapeToMesh()
@@ -636,7 +651,7 @@ class Mesh:
# @param name a new name of the mesh
# @ingroup l2_construct
def SetName(self, name):
- SetName(self.GetMesh(), name)
+ self.smeshpyD.SetName(self.GetMesh(), name)
## Gets the subMesh object associated to a \a theSubObject geometrical object.
# The subMesh object gives access to the IDs of nodes and elements.
@@ -931,6 +946,16 @@ class Mesh:
smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
salome.sg.updateObjBrowser(1)
+ ## Removes all nodes and elements of indicated shape
+ # @ingroup l2_construct
+ def ClearSubMesh(self, geomId):
+ self.mesh.ClearSubMesh(geomId)
+ if salome.sg.hasDesktop():
+ smeshgui = salome.ImportComponentGUI("SMESH")
+ smeshgui.Init(salome.myStudyId)
+ smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
+ salome.sg.updateObjBrowser(1)
+
## Computes a tetrahedral mesh using AutomaticLength + MEFISTO + NETGEN
# @param fineness [0,-1] defines mesh fineness
# @return True or False
@@ -1245,7 +1270,15 @@ class Mesh:
# @ingroup l2_grps_operon
def UnionGroups(self, group1, group2, name):
return self.mesh.UnionGroups(group1, group2, name)
-
+
+ ## Produces a union list of groups
+ # New group is created. All mesh elements that are present in
+ # initial groups are added to the new one
+ # @return an instance of SMESH_Group
+ # @ingroup l2_grps_operon
+ def UnionListOfGroups(self, groups, name):
+ return self.mesh.UnionListOfGroups(groups, name)
+
## Prodices an intersection of two groups
# A new group is created. All mesh elements that are common
# for the two initial groups are added to the new one.
@@ -1253,16 +1286,46 @@ class Mesh:
# @ingroup l2_grps_operon
def IntersectGroups(self, group1, group2, name):
return self.mesh.IntersectGroups(group1, group2, name)
+
+ ## Produces an intersection of groups
+ # New group is created. All mesh elements that are present in all
+ # initial groups simultaneously are added to the new one
+ # @return an instance of SMESH_Group
+ # @ingroup l2_grps_operon
+ def IntersectListOfGroups(self, groups, name):
+ return self.mesh.IntersectListOfGroups(groups, name)
## Produces a cut of two groups
# A new group is created. All mesh elements that are present in
# the main group but are not present in the tool group are added to the new one
# @return an instance of SMESH_Group
# @ingroup l2_grps_operon
- def CutGroups(self, mainGroup, toolGroup, name):
- return self.mesh.CutGroups(mainGroup, toolGroup, name)
+ def CutGroups(self, main_group, tool_group, name):
+ return self.mesh.CutGroups(main_group, tool_group, name)
+
+ ## Produces a cut of groups
+ # A new group is created. All mesh elements that are present in main groups
+ # but do not present in tool groups are added to the new one
+ # @return an instance of SMESH_Group
+ # @ingroup l2_grps_operon
+ def CutListOfGroups(self, main_groups, tool_groups, name):
+ return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
+
+ ## Produces a group of elements with specified element type using list of existing groups
+ # A new group is created. System
+ # 1) extract all nodes on which groups elements are built
+ # 2) combine all elements of specified dimension laying on these nodes
+ # @return an instance of SMESH_Group
+ # @ingroup l2_grps_operon
+ def CreateDimGroup(self, groups, elem_type, name):
+ return self.mesh.CreateDimGroup(groups, elem_type, name)
+ ## Convert group on geom into standalone group
+ # @ingroup l2_grps_delete
+ def ConvertToStandalone(self, group):
+ return self.mesh.ConvertToStandalone(group)
+
# Get some info about mesh:
# ------------------------
@@ -2718,6 +2781,43 @@ class Mesh:
# @ingroup l1_auxiliary
def GetLastCreatedElems(self):
return self.editor.GetLastCreatedElems()
+
+ ## Creates a hole in a mesh by doubling the nodes of some particular elements
+ # @param theNodes identifiers of nodes to be doubled
+ # @param theModifiedElems identifiers of elements to be updated by the new (doubled)
+ # nodes. If list of element identifiers is empty then nodes are doubled but
+ # they not assigned to elements
+ # @return TRUE if operation has been completed successfully, FALSE otherwise
+ # @ingroup l2_modif_edit
+ def DoubleNodes(self, theNodes, theModifiedElems):
+ return self.editor.DoubleNodes(theNodes, theModifiedElems)
+
+ ## Creates a hole in a mesh by doubling the nodes of some particular elements
+ # This method provided for convenience works as DoubleNodes() described above.
+ # @param theNodes identifiers of node to be doubled
+ # @param theModifiedElems identifiers of elements to be updated
+ # @return TRUE if operation has been completed successfully, FALSE otherwise
+ # @ingroup l2_modif_edit
+ def DoubleNode(self, theNodeId, theModifiedElems):
+ return self.editor.DoubleNode(theNodeId, theModifiedElems)
+
+ ## Creates a hole in a mesh by doubling the nodes of some particular elements
+ # This method provided for convenience works as DoubleNodes() described above.
+ # @param theNodes group of nodes to be doubled
+ # @param theModifiedElems group of elements to be updated.
+ # @return TRUE if operation has been completed successfully, FALSE otherwise
+ # @ingroup l2_modif_edit
+ def DoubleNodeGroup(self, theNodes, theModifiedElems):
+ return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
+
+ ## Creates a hole in a mesh by doubling the nodes of some particular elements
+ # This method provided for convenience works as DoubleNodes() described above.
+ # @param theNodes list of groups of nodes to be doubled
+ # @param theModifiedElems list of groups of elements to be updated.
+ # @return TRUE if operation has been completed successfully, FALSE otherwise
+ # @ingroup l2_modif_edit
+ def DoubleNodeGroups(self, theNodes, theModifiedElems):
+ return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
## The mother class to define algorithm, it is not recommended to use it directly.
#
@@ -2838,7 +2938,7 @@ class Mesh_Algorithm:
## Sets the name to the algorithm
def SetName(self, name):
- SetName(self.algo, name)
+ self.mesh.smeshpyD.SetName(self.algo, name)
## Gets the id of the algorithm
def GetId(self):
@@ -2901,7 +3001,7 @@ class Mesh_Algorithm:
s = ","
i = i + 1
pass
- SetName(hypo, hyp + a)
+ self.mesh.smeshpyD.SetName(hypo, hyp + a)
pass
status = self.mesh.mesh.AddHypothesis(self.geom, hypo)
TreatHypoStatus( status, GetName(hypo), GetName(self.geom), 0 )
@@ -2951,6 +3051,32 @@ class Mesh_Segment(Mesh_Algorithm):
return IsEqual(hyp.GetPrecision(), args[1])
return False
+ ## Defines "MaxSize" hypothesis to cut an edge into segments not longer than given value
+ # @param length is optional maximal allowed length of segment, if it is omitted
+ # the preestimated length is used that depends on geometry size
+ # @param UseExisting if ==true - searches for an existing hypothesis created with
+ # the same parameters, else (default) - create a new one
+ # @return an instance of StdMeshers_MaxLength hypothesis
+ # @ingroup l3_hypos_1dhyps
+ def MaxSize(self, length=0.0, UseExisting=0):
+ hyp = self.Hypothesis("MaxLength", [length], UseExisting=UseExisting)
+ if length > 0.0:
+ # set given length
+ hyp.SetLength(length)
+ if not UseExisting:
+ # set preestimated length
+ gen = self.mesh.smeshpyD
+ initHyp = gen.GetHypothesisParameterValues("MaxLength", "libStdMeshersEngine.so",
+ self.mesh.GetMesh(), self.mesh.GetShape(),
+ False) # <- byMesh
+ preHyp = initHyp._narrow(StdMeshers.StdMeshers_MaxLength)
+ if preHyp:
+ hyp.SetPreestimatedLength( preHyp.GetPreestimatedLength() )
+ pass
+ pass
+ hyp.SetUsePreestimatedLength( length == 0.0 )
+ return hyp
+
## Defines "NumberOfSegments" hypothesis to cut an edge in a fixed number of segments
# @param n for the number of segments that cut an edge
# @param s for the scale factor (optional)
diff --git a/src/StdMeshers/Makefile.am b/src/StdMeshers/Makefile.am
index ddf7bd64f..8b86e0958 100644
--- a/src/StdMeshers/Makefile.am
+++ b/src/StdMeshers/Makefile.am
@@ -66,7 +66,9 @@ salomeinclude_HEADERS = \
StdMeshers_UseExisting_1D2D.hxx \
StdMeshers_QuadToTriaAdaptor.hxx \
SMESH_StdMeshers.hxx \
- StdMeshers_TrianglePreference.hxx
+ StdMeshers_TrianglePreference.hxx \
+ StdMeshers_CompositeHexa_3D.hxx \
+ StdMeshers_MaxLength.hxx
# Libraries targets
@@ -109,7 +111,9 @@ dist_libStdMeshers_la_SOURCES = \
StdMeshers_CompositeSegment_1D.cxx \
StdMeshers_UseExisting_1D2D.cxx \
StdMeshers_QuadToTriaAdaptor.cxx \
- StdMeshers_TrianglePreference.cxx
+ StdMeshers_TrianglePreference.cxx \
+ StdMeshers_CompositeHexa_3D.cxx \
+ StdMeshers_MaxLength.cxx
# additionnal information to compil and link file
diff --git a/src/StdMeshers/StdMeshers_Arithmetic1D.cxx b/src/StdMeshers/StdMeshers_Arithmetic1D.cxx
index f13cf571b..5b63f922b 100644
--- a/src/StdMeshers/StdMeshers_Arithmetic1D.cxx
+++ b/src/StdMeshers/StdMeshers_Arithmetic1D.cxx
@@ -23,7 +23,6 @@
// File : StdMeshers_Arithmetic1D.cxx
// Author : Damien COQUERET, OCC
// Module : SMESH
-// $Header$
//
#include "StdMeshers_Arithmetic1D.hxx"
@@ -196,3 +195,17 @@ bool StdMeshers_Arithmetic1D::SetParametersByMesh(const SMESH_Mesh* theMesh,
}
return nbEdges;
}
+
+//================================================================================
+/*!
+ * \brief Initialize my parameter values by linear size of mesh element.
+ * \retval bool - true if parameter values have been successfully defined
+ */
+//================================================================================
+
+bool StdMeshers_Arithmetic1D::SetParametersByElementSize(double elemLenght,
+ const SMESH_Mesh* /*mesh*/)
+{
+ return bool( _begLength = _endLength = elemLenght );
+}
+
diff --git a/src/StdMeshers/StdMeshers_Arithmetic1D.hxx b/src/StdMeshers/StdMeshers_Arithmetic1D.hxx
index 04c136503..fb8075d1c 100644
--- a/src/StdMeshers/StdMeshers_Arithmetic1D.hxx
+++ b/src/StdMeshers/StdMeshers_Arithmetic1D.hxx
@@ -23,7 +23,6 @@
// File : StdMeshers_Arithmetic1D.hxx
// Author : Damien COQUERET, OCC
// Module : SMESH
-// $Header$
//
#ifndef _SMESH_ARITHMETIC1D_HXX_
#define _SMESH_ARITHMETIC1D_HXX_
@@ -57,6 +56,12 @@ public:
*/
virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
+ /*!
+ * \brief Initialize my parameter values by linear size of mesh element.
+ * \retval bool - true if parameter values have been successfully defined
+ */
+ virtual bool SetParametersByElementSize( double elemLenght, const SMESH_Mesh* theMesh=0);
+
protected:
double _begLength, _endLength;
};
diff --git a/src/StdMeshers/StdMeshers_AutomaticLength.cxx b/src/StdMeshers/StdMeshers_AutomaticLength.cxx
index 8e2fab30c..3e91de780 100644
--- a/src/StdMeshers/StdMeshers_AutomaticLength.cxx
+++ b/src/StdMeshers/StdMeshers_AutomaticLength.cxx
@@ -23,7 +23,6 @@
// File : StdMeshers_AutomaticLength.cxx
// Author : Edward AGAPOV, OCC
// Module : SMESH
-// $Header$
//
#include "StdMeshers_AutomaticLength.hxx"
@@ -367,3 +366,37 @@ bool StdMeshers_AutomaticLength::SetParametersByMesh(const SMESH_Mesh* theMesh
return nbEdges;
}
+
+//================================================================================
+/*!
+ * \brief Initialize my parameter values by linear size of mesh element.
+ * \retval bool - true if parameter values have been successfully defined
+ */
+//================================================================================
+
+bool StdMeshers_AutomaticLength::SetParametersByElementSize(double elemLenght,
+ const SMESH_Mesh* theMesh)
+{
+ return false;
+
+ // assure the base automatic length is stored in _TShapeToLength
+// GetLength( theMesh, elemLenght );
+
+// // find maximal edge length
+// double maxLen = 0;
+// map::iterator
+// tshape_length = _TShapeToLength.begin(), slEnd = _TShapeToLength.end();
+// for ( ; tshape_length != slEnd; ++tshape_length )
+// if ( tshape_length->second > maxLen )
+// maxLen = tshape_length->second;
+
+// // automatic length for longest element
+// double autoLen = GetLength( theMesh, maxLen );
+
+// // elemLenght = autoLen / (theCoarseConst + theFineConst * _fineness) -->
+// _fineness = ( autoLen / elemLenght - theCoarseConst ) / theFineConst;
+
+// return true;
+}
+
+
diff --git a/src/StdMeshers/StdMeshers_AutomaticLength.hxx b/src/StdMeshers/StdMeshers_AutomaticLength.hxx
index 387c8b58e..1ce7d30d5 100644
--- a/src/StdMeshers/StdMeshers_AutomaticLength.hxx
+++ b/src/StdMeshers/StdMeshers_AutomaticLength.hxx
@@ -23,8 +23,7 @@
// File : StdMeshers_AutomaticLength.hxx
// Author : Edward AGAPOV, OCC
// Module : SMESH
-// $Header$
-//
+
#ifndef _SMESH_AutomaticLength_HXX_
#define _SMESH_AutomaticLength_HXX_
@@ -96,6 +95,12 @@ public:
*/
virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
+ /*!
+ * \brief Initialize my parameter values by linear size of mesh element.
+ * \retval bool - true if parameter values have been successfully defined
+ */
+ virtual bool SetParametersByElementSize( double elemLenght, const SMESH_Mesh* theMesh=0);
+
protected:
std::map _TShapeToLength;
const SMESH_Mesh* _mesh;
diff --git a/src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx b/src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx
new file mode 100644
index 000000000..42acee19e
--- /dev/null
+++ b/src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx
@@ -0,0 +1,1526 @@
+// SMESH SMESH : implementaion of SMESH idl descriptions
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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.
+//
+// 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 : StdMeshers_CompositeHexa_3D.cxx
+// Module : SMESH
+// Created : Tue Nov 25 11:04:59 2008
+// Author : Edward AGAPOV (eap)
+
+#include "StdMeshers_CompositeHexa_3D.hxx"
+
+#include "SMDS_Mesh.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_SetIterator.hxx"
+#include "SMESH_Block.hxx"
+#include "SMESH_Comment.hxx"
+#include "SMESH_ComputeError.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MeshEditor.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_subMesh.hxx"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+
+#ifdef _DEBUG_
+
+// #define DEB_FACES
+// #define DEB_GRID
+#define DUMP_VERT(msg,V) \
+// { TopoDS_Vertex v = V; gp_Pnt p = BRep_Tool::Pnt(v);\
+// cout << msg << "( "<< p.X()<<", "<& edges);
+ _FaceSide* GetSide(const int i);
+ const _FaceSide* GetSide(const int i) const;
+ int size() { return myChildren.size(); }
+ int NbVertices() const;
+ TopoDS_Vertex FirstVertex() const;
+ TopoDS_Vertex LastVertex() const;
+ TopoDS_Vertex Vertex(int i) const;
+ bool Contain( const _FaceSide& side, int* which=0 ) const;
+ bool Contain( const TopoDS_Vertex& vertex ) const;
+ void AppendSide( const _FaceSide& side );
+ void SetBottomSide( int i );
+ int GetNbSegments(SMESH_Mesh& mesh) const;
+ bool StoreNodes(SMESH_Mesh& mesh, vector& myGrid, bool reverse );
+ void SetID(EQuadSides id) { myID = id; }
+ static inline const TopoDS_TShape* ptr(const TopoDS_Shape& theShape)
+ { return theShape.TShape().operator->(); }
+ void Dump() const;
+
+private:
+
+
+ TopoDS_Edge myEdge;
+ list< _FaceSide > myChildren;
+ int myNbChildren;
+
+ //set myVertices;
+ TopTools_MapOfShape myVertices;
+
+ EQuadSides myID; // debug
+};
+//================================================================================
+/*!
+ * \brief Class corresponding to a meshed composite face of a box.
+ * Provides simplified access to it's sub-mesh data.
+ */
+class _QuadFaceGrid
+{
+ typedef list< _QuadFaceGrid > TChildren;
+public:
+ _QuadFaceGrid();
+
+public: //** Methods to find and orient faces of 6 sides of the box **//
+
+ //!< initialization
+ bool Init(const TopoDS_Face& f);
+
+ //!< try to unite self with other face
+ bool AddContinuousFace( const _QuadFaceGrid& f );
+
+ //!< Try to set the side as bottom hirizontal side
+ bool SetBottomSide(const _FaceSide& side, int* sideIndex=0);
+
+ //!< Return face adjacent to i-th side of this face
+ _QuadFaceGrid* FindAdjacentForSide(int i, vector<_QuadFaceGrid>& faces) const; // (0 TChildIterator;
+
+ TChildIterator GetChildren() const
+ { return TChildIterator( myChildren.begin(), myChildren.end()); }
+
+public: //** Loading and access to mesh **//
+
+ //!< Load nodes of a mesh
+ bool LoadGrid( SMESH_Mesh& mesh );
+
+ //!< Return number of segments on the hirizontal sides
+ int GetNbHoriSegments(SMESH_Mesh& mesh, bool withBrothers=false) const;
+
+ //!< Return number of segments on the vertical sides
+ int GetNbVertSegments(SMESH_Mesh& mesh, bool withBrothers=false) const;
+
+ //!< Return a node by its position
+ const SMDS_MeshNode* GetNode(int iHori, int iVert) const;
+
+ //!< Return node coordinates by its position
+ gp_XYZ GetXYZ(int iHori, int iVert) const;
+
+public: //** Access to member fields **//
+
+ //!< Return i-th face side (0IsOK() ); }
+
+ bool loadCompositeGrid(SMESH_Mesh& mesh);
+
+ bool fillGrid(SMESH_Mesh& theMesh,
+ vector & theGrid,
+ const _Indexer& theIndexer,
+ int theX,
+ int theY);
+
+ bool locateChildren();
+
+ void setBrothers( set< _QuadFaceGrid* >& notLocatedBrothers );
+
+ TopoDS_Face myFace;
+ _FaceSide mySides;
+ bool myReverse;
+
+ TChildren myChildren;
+
+ _QuadFaceGrid* myLeftBottomChild;
+ _QuadFaceGrid* myRightBrother;
+ _QuadFaceGrid* myUpBrother;
+
+ _Indexer myIndexer;
+ vector myGrid;
+
+ SMESH_ComputeErrorPtr myError;
+
+ EBoxSides myID; // debug
+};
+
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+StdMeshers_CompositeHexa_3D::StdMeshers_CompositeHexa_3D(int hypId, int studyId, SMESH_Gen* gen)
+ :SMESH_3D_Algo(hypId, studyId, gen)
+{
+ _name = "CompositeHexa_3D";
+ _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit /shape type
+}
+
+//================================================================================
+/*!
+ * \brief always return true
+ */
+//================================================================================
+
+bool StdMeshers_CompositeHexa_3D::CheckHypothesis(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ Hypothesis_Status& aStatus)
+{
+ aStatus = HYP_OK;
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief Computes hexahedral mesh on a box with composite sides
+ * \param aMesh - mesh to compute
+ * \param aShape - shape to mesh
+ * \retval bool - succes sign
+ */
+//================================================================================
+
+bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh& theMesh,
+ const TopoDS_Shape& theShape)
+{
+ SMESH_MesherHelper helper( theMesh );
+ _quadraticMesh = helper.IsQuadraticSubMesh( theShape );
+ helper.SetElementsOnShape( true );
+
+ // -------------------------
+ // Try to find 6 side faces
+ // -------------------------
+ vector< _QuadFaceGrid > boxFaces; boxFaces.reserve( 6 );
+ TopExp_Explorer exp;
+ int iFace, nbFaces = 0;
+ for ( exp.Init(theShape, TopAbs_FACE); exp.More(); exp.Next(), ++nbFaces )
+ {
+ _QuadFaceGrid f;
+ if ( !f.Init( TopoDS::Face( exp.Current() )))
+ return error (COMPERR_BAD_SHAPE);
+ bool isContinuous = false;
+ for ( int i=0; i < boxFaces.size() && !isContinuous; ++i )
+ isContinuous = boxFaces[ i ].AddContinuousFace( f );
+ if ( !isContinuous )
+ boxFaces.push_back( f );
+ }
+ // Check what we have
+ if ( boxFaces.size() != 6 && nbFaces != 6)
+ return error
+ (COMPERR_BAD_SHAPE,
+ SMESH_Comment("Can't find 6 sides of a box. Number of found sides - ")<FindAdjacentForSide( Q_BOTTOM, boxFaces );
+ fLeft = fBottom->FindAdjacentForSide( Q_RIGHT, boxFaces );
+ fBack = fBottom->FindAdjacentForSide( Q_TOP, boxFaces );
+ fRight = fBottom->FindAdjacentForSide( Q_LEFT, boxFaces );
+ // check the found
+ if ( !fFront || !fBack || !fLeft || !fRight )
+ return error(COMPERR_BAD_SHAPE);
+ // top face
+ fTop = 0;
+ for ( int i=1; i < boxFaces.size() && !fTop; ++i ) {
+ fTop = & boxFaces[ i ];
+ if ( fTop==fFront || fTop==fLeft || fTop==fBack || fTop==fRight )
+ fTop = 0;
+ }
+ // set bottom of the top side
+ if ( !fTop->SetBottomSide( fFront->GetSide( Q_TOP ) )) {
+ if ( !fFront->IsComplex() )
+ return error( ERR_LI("Error in StdMeshers_CompositeHexa_3D::Compute()"));
+ else {
+ _QuadFaceGrid::TChildIterator chIt = fFront->GetChildren();
+ while ( chIt.more() ) {
+ const _QuadFaceGrid& frontChild = chIt.next();
+ if ( fTop->SetBottomSide( frontChild.GetSide( Q_TOP )))
+ break;
+ }
+ }
+ }
+ if ( !fTop )
+ return error(COMPERR_BAD_SHAPE);
+
+ fBottom->SetID( B_BOTTOM );
+ fBack ->SetID( B_BACK );
+ fLeft ->SetID( B_LEFT );
+ fFront ->SetID( B_FRONT );
+ fRight ->SetID( B_RIGHT );
+ fTop ->SetID( B_TOP );
+
+ // orient bottom egde of faces along axes of the unit box
+ fBottom->ReverseEdges();
+ fBack ->ReverseEdges();
+ fLeft ->ReverseEdges();
+
+ // ------------------------------------------
+ // Fill columns of nodes with existing nodes
+ // ------------------------------------------
+
+ // let faces load their grids
+ if ( !fBottom->LoadGrid( theMesh )) return error( fBottom->GetError() );
+ if ( !fBack ->LoadGrid( theMesh )) return error( fBack ->GetError() );
+ if ( !fLeft ->LoadGrid( theMesh )) return error( fLeft ->GetError() );
+ if ( !fFront ->LoadGrid( theMesh )) return error( fFront ->GetError() );
+ if ( !fRight ->LoadGrid( theMesh )) return error( fRight ->GetError() );
+ if ( !fTop ->LoadGrid( theMesh )) return error( fTop ->GetError() );
+
+ int x, xSize = fBottom->GetNbHoriSegments(theMesh) + 1, X = xSize - 1;
+ int y, ySize = fBottom->GetNbVertSegments(theMesh) + 1, Y = ySize - 1;
+ int z, zSize = fFront ->GetNbVertSegments(theMesh) + 1, Z = zSize - 1;
+ _Indexer colIndex( xSize, ySize );
+ vector< vector< const SMDS_MeshNode* > > columns( colIndex.size() );
+
+ // fill node columns by front and back box sides
+ for ( x = 0; x < xSize; ++x ) {
+ vector< const SMDS_MeshNode* >& column0 = columns[ colIndex( x, 0 )];
+ vector< const SMDS_MeshNode* >& column1 = columns[ colIndex( x, Y )];
+ column0.resize( zSize );
+ column1.resize( zSize );
+ for ( z = 0; z < zSize; ++z ) {
+ column0[ z ] = fFront->GetNode( x, z );
+ column1[ z ] = fBack ->GetNode( x, z );
+ }
+ }
+ // fill node columns by left and right box sides
+ for ( y = 1; y < ySize-1; ++y ) {
+ vector< const SMDS_MeshNode* >& column0 = columns[ colIndex( 0, y )];
+ vector< const SMDS_MeshNode* >& column1 = columns[ colIndex( X, y )];
+ column0.resize( zSize );
+ column1.resize( zSize );
+ for ( z = 0; z < zSize; ++z ) {
+ column0[ z ] = fLeft ->GetNode( y, z );
+ column1[ z ] = fRight->GetNode( y, z );
+ }
+ }
+ // get nodes from top and bottom box sides
+ for ( x = 1; x < xSize-1; ++x ) {
+ for ( y = 1; y < ySize-1; ++y ) {
+ vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )];
+ column.resize( zSize );
+ column.front() = fBottom->GetNode( x, y );
+ column.back() = fTop ->GetNode( x, y );
+ }
+ }
+
+ // ----------------------------
+ // Add internal nodes of a box
+ // ----------------------------
+ // projection points of internal nodes on box subshapes by which
+ // coordinates of internal nodes are computed
+ vector pointsOnShapes( SMESH_Block::ID_Shell );
+
+ // projections on vertices are constant
+ pointsOnShapes[ SMESH_Block::ID_V000 ] = fBottom->GetXYZ( 0, 0 );
+ pointsOnShapes[ SMESH_Block::ID_V100 ] = fBottom->GetXYZ( X, 0 );
+ pointsOnShapes[ SMESH_Block::ID_V010 ] = fBottom->GetXYZ( 0, Y );
+ pointsOnShapes[ SMESH_Block::ID_V110 ] = fBottom->GetXYZ( X, Y );
+ pointsOnShapes[ SMESH_Block::ID_V001 ] = fTop->GetXYZ( 0, 0 );
+ pointsOnShapes[ SMESH_Block::ID_V101 ] = fTop->GetXYZ( X, 0 );
+ pointsOnShapes[ SMESH_Block::ID_V011 ] = fTop->GetXYZ( 0, Y );
+ pointsOnShapes[ SMESH_Block::ID_V111 ] = fTop->GetXYZ( X, Y );
+
+ for ( x = 1; x < xSize-1; ++x )
+ {
+ gp_XYZ params; // normalized parameters of internal node within a unit box
+ params.SetCoord( 1, x / double(X) );
+ for ( y = 1; y < ySize-1; ++y )
+ {
+ params.SetCoord( 2, y / double(Y) );
+ // column to fill during z loop
+ vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )];
+ // points projections on horizontal edges
+ pointsOnShapes[ SMESH_Block::ID_Ex00 ] = fBottom->GetXYZ( x, 0 );
+ pointsOnShapes[ SMESH_Block::ID_Ex10 ] = fBottom->GetXYZ( x, Y );
+ pointsOnShapes[ SMESH_Block::ID_E0y0 ] = fBottom->GetXYZ( 0, y );
+ pointsOnShapes[ SMESH_Block::ID_E1y0 ] = fBottom->GetXYZ( X, y );
+ pointsOnShapes[ SMESH_Block::ID_Ex01 ] = fTop->GetXYZ( x, 0 );
+ pointsOnShapes[ SMESH_Block::ID_Ex11 ] = fTop->GetXYZ( x, Y );
+ pointsOnShapes[ SMESH_Block::ID_E0y1 ] = fTop->GetXYZ( 0, y );
+ pointsOnShapes[ SMESH_Block::ID_E1y1 ] = fTop->GetXYZ( X, y );
+ // points projections on horizontal faces
+ pointsOnShapes[ SMESH_Block::ID_Fxy0 ] = fBottom->GetXYZ( x, y );
+ pointsOnShapes[ SMESH_Block::ID_Fxy1 ] = fTop ->GetXYZ( x, y );
+ for ( z = 1; z < zSize-1; ++z ) // z loop
+ {
+ params.SetCoord( 3, z / double(Z) );
+ // point projections on vertical edges
+ pointsOnShapes[ SMESH_Block::ID_E00z ] = fFront->GetXYZ( 0, z );
+ pointsOnShapes[ SMESH_Block::ID_E10z ] = fFront->GetXYZ( X, z );
+ pointsOnShapes[ SMESH_Block::ID_E01z ] = fBack->GetXYZ( 0, z );
+ pointsOnShapes[ SMESH_Block::ID_E11z ] = fBack->GetXYZ( X, z );
+ // point projections on vertical faces
+ pointsOnShapes[ SMESH_Block::ID_Fx0z ] = fFront->GetXYZ( x, z );
+ pointsOnShapes[ SMESH_Block::ID_Fx1z ] = fBack ->GetXYZ( x, z );
+ pointsOnShapes[ SMESH_Block::ID_F0yz ] = fLeft ->GetXYZ( y, z );
+ pointsOnShapes[ SMESH_Block::ID_F1yz ] = fRight->GetXYZ( y, z );
+
+ // compute internal node coordinates
+ gp_XYZ coords;
+ SMESH_Block::ShellPoint( params, pointsOnShapes, coords );
+ column[ z ] = helper.AddNode( coords.X(), coords.Y(), coords.Z() );
+
+#ifdef DEB_GRID
+ // debug
+ //cout << "----------------------------------------------------------------------"<& col00 = columns[ colIndex( x, y )];
+ vector< const SMDS_MeshNode* >& col10 = columns[ colIndex( x+1, y )];
+ vector< const SMDS_MeshNode* >& col01 = columns[ colIndex( x, y+1 )];
+ vector< const SMDS_MeshNode* >& col11 = columns[ colIndex( x+1, y+1 )];
+ for ( z = 0; z < zSize-1; ++z )
+ {
+ // bottom face normal of a hexa mush point outside the volume
+ helper.AddVolume(col00[z], col01[z], col11[z], col10[z],
+ col00[z+1], col01[z+1], col11[z+1], col10[z+1]);
+ }
+ }
+ }
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief constructor of non-initialized _QuadFaceGrid
+ */
+//================================================================================
+
+_QuadFaceGrid::_QuadFaceGrid():
+ myReverse(false), myRightBrother(0), myUpBrother(0), myIndexer(0,0), myID(B_UNDEFINED)
+{
+}
+
+//================================================================================
+/*!
+ * \brief Initialization
+ */
+//================================================================================
+
+bool _QuadFaceGrid::Init(const TopoDS_Face& f)
+{
+ myFace = f;
+ mySides = _FaceSide();
+ myReverse = false;
+ myLeftBottomChild = myRightBrother = myUpBrother = 0;
+ myChildren.clear();
+ myGrid.clear();
+ //if ( myFace.Orientation() != TopAbs_FORWARD )
+ //myFace.Reverse();
+
+ TopoDS_Vertex V;
+ list< TopoDS_Edge > edges;
+ list< int > nbEdgesInWire;
+ int nbWire = SMESH_Block::GetOrderedEdges (myFace, V, edges, nbEdgesInWire);
+ if ( nbWire != 1 )
+ return false;
+
+ list< TopoDS_Edge >::iterator edgeIt = edges.begin();
+ if ( nbEdgesInWire.front() == 4 ) // exactly 4 edges
+ {
+ for ( ; edgeIt != edges.end(); ++edgeIt )
+ mySides.AppendSide( _FaceSide( *edgeIt ));
+ }
+ else if ( nbEdgesInWire.front() > 4 ) { // more than 4 edges - try to unite some
+ list< TopoDS_Edge > sideEdges;
+ while ( !edges.empty()) {
+ sideEdges.clear();
+ sideEdges.splice( sideEdges.end(), edges, edges.begin());// edges.front()->sideEdges.back()
+ while ( !edges.empty() ) {
+ if ( SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() )) {
+ sideEdges.splice( sideEdges.end(), edges, edges.begin());
+ }
+ else if ( SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() )) {
+ sideEdges.splice( sideEdges.begin(), edges, --edges.end());
+ }
+ else {
+ break;
+ }
+ }
+ mySides.AppendSide( _FaceSide( sideEdges ));
+ }
+ }
+ if (mySides.size() != 4)
+ return false;
+
+#ifdef _DEBUG_
+ mySides.GetSide( Q_BOTTOM )->SetID( Q_BOTTOM );
+ mySides.GetSide( Q_RIGHT )->SetID( Q_RIGHT );
+ mySides.GetSide( Q_TOP )->SetID( Q_TOP );
+ mySides.GetSide( Q_LEFT )->SetID( Q_LEFT );
+#endif
+
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief Try to unite self with other ordinary face
+ */
+//================================================================================
+
+bool _QuadFaceGrid::AddContinuousFace( const _QuadFaceGrid& other )
+{
+ for ( int i = 0; i < 4; ++i ) {
+ const _FaceSide& otherSide = other.GetSide( i );
+ int iMyCommon;
+ if ( mySides.Contain( otherSide, &iMyCommon ) ) {
+ // check if normals of two faces are collinear at all vertices of a otherSide
+ const double angleTol = PI / 180 / 2;
+ int iV, nbV = otherSide.NbVertices(), nbCollinear = 0;
+ for ( iV = 0; iV < nbV; ++iV )
+ {
+ TopoDS_Vertex v = otherSide.Vertex( iV );
+ gp_Vec n1, n2;
+ if ( !GetNormal( v, n1 ) || !other.GetNormal( v, n2 ))
+ continue;
+ if ( n1 * n2 < 0 )
+ n1.Reverse();
+ if ( n1.Angle(n2) < angleTol )
+ nbCollinear++;
+ else
+ break;
+ }
+ if ( nbCollinear > 1 ) { // this face becomes composite if not yet is
+ DUMP_VERT("Cont 1", mySides.GetSide(iMyCommon)->FirstVertex());
+ DUMP_VERT("Cont 2", mySides.GetSide(iMyCommon)->LastVertex());
+ DUMP_VERT("Cont 3", otherSide.FirstVertex());
+ DUMP_VERT("Cont 4", otherSide.LastVertex());
+ if ( myChildren.empty() ) {
+ myChildren.push_back( *this );
+ myFace.Nullify();
+ }
+ myChildren.push_back( other );
+ int otherBottomIndex = ( 4 + i - iMyCommon + 2 ) % 4;
+ myChildren.back().SetBottomSide( other.GetSide( otherBottomIndex ));
+ // collect vertices in mySides
+ mySides.AppendSide( other.GetSide(0) );
+ mySides.AppendSide( other.GetSide(1) );
+ mySides.AppendSide( other.GetSide(2) );
+ mySides.AppendSide( other.GetSide(3) );
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+//================================================================================
+/*!
+ * \brief Try to set the side as bottom hirizontal side
+ */
+//================================================================================
+
+bool _QuadFaceGrid::SetBottomSide(const _FaceSide& bottom, int* sideIndex)
+{
+ myLeftBottomChild = myRightBrother = myUpBrother = 0;
+
+ int myBottomIndex;
+ if ( myChildren.empty() )
+ {
+ if ( mySides.Contain( bottom, &myBottomIndex )) {
+ mySides.SetBottomSide( myBottomIndex );
+ if ( sideIndex )
+ *sideIndex = myBottomIndex;
+ return true;
+ }
+ }
+ else
+ {
+ TChildren::iterator childFace = myChildren.begin(), childEnd = myChildren.end();
+ for ( ; childFace != childEnd; ++childFace )
+ {
+ if ( childFace->SetBottomSide( bottom, &myBottomIndex ))
+ {
+ TChildren::iterator orientedCild = childFace;
+ for ( childFace = myChildren.begin(); childFace != childEnd; ++childFace ) {
+ if ( childFace != orientedCild )
+ childFace->SetBottomSide( childFace->GetSide( myBottomIndex ));
+ }
+ if ( sideIndex )
+ *sideIndex = myBottomIndex;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+//================================================================================
+/*!
+ * \brief Return face adjacent to i-th side of this face, (0& faces) const
+{
+ for ( int iF = 0; iF < faces.size(); ++iF ) {
+ _QuadFaceGrid* f = &faces[ iF ];
+ if ( f != this && f->SetBottomSide( GetSide( i )))
+ return f;
+ }
+ return (_QuadFaceGrid*) 0;
+}
+
+//================================================================================
+/*!
+ * \brief Return i-th side
+ */
+//================================================================================
+
+const _FaceSide& _QuadFaceGrid::GetSide(int i) const
+{
+ if ( myChildren.empty() )
+ return *mySides.GetSide(i);
+
+ _QuadFaceGrid* me = const_cast<_QuadFaceGrid*>(this);
+ if ( !me->locateChildren() || !myLeftBottomChild )
+ return *mySides.GetSide(i);
+
+ const _QuadFaceGrid* child = myLeftBottomChild;
+ switch ( i ){
+ case Q_BOTTOM:
+ case Q_LEFT:
+ break;
+ case Q_RIGHT:
+ while ( child->myRightBrother )
+ child = child->myRightBrother;
+ break;
+ case Q_TOP:
+ while ( child->myUpBrother )
+ child = child->myUpBrother;
+ break;
+ default: ;
+ }
+ return child->GetSide( i );
+}
+
+//================================================================================
+/*!
+ * \brief Reverse edges in order to have them oriented along axes of the unit box
+ */
+//================================================================================
+
+void _QuadFaceGrid::ReverseEdges(/*int e1, int e2*/)
+{
+ myReverse = !myReverse;
+
+// #ifdef DEB_FACES
+// if ( !myFace.IsNull() )
+// TopAbs::Print(myFace.Orientation(), cout);
+// #endif
+
+ if ( myChildren.empty() )
+ {
+// mySides.GetSide( e1 )->Reverse();
+// mySides.GetSide( e2 )->Reverse();
+ DumpVertices();
+ }
+ else
+ {
+ DumpVertices();
+ TChildren::iterator child = myChildren.begin(), childEnd = myChildren.end();
+ for ( ; child != childEnd; ++child )
+ child->ReverseEdges( /*e1, e2*/ );
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Load nodes of a mesh
+ */
+//================================================================================
+
+bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh )
+{
+ if ( !myChildren.empty() )
+ {
+ // Let child faces load their grids
+ TChildren::iterator child = myChildren.begin(), childEnd = myChildren.end();
+ for ( ; child != childEnd; ++child ) {
+ child->SetID( myID );
+ if ( !child->LoadGrid( mesh ) )
+ return error( child->GetError() );
+ }
+ // Fill myGrid with nodes of patches
+ return loadCompositeGrid( mesh );
+ }
+
+ // ---------------------------------------
+ // Fill myGrid with nodes bound to myFace
+ // ---------------------------------------
+
+ if ( !myGrid.empty() )
+ return true;
+
+ myIndexer._xSize = 1 + mySides.GetSide( Q_BOTTOM )->GetNbSegments( mesh );
+ myIndexer._ySize = 1 + mySides.GetSide( Q_LEFT )->GetNbSegments( mesh );
+
+ myGrid.resize( myIndexer.size() );
+
+ // strore nodes bound to the bottom edge
+ mySides.GetSide( Q_BOTTOM )->StoreNodes( mesh, myGrid, myReverse );
+
+ // store the rest nodes row by row
+
+ SMESHDS_SubMesh* faceSubMesh = mesh.GetSubMesh( myFace )->GetSubMeshDS();
+
+ SMDS_MeshNode dummy(0,0,0);
+ const SMDS_MeshElement* firstQuad = &dummy;// most left face above the last row of found nodes
+
+ int nbFoundNodes = myIndexer._xSize;
+ while ( nbFoundNodes != myGrid.size() )
+ {
+ // first and last nodes of the last filled row of nodes
+ const SMDS_MeshNode* n1down = myGrid[ nbFoundNodes - myIndexer._xSize ];
+ const SMDS_MeshNode* n2down = myGrid[ nbFoundNodes - myIndexer._xSize + 1];
+ const SMDS_MeshNode* n1downLast = myGrid[ nbFoundNodes-1 ];
+
+ // find the first face above the row by the first two left nodes
+ //
+ // n1up n2up
+ // o---o
+ // | |
+ // o---o o o o o
+ //n1down n2down
+ //
+ TIDSortedElemSet emptySet, avoidSet;
+ avoidSet.insert( firstQuad );
+ firstQuad = SMESH_MeshEditor::FindFaceInSet( n1down, n2down, emptySet, avoidSet);
+ if ( firstQuad && !faceSubMesh->Contains( firstQuad )) {
+ avoidSet.insert( firstQuad );
+ firstQuad = SMESH_MeshEditor::FindFaceInSet( n1down, n2down, emptySet, avoidSet);
+ }
+ if ( !firstQuad || !faceSubMesh->Contains( firstQuad ))
+ return error(ERR_LI("Error in _QuadFaceGrid::LoadGrid()"));
+
+ // find the node of quad bound to the left geom edge
+ int i2down = firstQuad->GetNodeIndex( n2down );
+ const SMDS_MeshNode* n1up = firstQuad->GetNode(( i2down+2 ) % 4 );
+ myGrid[ nbFoundNodes++ ] = n1up;
+ // the 4-the node of the first quad
+ int i1down = firstQuad->GetNodeIndex( n1down );
+ const SMDS_MeshNode* n2up = firstQuad->GetNode(( i1down+2 ) % 4 );
+ myGrid[ nbFoundNodes++ ] = n2up;
+
+ n1down = n2down;
+ n1up = n2up;
+ const SMDS_MeshElement* quad = firstQuad;
+
+ // find the rest nodes by remaining faces above the row
+ //
+ // n1up
+ // o---o--o
+ // | | | ->
+ // o---o--o o o o
+ // n1downLast
+ //
+ while ( n1down != n1downLast )
+ {
+ // next face
+ avoidSet.clear(); avoidSet.insert( quad );
+ quad = SMESH_MeshEditor::FindFaceInSet( n1down, n1up, emptySet, avoidSet );
+ if ( !quad || quad->NbNodes() % 4 > 0)
+ return error(ERR_LI("Error in _QuadFaceGrid::LoadGrid()"));
+
+ // next node
+ if ( quad->GetNode( i1down ) != n1down ) // check already found index
+ i1down = quad->GetNodeIndex( n1down );
+ n2up = quad->GetNode(( i1down+2 ) % 4 );
+ myGrid[ nbFoundNodes++ ] = n2up;
+
+ n1down = myGrid[ nbFoundNodes - myIndexer._xSize - 1 ];
+ n1up = n2up;
+ }
+ }
+
+ DumpGrid(); // debug
+
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief Find out mutual location of children: find their right and up brothers
+ */
+//================================================================================
+
+bool _QuadFaceGrid::locateChildren()
+{
+ if ( myLeftBottomChild )
+ return true;
+
+ TChildren::iterator child = myChildren.begin(), childEnd = myChildren.end();
+
+ // find a child sharing it's first bottom vertex with no other brother
+ myLeftBottomChild = 0;
+ for ( ; !myLeftBottomChild && child != childEnd; ++child )
+ {
+ TopoDS_Vertex leftVertex = child->GetSide( Q_BOTTOM ).FirstVertex();
+ bool sharedVertex = false;
+ TChildren::iterator otherChild = myChildren.begin();
+ for ( ; otherChild != childEnd && !sharedVertex; ++otherChild )
+ if ( otherChild != child )
+ sharedVertex = otherChild->mySides.Contain( leftVertex );
+ if ( !sharedVertex ) {
+ myLeftBottomChild = & (*child);
+ DUMP_VERT("0 left bottom Vertex: ",leftVertex );
+ }
+ }
+ if (!myLeftBottomChild)
+ return error(ERR_LI("Error in locateChildren()"));
+
+ set< _QuadFaceGrid* > notLocatedChilren;
+ for (child = myChildren.begin() ; child != childEnd; ++child )
+ notLocatedChilren.insert( & (*child));
+
+ // connect myLeftBottomChild to it's right and upper brothers
+ notLocatedChilren.erase( myLeftBottomChild );
+ myLeftBottomChild->setBrothers( notLocatedChilren );
+ if ( !notLocatedChilren.empty() )
+ return error(ERR_LI("Error in locateChildren()"));
+
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief Fill myGrid with nodes of patches
+ */
+//================================================================================
+
+bool _QuadFaceGrid::loadCompositeGrid(SMESH_Mesh& mesh)
+{
+ // Find out mutual location of children: find their right and up brothers
+ if ( !locateChildren() )
+ return false;
+
+ // Load nodes according to mutual location of children
+
+ // grid size
+ myIndexer._xSize = 1 + myLeftBottomChild->GetNbHoriSegments(mesh, /*withBrothers=*/true);
+ myIndexer._ySize = 1 + myLeftBottomChild->GetNbVertSegments(mesh, /*withBrothers=*/true);
+
+ myGrid.resize( myIndexer.size() );
+
+ int fromX = myReverse ? myIndexer._xSize : 0;
+ if (!myLeftBottomChild->fillGrid( mesh, myGrid, myIndexer, fromX, 0 ))
+ return error( myLeftBottomChild->GetError() );
+
+ DumpGrid();
+
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief Find right an upper brothers among notLocatedBrothers
+ */
+//================================================================================
+
+void _QuadFaceGrid::setBrothers( set< _QuadFaceGrid* >& notLocatedBrothers )
+{
+ if ( !notLocatedBrothers.empty() )
+ {
+ // find right brother
+ TopoDS_Vertex rightVertex = GetSide( Q_BOTTOM ).LastVertex();
+ DUMP_VERT("1 right bottom Vertex: ",rightVertex );
+ set< _QuadFaceGrid* >::iterator brIt, brEnd = notLocatedBrothers.end();
+ for ( brIt = notLocatedBrothers.begin(); !myRightBrother && brIt != brEnd; ++brIt )
+ {
+ _QuadFaceGrid* brother = *brIt;
+ TopoDS_Vertex brotherLeftVertex = brother->GetSide( Q_BOTTOM ).FirstVertex();
+ DUMP_VERT( "brother left bottom: ", brotherLeftVertex );
+ if ( rightVertex.IsSame( brotherLeftVertex )) {
+ myRightBrother = brother;
+ notLocatedBrothers.erase( myRightBrother );
+ }
+ }
+ // find upper brother
+ TopoDS_Vertex upVertex = GetSide( Q_LEFT ).FirstVertex();
+ DUMP_VERT("1 left up Vertex: ",upVertex);
+ brIt = notLocatedBrothers.begin(), brEnd = notLocatedBrothers.end();
+ for ( ; !myUpBrother && brIt != brEnd; ++brIt )
+ {
+ _QuadFaceGrid* brother = *brIt;
+ TopoDS_Vertex brotherLeftVertex = brother->GetSide( Q_BOTTOM ).FirstVertex();
+ DUMP_VERT("brother left bottom: ", brotherLeftVertex);
+ if ( upVertex.IsSame( brotherLeftVertex )) {
+ myUpBrother = brother;
+ notLocatedBrothers.erase( myUpBrother );
+ }
+ }
+ // recursive call
+ if ( myRightBrother )
+ myRightBrother->setBrothers( notLocatedBrothers );
+ if ( myUpBrother )
+ myUpBrother->setBrothers( notLocatedBrothers );
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Store nodes of a simple face into grid starting from (x,y) position
+ */
+//================================================================================
+
+bool _QuadFaceGrid::fillGrid(SMESH_Mesh& theMesh,
+ vector & theGrid,
+ const _Indexer& theIndexer,
+ int theX,
+ int theY)
+{
+ if ( myGrid.empty() && !LoadGrid( theMesh ))
+ return false;
+
+ // store my own grid in the global grid
+
+ int fromX = myReverse ? theX - myIndexer._xSize: theX;
+
+ for ( int i = 0, x = fromX; i < myIndexer._xSize; ++i, ++x )
+ for ( int j = 0, y = theY; j < myIndexer._ySize; ++j, ++y )
+ theGrid[ theIndexer( x, y )] = myGrid[ myIndexer( i, j )];
+
+ // store grids of my right and upper brothers
+
+ if ( myRightBrother )
+ {
+ if ( myReverse )
+ fromX += 1;
+ else
+ fromX += myIndexer._xSize - 1;
+ if ( !myRightBrother->fillGrid( theMesh, theGrid, theIndexer, fromX, theY ))
+ return error( myRightBrother->GetError() );
+ }
+ if ( myUpBrother )
+ {
+ if ( !myUpBrother->fillGrid( theMesh, theGrid, theIndexer,
+ theX, theY + myIndexer._ySize - 1))
+ return error( myUpBrother->GetError() );
+ }
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief Return number of segments on the hirizontal sides
+ */
+//================================================================================
+
+int _QuadFaceGrid::GetNbHoriSegments(SMESH_Mesh& mesh, bool withBrothers) const
+{
+ int nbSegs = 0;
+ if ( myLeftBottomChild )
+ {
+ nbSegs += myLeftBottomChild->GetNbHoriSegments( mesh, true );
+ }
+ else
+ {
+ nbSegs = mySides.GetSide( Q_BOTTOM )->GetNbSegments(mesh);
+ if ( withBrothers && myRightBrother )
+ nbSegs += myRightBrother->GetNbHoriSegments( mesh, withBrothers );
+ }
+ return nbSegs;
+}
+
+//================================================================================
+/*!
+ * \brief Return number of segments on the vertical sides
+ */
+//================================================================================
+
+int _QuadFaceGrid::GetNbVertSegments(SMESH_Mesh& mesh, bool withBrothers) const
+{
+ int nbSegs = 0;
+ if ( myLeftBottomChild )
+ {
+ nbSegs += myLeftBottomChild->GetNbVertSegments( mesh, true );
+ }
+ else
+ {
+ nbSegs = mySides.GetSide( Q_LEFT )->GetNbSegments(mesh);
+ if ( withBrothers && myUpBrother )
+ nbSegs += myUpBrother->GetNbVertSegments( mesh, withBrothers );
+ }
+ return nbSegs;
+}
+
+//================================================================================
+/*!
+ * \brief Return a node by its position
+ */
+//================================================================================
+
+const SMDS_MeshNode* _QuadFaceGrid::GetNode(int iHori, int iVert) const
+{
+ return myGrid[ myIndexer( iHori, iVert )];
+}
+
+//================================================================================
+/*!
+ * \brief Return node coordinates by its position
+ */
+//================================================================================
+
+gp_XYZ _QuadFaceGrid::GetXYZ(int iHori, int iVert) const
+{
+ const SMDS_MeshNode* n = myGrid[ myIndexer( iHori, iVert )];
+ return gp_XYZ( n->X(), n->Y(), n->Z() );
+}
+
+//================================================================================
+/*!
+ * \brief Return normal to the face at vertex v
+ */
+//================================================================================
+
+bool _QuadFaceGrid::GetNormal( const TopoDS_Vertex& v, gp_Vec& n ) const
+{
+ if ( myChildren.empty() )
+ {
+ if ( mySides.Contain( v )) {
+ try {
+ gp_Pnt2d uv = BRep_Tool::Parameters( v, myFace );
+ BRepAdaptor_Surface surface( myFace );
+ gp_Pnt p; gp_Vec d1u, d1v;
+ surface.D1( uv.X(), uv.Y(), p, d1u, d1v );
+ n = d1u.Crossed( d1v );
+ return true;
+ }
+ catch (Standard_Failure) {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ TChildren::const_iterator child = myChildren.begin(), childEnd = myChildren.end();
+ for ( ; child != childEnd; ++child )
+ if ( child->GetNormal( v, n ))
+ return true;
+ }
+ return false;
+}
+
+//================================================================================
+/*!
+ * \brief Dumps coordinates of grid nodes
+ */
+//================================================================================
+
+void _QuadFaceGrid::DumpGrid() const
+{
+#ifdef DEB_GRID
+ const char* names[] = { "B_BOTTOM", "B_RIGHT", "B_TOP", "B_LEFT", "B_FRONT", "B_BACK" };
+ cout << "****** Face " << names[ myID ] << endl;
+
+ if ( myChildren.empty() || !myGrid.empty() )
+ {
+ cout << "x size: " << myIndexer._xSize << "; y size: " << myIndexer._ySize << endl;
+ for ( int y = 0; y < myIndexer._ySize; ++y ) {
+ cout << "-- row " << y << endl;
+ for ( int x = 0; x < myIndexer._xSize; ++x ) {
+ const SMDS_MeshNode* n = myGrid[ myIndexer( x, y ) ];
+ cout << x << " ( " << n->X() << ", " << n->Y() << ", " << n->Z() << " )" << endl;
+ }
+ }
+ }
+ else
+ {
+ cout << "Nb children: " << myChildren.size() << endl;
+ TChildren::const_iterator child = myChildren.begin(), childEnd = myChildren.end();
+ for ( int i=0; child != childEnd; ++child, ++i ) {
+ cout << " *** SUBFACE " << i+1 << endl;
+ ((_QuadFaceGrid&)(*child)).SetID( myID );
+ child->DumpGrid();
+ }
+ }
+#endif
+}
+
+//================================================================================
+/*!
+ * \brief Dump vertices
+ */
+//================================================================================
+
+void _QuadFaceGrid::DumpVertices() const
+{
+#ifdef DEB_FACES
+ cout << "****** Face ";
+ const char* names[] = { "B_BOTTOM", "B_RIGHT", "B_TOP", "B_LEFT", "B_FRONT", "B_BACK" };
+ if ( myID >= B_BOTTOM && myID < B_BACK )
+ cout << names[ myID ] << endl;
+ else
+ cout << "UNDEFINED" << endl;
+
+ if ( myChildren.empty() )
+ {
+ for ( int i = 0; i < 4; ++i )
+ {
+ cout << " Side "; mySides.GetSide( i )->Dump();
+ }
+ }
+ else
+ {
+ cout << "-- Nb children: " << myChildren.size() << endl;
+ TChildren::const_iterator child = myChildren.begin(), childEnd = myChildren.end();
+ for ( int i=0; child != childEnd; ++child, ++i ) {
+ cout << " *** SUBFACE " << i+1 << endl;
+ ((_QuadFaceGrid&)(*child)).SetID( myID );
+ child->DumpVertices();
+ }
+ }
+#endif
+}
+
+//=======================================================================
+//function : _FaceSide
+//purpose : copy constructor
+//=======================================================================
+
+_FaceSide::_FaceSide(const _FaceSide& other)
+{
+ myEdge = other.myEdge;
+ myChildren = other.myChildren;
+ myNbChildren = other.myNbChildren;
+ myVertices.Assign( other.myVertices );
+ myID = other.myID;
+}
+
+//================================================================================
+/*!
+ * \brief Construct a face side of one edge
+ */
+//================================================================================
+
+_FaceSide::_FaceSide(const TopoDS_Edge& edge):
+ myEdge( edge ), myNbChildren(0)
+{
+ if ( !edge.IsNull() )
+ for ( TopExp_Explorer exp( edge, TopAbs_VERTEX ); exp.More(); exp.Next() )
+ //myVertices.insert( ptr ( exp.Current() ));
+ myVertices.Add( exp.Current() );
+}
+
+//================================================================================
+/*!
+ * \brief Construct a face side of several edges
+ */
+//================================================================================
+
+_FaceSide::_FaceSide(const list& edges):
+ myNbChildren(0)
+{
+ list::const_iterator edge = edges.begin(), eEnd = edges.end();
+ for ( ; edge != eEnd; ++edge ) {
+ myChildren.push_back( _FaceSide( *edge ));
+ myNbChildren++;
+// myVertices.insert( myChildren.back().myVertices.begin(),
+// myChildren.back().myVertices.end() );
+ myVertices.Add( myChildren.back().FirstVertex() );
+ myVertices.Add( myChildren.back().LastVertex() );
+ myChildren.back().SetID( Q_CHILD ); // not to splice them
+ }
+}
+
+//=======================================================================
+//function : GetSide
+//purpose :
+//=======================================================================
+
+_FaceSide* _FaceSide::GetSide(const int i)
+{
+ if ( i >= myNbChildren )
+ return 0;
+
+ list< _FaceSide >::iterator side = myChildren.begin();
+ if ( i )
+ std::advance( side, i );
+ return & (*side);
+}
+
+//=======================================================================
+//function : GetSide
+//purpose :
+//=======================================================================
+
+const _FaceSide* _FaceSide::GetSide(const int i) const
+{
+ return const_cast< _FaceSide* >(this)->GetSide(i);
+}
+
+//=======================================================================
+//function : NbVertices
+//purpose : return nb of vertices in the side
+//=======================================================================
+
+int _FaceSide::NbVertices() const
+{
+ if ( myChildren.empty() )
+ return myVertices.Extent();
+// return myVertices.size();
+
+ return myNbChildren + 1;
+}
+
+//=======================================================================
+//function : FirstVertex
+//purpose :
+//=======================================================================
+
+TopoDS_Vertex _FaceSide::FirstVertex() const
+{
+ if ( myChildren.empty() )
+ return TopExp::FirstVertex( myEdge, Standard_True );
+
+ return myChildren.front().FirstVertex();
+}
+
+//=======================================================================
+//function : LastVertex
+//purpose :
+//=======================================================================
+
+TopoDS_Vertex _FaceSide::LastVertex() const
+{
+ if ( myChildren.empty() )
+ return TopExp::LastVertex( myEdge, Standard_True );
+
+ return myChildren.back().LastVertex();
+}
+
+//=======================================================================
+//function : Vertex
+//purpose :
+//=======================================================================
+
+TopoDS_Vertex _FaceSide::Vertex(int i) const
+{
+ if ( myChildren.empty() )
+ return i ? LastVertex() : FirstVertex();
+
+ if ( i >= myNbChildren )
+ return myChildren.back().LastVertex();
+
+ return GetSide(i)->FirstVertex();
+}
+
+//=======================================================================
+//function : Contain
+//purpose :
+//=======================================================================
+
+bool _FaceSide::Contain( const _FaceSide& side, int* which ) const
+{
+ if ( !which || myChildren.empty() )
+ {
+ if ( which )
+ *which = 0;
+ int nbCommon = 0;
+// set::iterator v, vEnd = side.myVertices.end();
+// for ( v = side.myVertices.begin(); v != vEnd; ++v )
+// nbCommon += ( myVertices.find( *v ) != myVertices.end() );
+ TopTools_MapIteratorOfMapOfShape vIt ( side.myVertices );
+ for ( ; vIt.More(); vIt.Next() )
+ nbCommon += ( myVertices.Contains( vIt.Key() ));
+ return (nbCommon > 1);
+ }
+ list< _FaceSide >::const_iterator mySide = myChildren.begin(), sideEnd = myChildren.end();
+ for ( int i = 0; mySide != sideEnd; ++mySide, ++i ) {
+ if ( mySide->Contain( side )) {
+ *which = i;
+ return true;
+ }
+ }
+ return false;
+}
+
+//=======================================================================
+//function : Contain
+//purpose :
+//=======================================================================
+
+bool _FaceSide::Contain( const TopoDS_Vertex& vertex ) const
+{
+ return myVertices.Contains( vertex );
+// return myVertices.find( ptr( vertex )) != myVertices.end();
+}
+
+//=======================================================================
+//function : AppendSide
+//purpose :
+//=======================================================================
+
+void _FaceSide::AppendSide( const _FaceSide& side )
+{
+ if ( !myEdge.IsNull() )
+ {
+ myChildren.push_back( *this );
+ myNbChildren = 1;
+ myEdge.Nullify();
+ }
+ myChildren.push_back( side );
+ myNbChildren++;
+ //myVertices.insert( side.myVertices.begin(), side.myVertices.end() );
+ TopTools_MapIteratorOfMapOfShape vIt ( side.myVertices );
+ for ( ; vIt.More(); vIt.Next() )
+ myVertices.Add( vIt.Key() );
+
+ myID = Q_PARENT;
+ myChildren.back().SetID( EQuadSides( myNbChildren-1 ));
+}
+
+//=======================================================================
+//function : SetBottomSide
+//purpose :
+//=======================================================================
+
+void _FaceSide::SetBottomSide( int i )
+{
+ if ( i > 0 && myID == Q_PARENT ) {
+ list< _FaceSide >::iterator sideEnd, side = myChildren.begin();
+ std::advance( side, i );
+ myChildren.splice( myChildren.begin(), myChildren, side, myChildren.end() );
+
+ side = myChildren.begin(), sideEnd = myChildren.end();
+ for ( int i = 0; side != sideEnd; ++side, ++i ) {
+ side->SetID( EQuadSides(i) );
+ side->SetBottomSide(i);
+ }
+ }
+}
+
+//=======================================================================
+//function : GetNbSegments
+//purpose :
+//=======================================================================
+
+int _FaceSide::GetNbSegments(SMESH_Mesh& mesh) const
+{
+ int nb = 0;
+ if ( myChildren.empty() )
+ {
+ nb = mesh.GetSubMesh(myEdge)->GetSubMeshDS()->NbElements();
+ }
+ else
+ {
+ list< _FaceSide >::const_iterator side = myChildren.begin(), sideEnd = myChildren.end();
+ for ( ; side != sideEnd; ++side )
+ nb += side->GetNbSegments(mesh);
+ }
+ return nb;
+}
+
+//=======================================================================
+//function : StoreNodes
+//purpose :
+//=======================================================================
+
+bool _FaceSide::StoreNodes(SMESH_Mesh& mesh,
+ vector& myGrid,
+ bool reverse )
+{
+ list< TopoDS_Edge > edges;
+ if ( myChildren.empty() )
+ {
+ edges.push_back( myEdge );
+ }
+ else
+ {
+ list< _FaceSide >::const_iterator side = myChildren.begin(), sideEnd = myChildren.end();
+ for ( ; side != sideEnd; ++side )
+ if ( reverse )
+ edges.push_front( side->myEdge );
+ else
+ edges.push_back ( side->myEdge );
+ }
+ int nbNodes = 0;
+ list< TopoDS_Edge >::iterator edge = edges.begin(), eEnd = edges.end();
+ for ( ; edge != eEnd; ++edge )
+ {
+ map< double, const SMDS_MeshNode* > nodes;
+ bool ok = SMESH_Algo::GetSortedNodesOnEdge( mesh.GetMeshDS(),
+ *edge,
+ /*ignoreMediumNodes=*/true,
+ nodes);
+ if ( !ok ) return false;
+
+ bool forward = ( edge->Orientation() == TopAbs_FORWARD );
+ if ( reverse ) forward = !forward;
+ if ( forward )
+ {
+ map< double, const SMDS_MeshNode* >::iterator u_node, nEnd = nodes.end();
+ for ( u_node = nodes.begin(); u_node != nEnd; ++u_node )
+ myGrid[ nbNodes++ ] = u_node->second;
+ }
+ else
+ {
+ map< double, const SMDS_MeshNode* >::reverse_iterator u_node, nEnd = nodes.rend();
+ for ( u_node = nodes.rbegin(); u_node != nEnd; ++u_node )
+ myGrid[ nbNodes++ ] = u_node->second;
+ }
+ nbNodes--; // node on vertex present in two adjacent edges
+ }
+ return nbNodes > 0;
+}
+
+//=======================================================================
+//function : Dump
+//purpose : dump end vertices
+//=======================================================================
+
+void _FaceSide::Dump() const
+{
+ if ( myChildren.empty() )
+ {
+ const char* sideNames[] = { "Q_BOTTOM", "Q_RIGHT", "Q_TOP", "Q_LEFT", "Q_CHILD", "Q_PARENT" };
+ if ( myID >= Q_BOTTOM && myID < Q_PARENT )
+ cout << sideNames[ myID ] << endl;
+ else
+ cout << "" << endl;
+ TopoDS_Vertex f = FirstVertex();
+ TopoDS_Vertex l = LastVertex();
+ gp_Pnt pf = BRep_Tool::Pnt(f);
+ gp_Pnt pl = BRep_Tool::Pnt(l);
+ cout << "\t ( "<< ptr( f ) << " - " << ptr( l )<< " )"
+ << "\t ( "<< pf.X()<<", "<