diff --git a/doc/salome/gui/SMESH/images/bare_border_faces_smpl.png b/doc/salome/gui/SMESH/images/bare_border_faces_smpl.png
new file mode 100644
index 000000000..6b7ead85e
Binary files /dev/null and b/doc/salome/gui/SMESH/images/bare_border_faces_smpl.png differ
diff --git a/doc/salome/gui/SMESH/images/bare_border_volumes_smpl.png b/doc/salome/gui/SMESH/images/bare_border_volumes_smpl.png
new file mode 100644
index 000000000..a1e799aa2
Binary files /dev/null and b/doc/salome/gui/SMESH/images/bare_border_volumes_smpl.png differ
diff --git a/doc/salome/gui/SMESH/images/controls_popup.png b/doc/salome/gui/SMESH/images/controls_popup.png
new file mode 100755
index 000000000..b0bd01fb9
Binary files /dev/null and b/doc/salome/gui/SMESH/images/controls_popup.png differ
diff --git a/doc/salome/gui/SMESH/images/copy_mesh_dlg.png b/doc/salome/gui/SMESH/images/copy_mesh_dlg.png
new file mode 100644
index 000000000..db9c929b5
Binary files /dev/null and b/doc/salome/gui/SMESH/images/copy_mesh_dlg.png differ
diff --git a/doc/salome/gui/SMESH/images/copy_mesh_icon.png b/doc/salome/gui/SMESH/images/copy_mesh_icon.png
new file mode 100644
index 000000000..263479f3b
Binary files /dev/null and b/doc/salome/gui/SMESH/images/copy_mesh_icon.png differ
diff --git a/doc/salome/gui/SMESH/images/over_constrained_faces.png b/doc/salome/gui/SMESH/images/over_constrained_faces.png
new file mode 100644
index 000000000..9d584e8ac
Binary files /dev/null and b/doc/salome/gui/SMESH/images/over_constrained_faces.png differ
diff --git a/doc/salome/gui/SMESH/images/over_constrained_volumes.png b/doc/salome/gui/SMESH/images/over_constrained_volumes.png
new file mode 100644
index 000000000..761144382
Binary files /dev/null and b/doc/salome/gui/SMESH/images/over_constrained_volumes.png differ
diff --git a/doc/salome/gui/SMESH/images/scalar_bar_dlg.png b/doc/salome/gui/SMESH/images/scalar_bar_dlg.png
new file mode 100755
index 000000000..59ca53065
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scalar_bar_dlg.png differ
diff --git a/doc/salome/gui/SMESH/input/about_meshes.doc b/doc/salome/gui/SMESH/input/about_meshes.doc
index 8a81c7ea0..c79f26644 100644
--- a/doc/salome/gui/SMESH/input/about_meshes.doc
+++ b/doc/salome/gui/SMESH/input/about_meshes.doc
@@ -16,6 +16,9 @@ for example, a face.
Several created meshes can be \subpage building_compounds_page "combined into mesh compounds".
+The whole mesh or it's part can be \subpage copy_mesh_page "copied"
+into another mesh.
+
All created meshes and submeshes can be \subpage editing_meshes_page "edited".
Meshes can be also edited using the MESH functions destined for
diff --git a/doc/salome/gui/SMESH/input/about_quality_controls.doc b/doc/salome/gui/SMESH/input/about_quality_controls.doc
index 8f78c38c5..124867c9e 100644
--- a/doc/salome/gui/SMESH/input/about_quality_controls.doc
+++ b/doc/salome/gui/SMESH/input/about_quality_controls.doc
@@ -32,6 +32,8 @@ Edge quality controls:
Face quality controls:
\subpage free_faces_page "Free faces"
+\subpage bare_border_faces_page "Bare border faces"
+\subpage over_constrained_faces_page "Over-constrained faces"
\subpage length_2d_page "Length 2D"
\subpage borders_at_multi_connection_2d_page "Borders at multi-connection 2D"
\subpage area_page "Area"
@@ -48,6 +50,23 @@ Volume quality controls:
\subpage aspect_ratio_3d_page "Aspect ratio 3D"
\subpage volume_page "Volume"
\subpage max_element_length_3d_page "Max element length 3D"
+\subpage bare_border_volumes_page "Bare border volumes"
+\subpage over_constrained_volumes_page "Over-constrained volumes"
+To manage the quality controls call pop-up in the VTK viewer and select "Controls" sub-menu
+\image html controls_popup.png
+
+
+ Reset switches off quality controls;
+ Node Controls provides access to the node quality controls;
+ Edge Controls provides access to the edge quality controls;
+ Face Controls provides access to the face quality controls;
+ Volume Controls provides access to the volume quality controls;
+ Scalar Bar Properties allows setting \subpage scalar_bar_dlg;
+ Export Distribution... allows saving the distribution of quality control values in the text file;
+ Show Distribution Shows/Hides the distribution histogram of the quality control values in the VTK Viewer.
+
+
+
*/
diff --git a/doc/salome/gui/SMESH/input/bare_border_face.doc b/doc/salome/gui/SMESH/input/bare_border_face.doc
new file mode 100644
index 000000000..2115d3249
--- /dev/null
+++ b/doc/salome/gui/SMESH/input/bare_border_face.doc
@@ -0,0 +1,15 @@
+/*!
+
+\page bare_border_faces_page Bare border faces
+
+This mesh quality control highlights the faces having the border not
+shared with other faces (free border) and missing an edge based on
+nodes of the free border. The faces with bare border are shown with a
+color different from the color of shared faces.
+
+\image html bare_border_faces_smpl.png
+
+\sa A sample TUI Script making a group of faces highlighted in the
+picture is \ref tui_bare_border_faces "Bare border faces Control".
+
+*/
diff --git a/doc/salome/gui/SMESH/input/bare_border_volumes.doc b/doc/salome/gui/SMESH/input/bare_border_volumes.doc
new file mode 100644
index 000000000..d0dd894ba
--- /dev/null
+++ b/doc/salome/gui/SMESH/input/bare_border_volumes.doc
@@ -0,0 +1,15 @@
+/*!
+
+\page bare_border_volumes_page Bare border volumes
+
+This mesh quality control highlights the volumes having the border not
+shared with other volumes (free border) and missing a face based on
+nodes of the free border. The volumes with bare border are shown with a
+color different from the color of shared volumes.
+
+\image html bare_border_volumes_smpl.png
+
+\sa A sample TUI Script making a group of volumes highlighted in the
+picture is \ref tui_bare_border_volumes "Bare border volumes Control".
+
+*/
diff --git a/doc/salome/gui/SMESH/input/copy_mesh.doc b/doc/salome/gui/SMESH/input/copy_mesh.doc
new file mode 100644
index 000000000..2c65ab8d0
--- /dev/null
+++ b/doc/salome/gui/SMESH/input/copy_mesh.doc
@@ -0,0 +1,56 @@
+/*!
+
+\page copy_mesh_page Copy Mesh
+
+\n A mesh can be created by copying a part of or the whole other mesh.
+
+To make a copy of a mesh:
+
+\par
+From the \b Mesh menu select Copy Mesh or click "Copy Mesh"
+button in the toolbar.
+
+\image html copy_mesh_icon.png
+"Copy Mesh" button
+
+\par
+The following dialog box will appear:
+
+\image html copy_mesh_dlg.png
+
+\par
+In the dialog:
+
+specify the part of mesh to copy:
+
+
+Select the whole mesh, submesh or group by mouse activating
+this checkbox; or
+choose mesh elements with the mouse in the 3D Viewer. It is
+possible to select a whole area with a mouse frame; or
+input the Source Element IDs directly in this field. The
+selected elements will be highlighted in the viewer; or
+apply Filters. Set filter button allows to apply a filter
+to the selection of elements. See more about filters in the \ref
+selection_filter_library_page "Selection filter library" page.
+
+
+
+specify the New Mesh Name ;
+
+specify the conditions of copying:
+
+activate Generate groups checkbox to copy the groups of
+elements of the source mesh to the newly created mesh.
+activate Preserve IDs of elements checkbox to keep
+the IDs of new nodes and elements the same as the IDs of source nodes
+and elements.
+
+
+
+Click \b Apply or Apply and Close button to confirm the operation.
+
+
+See Also a sample
+\ref tui_copy_mesh "TUI Example of mesh copying."
+*/
diff --git a/doc/salome/gui/SMESH/input/over_constrained_faces.doc b/doc/salome/gui/SMESH/input/over_constrained_faces.doc
new file mode 100644
index 000000000..26ad944f7
--- /dev/null
+++ b/doc/salome/gui/SMESH/input/over_constrained_faces.doc
@@ -0,0 +1,14 @@
+/*!
+
+\page over_constrained_faces_page Over-constrained faces
+
+\n This mesh quality control highlights faces sharing only one of its borders with other faces.
+
+\image html over_constrained_faces.png
+
+In this picture the over-constrained face is displayed in red.
+
+See Also a sample TUI Script of a
+\ref tui_over_constrained_faces "Over-constrained faces" filter.
+
+*/
diff --git a/doc/salome/gui/SMESH/input/over_constrained_volumes.doc b/doc/salome/gui/SMESH/input/over_constrained_volumes.doc
new file mode 100644
index 000000000..1519e0ae6
--- /dev/null
+++ b/doc/salome/gui/SMESH/input/over_constrained_volumes.doc
@@ -0,0 +1,14 @@
+/*!
+
+\page over_constrained_volumes_page Over-constrained volumes
+
+\n This mesh quality control highlights volumes sharing only one of its borders with other volumes.
+
+\image html over_constrained_volumes.png
+
+In this picture the over-constrained volume is displayed in red.
+
+See Also a sample TUI Script of a
+\ref tui_over_constrained_volumes "Over-constrained volumes" filter.
+
+*/
\ No newline at end of file
diff --git a/doc/salome/gui/SMESH/input/scalar_bar.doc b/doc/salome/gui/SMESH/input/scalar_bar.doc
new file mode 100755
index 000000000..146a7fa78
--- /dev/null
+++ b/doc/salome/gui/SMESH/input/scalar_bar.doc
@@ -0,0 +1,40 @@
+/*!
+
+\page scalar_bar_dlg Scalar Bar properties
+
+In this dialog you can specify the properties of the scalar bar
+
+\image html scalar_bar_dlg.png
+
+
+Scalar Range in this menu you can specify
+Min value and Max value of the Scalar Bar
+
+Font - in this menu you can set type, face and color for
+the font of Title and Labels of the Scalar
+Bar
+
+Colors & Labels - in this menu you can set the number of
+colors and the number of labels of the Scalar
+Bar
+
+Orientation - allows choosing between vertical and
+horizontal orientation of the Scalar Bar .
+
+Origin & Size Vertical & Horizontal - allows defining the
+location (X and Y ) and size (Width and
+Height ) of Scalar Bar
+
+X : abscissa of the origin (from the left
+side)
+Y : ordinate of the origin (from the bottom)
+
+Distribution in this menu you can Show/Hide distribution histogram of the values of the Scalar Bar and specify histogram properties
+
+Multicolor the histogram is colored as Scalar Bar
+Monocolor the histogram is colored as selected with Distribution color selector
+
+
+
+
+*/
diff --git a/doc/salome/gui/SMESH/input/selection_filter_library.doc b/doc/salome/gui/SMESH/input/selection_filter_library.doc
index 1f612994f..9657f4c0d 100644
--- a/doc/salome/gui/SMESH/input/selection_filter_library.doc
+++ b/doc/salome/gui/SMESH/input/selection_filter_library.doc
@@ -144,7 +144,14 @@ Additional criteria to select mesh Faces are the following:
one element of mesh only. See also a
\ref free_edges_page "Free Edges quality control".
-Free faces selects 3D mesh elements wich belong to less than two volumes.
+Free faces selects 2D mesh elements wich belong to less than two volumes.
+
+Faces with bare border selects 2D mesh elements having a free border without an edge on it.
+See also \ref bare_border_faces_page "Bare border faces quality control".
+
+Over-constrained faces selects 2D mesh elements having only one border shared
+with other 2D elements.
+See also \ref over_constrained_faces_page "Over-constrained faces quality control".
Borders at Multi-Connections 2D selects cells consisting of edges belonging to
several elements of mesh. The number of mesh elements should be more, less or equal
@@ -187,6 +194,13 @@ diagonals with a value of length, which is more, less or equal
Bad oriented volume selects mesh volumes, which are incorrectly oriented from
the point of view of MED convention.
+
+Over-constrained volumes selects mesh volumes having only one border shared
+with other volumes.
+See also \ref over_constrained_volumes_page "Over-constrained volumes quality control".
+
+Volumes with bare border selects 3D mesh elements having a free border without a face on it.
+See also \ref bare_border_volumes_page "Bare border volumes quality control".
diff --git a/doc/salome/gui/SMESH/input/tui_creating_meshes.doc b/doc/salome/gui/SMESH/input/tui_creating_meshes.doc
index 359ffd7d5..bad32ebf4 100644
--- a/doc/salome/gui/SMESH/input/tui_creating_meshes.doc
+++ b/doc/salome/gui/SMESH/input/tui_creating_meshes.doc
@@ -249,4 +249,48 @@ demonstrating the resulting mesh.
\skipline import geompy
\until #end
+
+\anchor tui_copy_mesh
+Mesh Copying
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+# make geometry of a box
+box = geompy.MakeBoxDXDYDZ(100,100,100)
+face = geompy.SubShapeAllSorted(box, geompy.ShapeType["FACE"])[0]
+
+# generate 3D mesh
+mesh = Mesh(box)
+localAlgo = mesh.Triangle(face)
+mesh.AutomaticHexahedralization()
+
+# objects to copy
+fGroup = mesh.GroupOnGeom( face, "2D on face")
+nGroup = mesh.GroupOnGeom( face, "nodes on face", NODE)
+subMesh = localAlgo.GetSubMesh()
+
+# make a new mesh by copying different part of the mesh
+
+# 1. copy the whole mesh
+newMesh = CopyMesh( mesh, "whole mesh copy")
+
+# 2. copy a group of 2D elements along with groups
+newMesh = CopyMesh( fGroup, "face group copy with groups",toCopyGroups=True)
+
+# 3. copy a group of nodes with preseving their ids
+newMesh = CopyMesh( nGroup, "node group copy", toKeepIDs=True)
+
+# 4. copy some faces
+faceIds = fGroup.GetIDs()[-10:]
+newMesh = CopyMesh( mesh.GetIDSource( faceIds, FACE ), "some faces copy")
+
+# 5. copy some nodes
+nodeIds = nGroup.GetIDs()[-10:]
+newMesh = CopyMesh( mesh.GetIDSource( nodeIds, NODE), "some nodes copy")
+
+# 6. copy a sub-mesh
+newMesh = CopyMesh( subMesh, "submesh copy" )
+\endcode
+
*/
diff --git a/doc/salome/gui/SMESH/input/tui_filters.doc b/doc/salome/gui/SMESH/input/tui_filters.doc
index 6677b2ab5..aa3e1eb1c 100755
--- a/doc/salome/gui/SMESH/input/tui_filters.doc
+++ b/doc/salome/gui/SMESH/input/tui_filters.doc
@@ -90,7 +90,7 @@ Filter 2D mesh elements (faces) according to the minimum angle value:
# create mesh
from SMESH_mechanic import *
# get faces with minimum angle > 75
-filter = smesh.GetFilter(smesh.FACE, smesh.FT_MinimumAngle, smesh.FT_MoreThan, 75)
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_MinimumAngle,">", 75)
ids = mesh.GetIdsFromFilter(filter)
print "Number of faces with minimum angle > 75:", len(ids)
\endcode
@@ -237,7 +237,7 @@ from SMESH_mechanic import *
# add node
mesh.AddNode(0,0,0)
# get all free nodes
-filter = smesh.GetFilter(smesh.EDGE, smesh.FT_FreeNodes)
+filter = smesh.GetFilter(smesh.NODE, smesh.FT_FreeNodes)
ids = mesh.GetIdsFromFilter(filter)
print "Number of free nodes:", len(ids)
\endcode
@@ -255,13 +255,69 @@ Filter free faces:
# create mesh
from SMESH_mechanic import *
# get all free faces
-filter = smesh.GetFilter(smesh.EDGE, smesh.FT_FreeFaces)
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_FreeFaces)
ids = mesh.GetIdsFromFilter(filter)
print "Number of free faces:", len(ids)
\endcode
\sa \ref tui_free_faces
+\section filter_bare_border_faces Bare border faces
+
+Filter faces with bare borders:
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_BareBorderFace
+- threshold value is not required
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# remove some faces to have faces with bare borders
+mesh.RemoveElements( mesh.GetElementsByType(FACE)[0:5] )
+# get all faces bare borders
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_BareBorderFace)
+ids = mesh.GetIdsFromFilter(filter)
+print "Faces with bare borders:", ids
+\endcode
+
+\sa \ref tui_bare_border_faces
+
+\section filter_coplanar_faces Coplanar faces
+
+Filter faces with bare borders:
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_CoplanarFaces
+- threshold value is the face ID
+- tolerance is in degrees
+
+\code
+# create mesh
+from SMESH_mechanic import *
+faceID = mesh.GetElementsByType(FACE)[0]
+# get all faces co-planar to the first face with tolerance 5 degrees
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_CoplanarFaces,faceID,Tolerance=5.0)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces coplanar with the first one:", len(ids)
+\endcode
+
+\section filter_over_constrained_faces Over-constrained faces
+
+Filter over-constrained faces:
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_OverConstrainedFace
+- threshold value is not required
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get all over-constrained faces
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_OverConstrainedFace)
+ids = mesh.GetIdsFromFilter(filter)
+print "Over-constrained faces:", ids
+\endcode
+
+\sa \ref tui_over_constrained_faces
+
\section filter_borders_multiconnection Borders at multi-connection
Filter border 1D mesh elements (edges) according to the specified number of
@@ -377,6 +433,48 @@ print "Number of volumes with maximum element length > 10:", len(ids)
\sa \ref tui_max_element_length_3d
+\section filter_bare_border_volumes Bare border volumes
+
+Filter 3D mesh elements with bare borders:
+- element type is \a smesh.VOLUME
+- functor type is \a smesh.FT_BareBorderVolume
+- threshold value is not required
+
+\code
+# create mesh
+from SMESH_mechanic import *
+mesh.Tetrahedron()
+mesh.Compute()
+# remove some volumes to have volumes with bare borders
+mesh.RemoveElements( mesh.GetElementsByType(VOLUME)[0:5] )
+# get all volumes with bare borders
+filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_BareBorderVolume)
+ids = mesh.GetIdsFromFilter(filter)
+print "Volumes with bare borders:", ids
+\endcode
+
+\sa \ref tui_bare_border_volumes
+
+\section filter_over_constrained_volumes Over-constrained volumes
+
+Filter over-constrained volumes:
+- element type is \a smesh.VOLUME
+- functor type is \a smesh.FT_OverConstrainedVolume
+- threshold value is not required
+
+\code
+# create mesh
+from SMESH_mechanic import *
+mesh.Tetrahedron()
+mesh.Compute()
+# get all over-constrained volumes
+filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_OverConstrainedVolume)
+ids = mesh.GetIdsFromFilter(filter)
+print "Over-constrained volumes:", ids
+\endcode
+
+\sa \ref tui_over_constrained_faces
+
\section filter_belong_to_geom Belong to Geom
Filter mesh entities (nodes or elements) which all nodes lie on the
diff --git a/doc/salome/gui/SMESH/input/tui_quality_controls.doc b/doc/salome/gui/SMESH/input/tui_quality_controls.doc
index fc496dcde..420e507e1 100644
--- a/doc/salome/gui/SMESH/input/tui_quality_controls.doc
+++ b/doc/salome/gui/SMESH/input/tui_quality_controls.doc
@@ -309,6 +309,90 @@ aGroup.Add(aFaceIds)
salome.sg.updateObjBrowser(1)
\endcode
+\section tui_bare_border_faces Bare border faces
+
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+box = geompy.MakeBoxDXDYDZ(100, 100, 100)
+geompy.addToStudy( box, "box" )
+
+mesh = smesh.Mesh(box)
+mesh.Segment().NumberOfSegments(3)
+mesh.Quadrangle()
+mesh.Compute()
+
+# remove 2 faces
+allFaces = mesh.GetElementsByType(FACE)
+mesh.RemoveElements( allFaces[0:2])
+
+bareGroup = mesh.MakeGroup("bare faces", FACE, FT_BareBorderFace)
+assert(bareGroup.Size() == 3)
+\endcode
+
+\section tui_bare_border_volumes Bare border volumes
+
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+box = geompy.MakeBoxDXDYDZ(100, 30, 10)
+# the smallest face of the box
+face = geompy.SubShapeAllSorted( box, geompy.ShapeType["FACE"])[0]
+
+geompy.addToStudy( box, "box" )
+geompy.addToStudyInFather( box, face, "face" )
+
+mesh = Mesh(box)
+mesh.AutomaticHexahedralization();
+
+# remove half of mesh faces from the smallest face
+faceFaces = mesh.GetSubMeshElementsId(face)
+faceToRemove = faceFaces[: len(faceFaces)/2]
+mesh.RemoveElements( faceToRemove )
+
+# make a group of volumes missing the removed faces
+bareGroup = mesh.MakeGroup("bare volumes", VOLUME, FT_BareBorderVolume)
+assert(bareGroup.Size() == len( faceToRemove))
+\endcode
+
+\section tui_over_constrained_faces Over-constrained faces
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+mesh = Mesh()
+faceFilter = GetFilter(FACE,FT_OverConstrainedFace)
+
+#make an edge
+n1 = mesh.AddNode(0,0,0)
+n2 = mesh.AddNode(10,0,0)
+edge = mesh.AddEdge([n1,n2])
+assert( not mesh.GetIdsFromFilter( faceFilter ))
+
+# make faces
+mesh.ExtrusionSweep([edge], MakeDirStruct(0,7,0), 5)
+assert( 2 == len( mesh.GetIdsFromFilter( faceFilter )))
+\endcode
+
+\section tui_over_constrained_volumes Over-constrained volumes
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+mesh = Mesh()
+volumeFilter = GetFilter(VOLUME,FT_OverConstrainedVolume)
+
+# make volumes by extrusion of one face
+n1 = mesh.AddNode(0,0,0)
+n2 = mesh.AddNode(10,0,0)
+edge = mesh.AddEdge([n1,n2])
+mesh.ExtrusionSweep([edge], MakeDirStruct(0,7,0), 1)
+mesh.ExtrusionSweep( mesh.GetElementsByType(FACE), MakeDirStruct(0,0,5), 7)
+assert( 2 == len( mesh.GetIdsFromFilter( volumeFilter )))
+\endcode
+
\section tui_length_2d Length 2D
\code
diff --git a/idl/SMESH_Filter.idl b/idl/SMESH_Filter.idl
index e12607bcd..087a0b48b 100644
--- a/idl/SMESH_Filter.idl
+++ b/idl/SMESH_Filter.idl
@@ -64,6 +64,10 @@ module SMESH
FT_LyingOnGeom,
FT_RangeOfIds,
FT_BadOrientedVolume,
+ FT_BareBorderVolume,
+ FT_BareBorderFace,
+ FT_OverConstrainedVolume,
+ FT_OverConstrainedFace,
FT_LinearOrQuadratic,
FT_GroupColor,
FT_ElemGeomType,
@@ -88,6 +92,7 @@ module SMESH
};
typedef sequence Histogram;
+
/*!
* Base interface for all functors ( i.e. numerical functors and predicates )
*/
@@ -98,8 +103,6 @@ module SMESH
ElementType GetElementType();
};
-
-
/*!
* Numerical functors are intended for calculating value by Id of mesh entity
*/
@@ -150,6 +153,7 @@ module SMESH
Values GetValues();
};
+
/*!
* Predicates are intended for verification of criteria,
* must return bool value by mesh id
@@ -166,6 +170,29 @@ module SMESH
*/
interface BadOrientedVolume: Predicate {};
+ /*!
+ * Logical functor (predicate) "Volumes with bare border".
+ * Verify whether a mesh volume has a free facet without a mesh face on it
+ */
+ interface BareBorderVolume: Predicate {};
+ /*!
+ * Logical functor (predicate) "Faces with bare border".
+ * Verify whether a mesh face has a side not shared with another face
+ * and without a mesh edge on it
+ */
+ interface BareBorderFace: Predicate {};
+
+ /*!
+ * Logical functor (predicate) "Over-constrained Volume"
+ * Verify whether a mesh volume has only one facet shared with other volumes
+ */
+ interface OverConstrainedVolume: Predicate {};
+ /*!
+ * Logical functor (predicate) "Over-constrained Face".
+ * Verify whether a mesh face has only one border shared with other faces
+ */
+ interface OverConstrainedFace: Predicate {};
+
/*!
* Logical functor (predicate) "Belong To Geometry".
* Verify whether mesh element or node belong to pointed Geom Object
@@ -503,6 +530,10 @@ module SMESH
RangeOfIds CreateRangeOfIds();
BadOrientedVolume CreateBadOrientedVolume();
+ BareBorderVolume CreateBareBorderVolume();
+ BareBorderFace CreateBareBorderFace();
+ OverConstrainedVolume CreateOverConstrainedVolume();
+ OverConstrainedFace CreateOverConstrainedFace();
LinearOrQuadratic CreateLinearOrQuadratic();
GroupColor CreateGroupColor();
diff --git a/idl/SMESH_Gen.idl b/idl/SMESH_Gen.idl
index 3c375e625..d958719e3 100644
--- a/idl/SMESH_Gen.idl
+++ b/idl/SMESH_Gen.idl
@@ -221,10 +221,45 @@ module SMESH
raises ( SALOME::SALOME_Exception );
/*!
- * Create a Mesh object, without a geometry shape reference
+ * Create a mesh by copying a part of another mesh
+ * \param meshPart - a part of mesh to copy
+ * \param meshName - a name of the new mesh
+ * \param toCopyGroups - to create in the new mesh groups
+ * the copied elements belongs to
+ * \param toKeepIDs - to preserve IDs of the copied elements or not
*/
-// SMESH_Mesh NewEmpty()
-// raises ( SALOME::SALOME_Exception );
+ SMESH_Mesh CopyMesh(in SMESH_IDSource meshPart,
+ in string meshName,
+ in boolean toCopyGroups,
+ in boolean toKeepIDs)
+ raises ( SALOME::SALOME_Exception );
+
+ /*!
+ * Concatenate the given meshes into one mesh.
+ * Union groups with the same name and type if
+ * theUniteIdenticalGroups flag is true.
+ * Merge coincident nodes and elements if
+ * theMergeNodesAndElements flag is true.
+ */
+ SMESH_Mesh Concatenate(in mesh_array theMeshesArray,
+ in boolean theUniteIdenticalGroups,
+ in boolean theMergeNodesAndElements,
+ in double theMergeTolerance)
+ raises ( SALOME::SALOME_Exception );
+
+ /*!
+ * Concatenate the given meshes into one mesh.
+ * Union groups with the same name and type if
+ * theUniteIdenticalGroups flag is true.
+ * Merge coincident nodes and elements if
+ * theMergeNodesAndElements flag is true.
+ * Create the groups of all elements from initial meshes.
+ */
+ SMESH_Mesh ConcatenateWithGroups(in mesh_array theMeshesArray,
+ in boolean theUniteIdenticalGroups,
+ in boolean theMergeNodesAndElements,
+ in double theMergeTolerance)
+ raises ( SALOME::SALOME_Exception );
/*!
* Mesh a subShape.
@@ -309,33 +344,6 @@ module SMESH
in long theElementID)
raises ( SALOME::SALOME_Exception );
- /*!
- * Concatenate the given meshes into one mesh.
- * Union groups with the same name and type if
- * theUniteIdenticalGroups flag is true.
- * Merge coincident nodes and elements if
- * theMergeNodesAndElements flag is true.
- */
- SMESH_Mesh Concatenate(in mesh_array theMeshesArray,
- in boolean theUniteIdenticalGroups,
- in boolean theMergeNodesAndElements,
- in double theMergeTolerance)
- raises ( SALOME::SALOME_Exception );
-
- /*!
- * Concatenate the given meshes into one mesh.
- * Union groups with the same name and type if
- * theUniteIdenticalGroups flag is true.
- * Merge coincident nodes and elements if
- * theMergeNodesAndElements flag is true.
- * Create the groups of all elements from initial meshes.
- */
- SMESH_Mesh ConcatenateWithGroups(in mesh_array theMeshesArray,
- in boolean theUniteIdenticalGroups,
- in boolean theMergeNodesAndElements,
- in double theMergeTolerance)
- raises ( SALOME::SALOME_Exception );
-
/*!
* \brief Return id of object, registered in current study context
*
diff --git a/resources/Makefile.am b/resources/Makefile.am
index cc7d5a885..623d04ff1 100644
--- a/resources/Makefile.am
+++ b/resources/Makefile.am
@@ -107,6 +107,10 @@ dist_salomeres_DATA = \
mesh_vertex_n.png \
mesh_vertex.png \
mesh_volume_3d.png \
+ bare_border_volume.png \
+ bare_border_face.png \
+ over_constrained_volume.png \
+ over_constrained_face.png \
mesh_wireframe.png \
mesh_points.png \
mesh_wrap.png \
@@ -173,6 +177,7 @@ dist_salomeres_DATA = \
mesh_tree_hypo_projection_3d.png \
mesh_tree_hypo_projection_2d.png \
mesh_build_compound.png \
+ copy_mesh.png \
mesh_node_to_point.png \
mesh_tree_mesh_partial.png \
mesh_extractGroup.png \
diff --git a/resources/bare_border_face.png b/resources/bare_border_face.png
new file mode 100644
index 000000000..1993f2087
Binary files /dev/null and b/resources/bare_border_face.png differ
diff --git a/resources/bare_border_volume.png b/resources/bare_border_volume.png
new file mode 100644
index 000000000..3ef6e6a46
Binary files /dev/null and b/resources/bare_border_volume.png differ
diff --git a/resources/copy_mesh.png b/resources/copy_mesh.png
new file mode 100644
index 000000000..263479f3b
Binary files /dev/null and b/resources/copy_mesh.png differ
diff --git a/resources/over_constrained_face.png b/resources/over_constrained_face.png
new file mode 100644
index 000000000..22b61bbed
Binary files /dev/null and b/resources/over_constrained_face.png differ
diff --git a/resources/over_constrained_volume.png b/resources/over_constrained_volume.png
new file mode 100644
index 000000000..0e2da263f
Binary files /dev/null and b/resources/over_constrained_volume.png differ
diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx
index 677f467de..42b5b6a1a 100644
--- a/src/Controls/SMESH_Controls.cxx
+++ b/src/Controls/SMESH_Controls.cxx
@@ -310,12 +310,16 @@ double NumericalFunctor::GetValue( long theId )
* \param nbIntervals - number of intervals
* \param nbEvents - number of mesh elements having values within i-th interval
* \param funValues - boundaries of intervals
+ * \param elements - elements to check vulue of; empty list means "of all"
+ * \param minmax - boundaries of diapason of values to divide into intervals
*/
//================================================================================
void NumericalFunctor::GetHistogram(int nbIntervals,
std::vector& nbEvents,
- std::vector& funValues)
+ std::vector& funValues,
+ const vector& elements,
+ const double* minmax)
{
if ( nbIntervals < 1 ||
!myMesh ||
@@ -326,13 +330,30 @@ void NumericalFunctor::GetHistogram(int nbIntervals,
// get all values sorted
std::multiset< double > values;
- SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator(GetType());
- while ( elemIt->more() )
- values.insert( GetValue( elemIt->next()->GetID() ));
+ if ( elements.empty() )
+ {
+ SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator(GetType());
+ while ( elemIt->more() )
+ values.insert( GetValue( elemIt->next()->GetID() ));
+ }
+ else
+ {
+ vector::const_iterator id = elements.begin();
+ for ( ; id != elements.end(); ++id )
+ values.insert( GetValue( *id ));
+ }
+ if ( minmax )
+ {
+ funValues[0] = minmax[0];
+ funValues[nbIntervals] = minmax[1];
+ }
+ else
+ {
+ funValues[0] = *values.begin();
+ funValues[nbIntervals] = *values.rbegin();
+ }
// case nbIntervals == 1
- funValues[0] = *values.begin();
- funValues[nbIntervals] = *values.rbegin();
if ( nbIntervals == 1 )
{
nbEvents[0] = values.size();
@@ -350,15 +371,21 @@ void NumericalFunctor::GetHistogram(int nbIntervals,
std::multiset< double >::iterator min = values.begin(), max;
for ( int i = 0; i < nbIntervals; ++i )
{
+ // find end value of i-th interval
double r = (i+1) / double( nbIntervals );
funValues[i+1] = funValues.front() * (1-r) + funValues.back() * r;
+
+ // count values in the i-th interval if there are any
if ( min != values.end() && *min <= funValues[i+1] )
{
- max = values.upper_bound( funValues[i+1] ); // greater than funValues[i+1], or end()
+ // find the first value out of the interval
+ max = values.upper_bound( funValues[i+1] ); // max is greater than funValues[i+1], or end()
nbEvents[i] = std::distance( min, max );
min = max;
}
}
+ // add values larger than minmax[1]
+ nbEvents.back() += std::distance( min, values.end() );
}
//=======================================================================
@@ -1902,7 +1929,115 @@ SMDSAbs_ElementType BadOrientedVolume::GetType() const
return SMDSAbs_Volume;
}
+/*
+ Class : BareBorderVolume
+*/
+bool BareBorderVolume::IsSatisfy(long theElementId )
+{
+ SMDS_VolumeTool myTool;
+ if ( myTool.Set( myMesh->FindElement(theElementId)))
+ {
+ for ( int iF = 0; iF < myTool.NbFaces(); ++iF )
+ if ( myTool.IsFreeFace( iF ))
+ {
+ const SMDS_MeshNode** n = myTool.GetFaceNodes(iF);
+ vector< const SMDS_MeshNode*> nodes( n, n+myTool.NbFaceNodes(iF));
+ if ( !myMesh->FindElement( nodes, SMDSAbs_Face, /*Nomedium=*/false))
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ Class : BareBorderFace
+*/
+
+bool BareBorderFace::IsSatisfy(long theElementId )
+{
+ if ( const SMDS_MeshElement* face = myMesh->FindElement(theElementId))
+ if ( face->GetType() == SMDSAbs_Face )
+ {
+ int nbN = face->NbCornerNodes();
+ for ( int i = 0; i < nbN; ++i )
+ {
+ // check if a link is shared by another face
+ const SMDS_MeshNode* n1 = face->GetNode( i );
+ const SMDS_MeshNode* n2 = face->GetNode( (i+1)%nbN );
+ SMDS_ElemIteratorPtr fIt = n1->GetInverseElementIterator( SMDSAbs_Face );
+ bool isShared = false;
+ while ( !isShared && fIt->more() )
+ {
+ const SMDS_MeshElement* f = fIt->next();
+ isShared = ( f != face && f->GetNodeIndex(n2) != -1 );
+ }
+ if ( !isShared )
+ {
+ myLinkNodes.resize( 2 + face->IsQuadratic());
+ myLinkNodes[0] = n1;
+ myLinkNodes[1] = n2;
+ if ( face->IsQuadratic() )
+ myLinkNodes[2] = face->GetNode( i+nbN );
+ return !myMesh->FindElement( myLinkNodes, SMDSAbs_Edge, /*noMedium=*/false);
+ }
+ }
+ }
+ return false;
+}
+
+/*
+ Class : OverConstrainedVolume
+*/
+
+bool OverConstrainedVolume::IsSatisfy(long theElementId )
+{
+ // An element is over-constrained if it has N-1 free borders where
+ // N is the number of edges/faces for a 2D/3D element.
+ SMDS_VolumeTool myTool;
+ if ( myTool.Set( myMesh->FindElement(theElementId)))
+ {
+ int nbSharedFaces = 0;
+ for ( int iF = 0; iF < myTool.NbFaces(); ++iF )
+ if ( !myTool.IsFreeFace( iF ) && ++nbSharedFaces > 1 )
+ break;
+ return ( nbSharedFaces == 1 );
+ }
+ return false;
+}
+
+/*
+ Class : OverConstrainedFace
+*/
+
+bool OverConstrainedFace::IsSatisfy(long theElementId )
+{
+ // An element is over-constrained if it has N-1 free borders where
+ // N is the number of edges/faces for a 2D/3D element.
+ if ( const SMDS_MeshElement* face = myMesh->FindElement(theElementId))
+ if ( face->GetType() == SMDSAbs_Face )
+ {
+ int nbSharedBorders = 0;
+ int nbN = face->NbCornerNodes();
+ for ( int i = 0; i < nbN; ++i )
+ {
+ // check if a link is shared by another face
+ const SMDS_MeshNode* n1 = face->GetNode( i );
+ const SMDS_MeshNode* n2 = face->GetNode( (i+1)%nbN );
+ SMDS_ElemIteratorPtr fIt = n1->GetInverseElementIterator( SMDSAbs_Face );
+ bool isShared = false;
+ while ( !isShared && fIt->more() )
+ {
+ const SMDS_MeshElement* f = fIt->next();
+ isShared = ( f != face && f->GetNodeIndex(n2) != -1 );
+ }
+ if ( isShared && ++nbSharedBorders > 1 )
+ break;
+ }
+ return ( nbSharedBorders == 1 );
+ }
+ return false;
+}
/*
Class : FreeBorders
diff --git a/src/Controls/SMESH_ControlsDef.hxx b/src/Controls/SMESH_ControlsDef.hxx
index 915bd9f4b..0a71438d7 100644
--- a/src/Controls/SMESH_ControlsDef.hxx
+++ b/src/Controls/SMESH_ControlsDef.hxx
@@ -127,9 +127,11 @@ namespace SMESH{
virtual void SetMesh( const SMDS_Mesh* theMesh );
virtual double GetValue( long theElementId );
virtual double GetValue(const TSequenceOfXYZ& thePoints) { return -1.0;};
- void GetHistogram(int nbIntervals,
- std::vector& nbEvents,
- std::vector& funValues);
+ void GetHistogram(int nbIntervals,
+ std::vector& nbEvents,
+ std::vector& funValues,
+ const std::vector& elements,
+ const double* minmax=0);
virtual SMDSAbs_ElementType GetType() const = 0;
virtual double GetBadRate( double Value, int nbNodes ) const = 0;
long GetPrecision() const;
@@ -373,11 +375,72 @@ namespace SMESH{
virtual void SetMesh( const SMDS_Mesh* theMesh );
virtual bool IsSatisfy( long theElementId );
virtual SMDSAbs_ElementType GetType() const;
-
+
protected:
const SMDS_Mesh* myMesh;
};
-
+
+ /*
+ BareBorderVolume
+ */
+ class SMESHCONTROLS_EXPORT BareBorderVolume: public Predicate
+ {
+ public:
+ BareBorderVolume():myMesh(0) {}
+ virtual void SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; }
+ virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Volume; }
+ virtual bool IsSatisfy( long theElementId );
+ protected:
+ const SMDS_Mesh* myMesh;
+ };
+ typedef boost::shared_ptr BareBorderVolumePtr;
+
+ /*
+ BareBorderFace
+ */
+ class SMESHCONTROLS_EXPORT BareBorderFace: public Predicate
+ {
+ public:
+ BareBorderFace():myMesh(0) {}
+ virtual void SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; }
+ virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Face; }
+ virtual bool IsSatisfy( long theElementId );
+ protected:
+ const SMDS_Mesh* myMesh;
+ std::vector< const SMDS_MeshNode* > myLinkNodes;
+ };
+ typedef boost::shared_ptr BareBorderFacePtr;
+
+ /*
+ OverConstrainedVolume
+ */
+ class SMESHCONTROLS_EXPORT OverConstrainedVolume: public Predicate
+ {
+ public:
+ OverConstrainedVolume():myMesh(0) {}
+ virtual void SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; }
+ virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Volume; }
+ virtual bool IsSatisfy( long theElementId );
+ protected:
+ const SMDS_Mesh* myMesh;
+ };
+ typedef boost::shared_ptr OverConstrainedVolumePtr;
+
+ /*
+ OverConstrainedFace
+ */
+ class SMESHCONTROLS_EXPORT OverConstrainedFace: public Predicate
+ {
+ public:
+ OverConstrainedFace():myMesh(0) {}
+ virtual void SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; }
+ virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Face; }
+ virtual bool IsSatisfy( long theElementId );
+ protected:
+ const SMDS_Mesh* myMesh;
+ std::vector< const SMDS_MeshNode* > myLinkNodes;
+ };
+ typedef boost::shared_ptr OverConstrainedFacePtr;
/*
Class : FreeEdges
@@ -399,7 +462,7 @@ namespace SMESH{
};
typedef std::set TBorders;
void GetBoreders(TBorders& theBorders);
-
+
protected:
const SMDS_Mesh* myMesh;
};
diff --git a/src/OBJECT/SMESH_Actor.cxx b/src/OBJECT/SMESH_Actor.cxx
index 4b4f432ff..cafd4b000 100644
--- a/src/OBJECT/SMESH_Actor.cxx
+++ b/src/OBJECT/SMESH_Actor.cxx
@@ -204,6 +204,25 @@ SMESH_ActorDef::SMESH_ActorDef()
aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
//#endif
+ my3DExtActor = SMESH_DeviceActor::New();
+ my3DExtActor->SetUserMatrix(aMatrix);
+ my3DExtActor->PickableOff();
+ my3DExtActor->SetProperty(my2DExtProp);
+ my3DExtActor->SetBackfaceProperty(my2DExtProp);
+ my3DExtActor->SetRepresentation(SMESH_DeviceActor::eSurface);
+ aFilter = my3DExtActor->GetExtractUnstructuredGrid();
+ aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
+ aFilter->RegisterCellsWithType(VTK_TETRA);
+ aFilter->RegisterCellsWithType(VTK_VOXEL);
+ aFilter->RegisterCellsWithType(VTK_HEXAHEDRON);
+ aFilter->RegisterCellsWithType(VTK_WEDGE);
+ aFilter->RegisterCellsWithType(VTK_PYRAMID);
+ aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA);
+ aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
+ aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
+ aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
+ aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
+
//Definition 1D device of the actor
//---------------------------------
myEdgeProp = vtkProperty::New();
@@ -537,6 +556,7 @@ SMESH_ActorDef::~SMESH_ActorDef()
my2DExtProp->Delete();
my2DExtActor->Delete();
my3DActor->Delete();
+ my3DExtActor->Delete();
myNodeActor->Delete();
myBaseActor->Delete();
@@ -728,8 +748,8 @@ SetControlMode(eControl theMode,
bool anIsScalarVisible = theMode > eNone;
- if(anIsScalarVisible){
- switch(theMode){
+ if(anIsScalarVisible) {
+ switch(theMode) {
case eLength:
{
SMESH::Controls::Length* aControl = new SMESH::Controls::Length();
@@ -760,6 +780,14 @@ SetControlMode(eControl theMode,
myFunctor.reset(new SMESH::Controls::FreeFaces());
myControlActor = my2DActor;
break;
+ case eBareBorderFace:
+ myFunctor.reset(new SMESH::Controls::BareBorderFace());
+ myControlActor = my2DActor;
+ break;
+ case eOverConstrainedFace:
+ myFunctor.reset(new SMESH::Controls::OverConstrainedFace());
+ myControlActor = my2DActor;
+ break;
case eMultiConnection:
myFunctor.reset(new SMESH::Controls::MultiConnection());
myControlActor = my1DActor;
@@ -824,6 +852,18 @@ SetControlMode(eControl theMode,
myControlActor = my3DActor;
break;
}
+ case eBareBorderVolume:
+ {
+ myFunctor.reset(new SMESH::Controls::BareBorderVolume());
+ myControlActor = my3DActor;
+ break;
+ }
+ case eOverConstrainedVolume:
+ {
+ myFunctor.reset(new SMESH::Controls::OverConstrainedVolume());
+ myControlActor = my3DActor;
+ break;
+ }
case eMinimumAngle:
{
SMESH::Controls::MinimumAngle* aControl = new SMESH::Controls::MinimumAngle();
@@ -865,14 +905,22 @@ SetControlMode(eControl theMode,
my1DExtActor->SetExtControlMode(myFunctor);
break;
case eFreeFaces:
+ case eBareBorderFace:
+ case eOverConstrainedFace:
my2DExtActor->SetExtControlMode(myFunctor);
break;
+ case eBareBorderVolume:
+ case eOverConstrainedVolume:
+ my3DExtActor->SetExtControlMode(myFunctor);
+ break;
case eLength2D:
case eMultiConnection2D:
my1DExtActor->SetExtControlMode(myFunctor,myScalarBarActor,myLookupTable);
+ UpdateDistribution();
break;
default:
myControlActor->SetControlMode(myFunctor,myScalarBarActor,myLookupTable);
+ UpdateDistribution();
}
}
@@ -916,6 +964,7 @@ void SMESH_ActorDef::AddToRender(vtkRenderer* theRenderer){
theRenderer->AddActor(myNodeExtActor);
my3DActor->AddToRender(theRenderer);
+ my3DExtActor->AddToRender(theRenderer);
my2DActor->AddToRender(theRenderer);
my2DExtActor->AddToRender(theRenderer);
@@ -959,6 +1008,7 @@ void SMESH_ActorDef::RemoveFromRender(vtkRenderer* theRenderer){
my2DActor->RemoveFromRender(theRenderer);
my2DExtActor->RemoveFromRender(theRenderer);
my3DActor->RemoveFromRender(theRenderer);
+ my3DExtActor->RemoveFromRender(theRenderer);
theRenderer->RemoveActor(myScalarBarActor);
theRenderer->RemoveActor(myPointLabels);
@@ -994,6 +1044,7 @@ bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj,
my2DActor->Init(myVisualObj,myImplicitBoolean);
my2DExtActor->Init(myVisualObj,myImplicitBoolean);
my3DActor->Init(myVisualObj,myImplicitBoolean);
+ my3DExtActor->Init(myVisualObj,myImplicitBoolean);
my0DActor->GetMapper()->SetLookupTable(myLookupTable);
//my0DExtActor->GetMapper()->SetLookupTable(myLookupTable);
@@ -1004,6 +1055,7 @@ bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj,
my2DActor->GetMapper()->SetLookupTable(myLookupTable);
my2DExtActor->GetMapper()->SetLookupTable(myLookupTable);
my3DActor->GetMapper()->SetLookupTable(myLookupTable);
+ my3DExtActor->GetMapper()->SetLookupTable(myLookupTable);
vtkFloatingPointType aFactor, aUnits;
my2DActor->GetPolygonOffsetParameters(aFactor,aUnits);
@@ -1076,6 +1128,7 @@ void SMESH_ActorDef::SetTransform(VTKViewer_Transform* theTransform){
my2DActor->SetTransform(theTransform);
my2DExtActor->SetTransform(theTransform);
my3DActor->SetTransform(theTransform);
+ my3DExtActor->SetTransform(theTransform);
Modified();
}
@@ -1131,6 +1184,7 @@ void SMESH_ActorDef::SetShrinkFactor(vtkFloatingPointType theValue){
my2DActor->SetShrinkFactor(theValue);
my2DExtActor->SetShrinkFactor(theValue);
my3DActor->SetShrinkFactor(theValue);
+ my3DExtActor->SetShrinkFactor(theValue);
Modified();
}
@@ -1146,6 +1200,7 @@ void SMESH_ActorDef::SetShrink(){
my2DActor->SetShrink();
my2DExtActor->SetShrink();
my3DActor->SetShrink();
+ my3DExtActor->SetShrink();
myIsShrunk = true;
Modified();
@@ -1162,6 +1217,7 @@ void SMESH_ActorDef::UnShrink(){
my2DActor->UnShrink();
my2DExtActor->UnShrink();
my3DActor->UnShrink();
+ my3DExtActor->UnShrink();
myIsShrunk = false;
Modified();
@@ -1208,6 +1264,7 @@ void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation){
my2DActor->VisibilityOff();
my2DExtActor->VisibilityOff();
my3DActor->VisibilityOff();
+ my3DExtActor->VisibilityOff();
myScalarBarActor->VisibilityOff();
myPointLabels->VisibilityOff();
@@ -1227,8 +1284,14 @@ void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation){
my1DExtActor->VisibilityOn();
break;
case eFreeFaces:
+ case eBareBorderFace:
+ case eOverConstrainedFace:
my2DExtActor->VisibilityOn();
break;
+ case eBareBorderVolume:
+ case eOverConstrainedVolume:
+ my3DExtActor->VisibilityOn();
+ break;
case eLength2D:
case eMultiConnection2D:
my1DExtActor->VisibilityOn();
@@ -1467,6 +1530,7 @@ void SMESH_ActorDef::SetRepresentation (int theMode)
//my0DExtActor->SetVisibility(false);
my1DExtActor->SetVisibility(false);
my2DExtActor->SetVisibility(false);
+ my3DExtActor->SetVisibility(false);
// ???
//my0DActor->SetProperty(aProp);
@@ -1797,6 +1861,7 @@ SMESH_ActorDef::SetImplicitFunctionUsed(bool theIsImplicitFunctionUsed)
my2DActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
my2DExtActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
my3DActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
+ my3DExtActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
}
vtkIdType
@@ -1958,7 +2023,7 @@ void SMESH_ActorDef::UpdateScalarBar()
myScalarBarActor->SetDistributionColoringType(coloringType);
QColor distributionColor = mgr->colorValue("SMESH", "distribution_color",
- QColor(255, 255, 255));
+ QColor(255, 255, 255));
double rgb[3];
rgb[0]= distributionColor.red()/255.;
rgb[1]= distributionColor.green()/255.;
@@ -1968,6 +2033,27 @@ void SMESH_ActorDef::UpdateScalarBar()
}
+void SMESH_ActorDef::UpdateDistribution()
+{
+ if(SMESH::Controls::NumericalFunctor* fun =
+ dynamic_cast(myFunctor.get()))
+ {
+ int nbIntervals = myScalarBarActor->GetMaximumNumberOfColors();
+ std::vector nbEvents;
+ std::vector funValues;
+ SMESH_VisualObjDef::TEntityList elems;
+ if ( ! dynamic_cast(myVisualObj.get()))
+ dynamic_cast(myVisualObj.get())->GetEntities( fun->GetType(), elems );
+ std::vector elemIds;
+ for ( SMESH_VisualObjDef::TEntityList::iterator e = elems.begin(); e != elems.end(); ++e)
+ elemIds.push_back( (*e)->GetID());
+ vtkLookupTable* lookupTable = static_cast(myScalarBarActor->GetLookupTable());
+ double * range = lookupTable->GetRange();
+ fun->GetHistogram(nbIntervals, nbEvents, funValues, elemIds, range);
+ myScalarBarActor->SetDistribution(nbEvents);
+ }
+}
+
void SMESH_ActorDef::SetQuadratic2DRepresentation(EQuadratic2DRepresentation theMode)
{
switch(theMode) {
diff --git a/src/OBJECT/SMESH_Actor.h b/src/OBJECT/SMESH_Actor.h
index 24a57a00a..744571e41 100644
--- a/src/OBJECT/SMESH_Actor.h
+++ b/src/OBJECT/SMESH_Actor.h
@@ -123,7 +123,8 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
enum eControl{eNone, eLength, eLength2D, eFreeBorders, eFreeEdges, eFreeNodes,
eFreeFaces, eMultiConnection, eArea, eTaper, eAspectRatio,
eMinimumAngle, eWarping, eSkew, eAspectRatio3D, eMultiConnection2D, eVolume3D,
- eMaxElementLength2D, eMaxElementLength3D};
+ eMaxElementLength2D, eMaxElementLength3D, eBareBorderFace, eBareBorderVolume,
+ eOverConstrainedFace, eOverConstrainedVolume};
virtual void SetControlMode(eControl theMode) = 0;
virtual eControl GetControlMode() = 0;
virtual SMESH::Controls::FunctorPtr GetFunctor() = 0;
@@ -141,6 +142,7 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
virtual long GetControlsPrecision() const = 0;
virtual void UpdateScalarBar() = 0;
+ virtual void UpdateDistribution() = 0;
};
diff --git a/src/OBJECT/SMESH_ActorDef.h b/src/OBJECT/SMESH_ActorDef.h
index 09b2232f0..53001f4ef 100644
--- a/src/OBJECT/SMESH_ActorDef.h
+++ b/src/OBJECT/SMESH_ActorDef.h
@@ -196,6 +196,7 @@ class SMESH_ActorDef : public SMESH_Actor
virtual long GetControlsPrecision() const { return myControlsPrecision; }
virtual void UpdateScalarBar();
+ virtual void UpdateDistribution();
virtual void SetQuadratic2DRepresentation(EQuadratic2DRepresentation);
@@ -234,6 +235,7 @@ class SMESH_ActorDef : public SMESH_Actor
SMESH_DeviceActor* my2DActor;
SMESH_DeviceActor* my2DExtActor;
SMESH_DeviceActor* my3DActor;
+ SMESH_DeviceActor* my3DExtActor;
SMESH_DeviceActor* myControlActor;
vtkProperty* myNodeExtProp;
diff --git a/src/OBJECT/SMESH_DeviceActor.cxx b/src/OBJECT/SMESH_DeviceActor.cxx
index 600a4987c..d4a04203b 100644
--- a/src/OBJECT/SMESH_DeviceActor.cxx
+++ b/src/OBJECT/SMESH_DeviceActor.cxx
@@ -310,12 +310,6 @@ SMESH_DeviceActor
double aValue = aNumericalFunctor->GetValue(anObjId);
aScalars->SetValue(i,aValue);
}
- int nbIntervals = theScalarBarActor->GetMaximumNumberOfColors();
- std::vector nbEvents;
- std::vector funValues;
- aNumericalFunctor->GetHistogram(nbIntervals, nbEvents, funValues);
- theScalarBarActor->SetDistribution(nbEvents);
-
}else if(Predicate* aPredicate = dynamic_cast(theFunctor.get())){
for(vtkIdType i = 0; i < aNbCells; i++){
vtkIdType anId = myExtractUnstructuredGrid->GetInputId(i);
@@ -475,16 +469,6 @@ SMESH_DeviceActor
myMergeFilter->SetScalars(aDataSet);
aDataSet->Delete();
}
-
- //Set Distribution
- if(NumericalFunctor* aNumericalFunctor = dynamic_cast(theFunctor.get())){
- int nbIntervals = theScalarBarActor->GetMaximumNumberOfColors();
- std::vector nbEvents;
- std::vector funValues;
- aNumericalFunctor->GetHistogram(nbIntervals, nbEvents, funValues);
- theScalarBarActor->SetDistribution(nbEvents);
- }
-
}
GetMapper()->SetScalarVisibility(anIsInitialized);
theScalarBarActor->SetVisibility(anIsInitialized);
@@ -500,8 +484,13 @@ SMESH_DeviceActor
myVisualObj->UpdateFunctor(theFunctor);
using namespace SMESH::Controls;
- if ( dynamic_cast(theFunctor.get()) ||
- dynamic_cast(theFunctor.get()) ) {
+ if ( dynamic_cast(theFunctor.get()) ||
+ dynamic_cast(theFunctor.get()) ||
+ dynamic_cast(theFunctor.get()) ||
+ dynamic_cast(theFunctor.get()) ||
+ dynamic_cast(theFunctor.get()) ||
+ dynamic_cast(theFunctor.get()))
+ {
Predicate* aFreePredicate = dynamic_cast(theFunctor.get());
myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
@@ -514,7 +503,9 @@ SMESH_DeviceActor
if(!myExtractUnstructuredGrid->IsCellsRegistered())
myExtractUnstructuredGrid->RegisterCell(-1);
SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid());
- }else if(FreeEdges* aFreeEdges = dynamic_cast(theFunctor.get())){
+ }
+ else if(FreeEdges* aFreeEdges = dynamic_cast(theFunctor.get()))
+ {
SMESH::Controls::FreeEdges::TBorders aBorders;
aFreeEdges->GetBoreders(aBorders);
vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
@@ -561,7 +552,9 @@ SMESH_DeviceActor
SetUnstructuredGrid(aDataSet);
aDataSet->Delete();
- }else if(FreeNodes* aFreeNodes = dynamic_cast(theFunctor.get())){
+ }
+ else if(FreeNodes* aFreeNodes = dynamic_cast(theFunctor.get()))
+ {
myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
vtkIdType aNbNodes = myVisualObj->GetNbEntities(SMDSAbs_Node);
for( vtkIdType i = 0; i < aNbNodes; i++ ){
diff --git a/src/OBJECT/SMESH_PreviewActorsCollection.cxx b/src/OBJECT/SMESH_PreviewActorsCollection.cxx
index 059edd927..91e38e354 100644
--- a/src/OBJECT/SMESH_PreviewActorsCollection.cxx
+++ b/src/OBJECT/SMESH_PreviewActorsCollection.cxx
@@ -101,7 +101,7 @@ bool SMESH_PreviewActorsCollection::Init( const TopoDS_Shape& theShape, TopAbs_S
int index = myMapOfShapes.FindIndex( exp.Current() );
if ( index && !myMapOfActors.contains( index ) ) {
// create actor if the index is present
- if ( GEOM_Actor* anActor = createActor( exp.Current() )) {
+ if ( GEOM_Actor* anActor = createActor( exp.Current().Oriented(TopAbs_FORWARD))) {
// Create new entry for actor
QString aString = theEntry;
aString += QString("_%1").arg( index ); // add index to actor entry
diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx
index 39c2ca976..a85e23e23 100644
--- a/src/SMESH/SMESH_Mesh.cxx
+++ b/src/SMESH/SMESH_Mesh.cxx
@@ -265,14 +265,12 @@ void SMESH_Mesh::Clear()
_myMeshDS->ClearMesh();
// update compute state of submeshes
- if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) ) {
- SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
- /*complexShapeFirst=*/false);
- while ( smIt->more() ) {
- sm = smIt->next();
- sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
- sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); // for event listeners (issue 0020918)
- }
+ if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) )
+ {
+ sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ sm->ComputeSubMeshStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); // for event listeners (issue 0020918)
+ sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
}
_isModified = false;
}
diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx
index 4a970ffa2..d21d4784c 100644
--- a/src/SMESH/SMESH_MeshEditor.cxx
+++ b/src/SMESH/SMESH_MeshEditor.cxx
@@ -132,114 +132,125 @@ SMESH_MeshEditor::AddElement(const vector & node,
int nbnode = node.size();
SMESHDS_Mesh* mesh = GetMeshDS();
switch ( type ) {
- case SMDSAbs_0DElement:
- if ( nbnode == 1 ) {
- if ( ID >= 0 ) e = mesh->Add0DElementWithID(node[0], ID);
- else e = mesh->Add0DElement (node[0] );
- }
- break;
- case SMDSAbs_Edge:
- if ( nbnode == 2 ) {
- if ( ID >= 0 ) e = mesh->AddEdgeWithID(node[0], node[1], ID);
- else e = mesh->AddEdge (node[0], node[1] );
- }
- else if ( nbnode == 3 ) {
- if ( ID >= 0 ) e = mesh->AddEdgeWithID(node[0], node[1], node[2], ID);
- else e = mesh->AddEdge (node[0], node[1], node[2] );
- }
- break;
case SMDSAbs_Face:
if ( !isPoly ) {
if (nbnode == 3) {
if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], ID);
- else e = mesh->AddFace (node[0], node[1], node[2] );
+ else e = mesh->AddFace (node[0], node[1], node[2] );
}
else if (nbnode == 4) {
if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], ID);
- else e = mesh->AddFace (node[0], node[1], node[2], node[3] );
+ else e = mesh->AddFace (node[0], node[1], node[2], node[3] );
}
else if (nbnode == 6) {
if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
- node[4], node[5], ID);
- else e = mesh->AddFace (node[0], node[1], node[2], node[3],
- node[4], node[5] );
+ node[4], node[5], ID);
+ else e = mesh->AddFace (node[0], node[1], node[2], node[3],
+ node[4], node[5] );
}
else if (nbnode == 8) {
if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
- node[4], node[5], node[6], node[7], ID);
- else e = mesh->AddFace (node[0], node[1], node[2], node[3],
- node[4], node[5], node[6], node[7] );
+ node[4], node[5], node[6], node[7], ID);
+ else e = mesh->AddFace (node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7] );
}
} else {
if ( ID >= 0 ) e = mesh->AddPolygonalFaceWithID(node, ID);
- else e = mesh->AddPolygonalFace (node );
+ else e = mesh->AddPolygonalFace (node );
}
break;
+
case SMDSAbs_Volume:
if ( !isPoly ) {
if (nbnode == 4) {
if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], ID);
- else e = mesh->AddVolume (node[0], node[1], node[2], node[3] );
+ else e = mesh->AddVolume (node[0], node[1], node[2], node[3] );
}
else if (nbnode == 5) {
if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
- node[4], ID);
- else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
- node[4] );
+ node[4], ID);
+ else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
+ node[4] );
}
else if (nbnode == 6) {
if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
- node[4], node[5], ID);
- else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
- node[4], node[5] );
+ node[4], node[5], ID);
+ else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
+ node[4], node[5] );
}
else if (nbnode == 8) {
if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
- node[4], node[5], node[6], node[7], ID);
- else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
- node[4], node[5], node[6], node[7] );
+ node[4], node[5], node[6], node[7], ID);
+ else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7] );
}
else if (nbnode == 10) {
if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
- node[4], node[5], node[6], node[7],
- node[8], node[9], ID);
- else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
- node[4], node[5], node[6], node[7],
- node[8], node[9] );
+ node[4], node[5], node[6], node[7],
+ node[8], node[9], ID);
+ else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7],
+ node[8], node[9] );
}
else if (nbnode == 13) {
if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
- node[4], node[5], node[6], node[7],
- node[8], node[9], node[10],node[11],
- node[12],ID);
- else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
- node[4], node[5], node[6], node[7],
- node[8], node[9], node[10],node[11],
- node[12] );
+ node[4], node[5], node[6], node[7],
+ node[8], node[9], node[10],node[11],
+ node[12],ID);
+ else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7],
+ node[8], node[9], node[10],node[11],
+ node[12] );
}
else if (nbnode == 15) {
if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
- node[4], node[5], node[6], node[7],
- node[8], node[9], node[10],node[11],
- node[12],node[13],node[14],ID);
- else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
- node[4], node[5], node[6], node[7],
- node[8], node[9], node[10],node[11],
- node[12],node[13],node[14] );
+ node[4], node[5], node[6], node[7],
+ node[8], node[9], node[10],node[11],
+ node[12],node[13],node[14],ID);
+ else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7],
+ node[8], node[9], node[10],node[11],
+ node[12],node[13],node[14] );
}
else if (nbnode == 20) {
if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
- node[4], node[5], node[6], node[7],
- node[8], node[9], node[10],node[11],
- node[12],node[13],node[14],node[15],
- node[16],node[17],node[18],node[19],ID);
- else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
- node[4], node[5], node[6], node[7],
- node[8], node[9], node[10],node[11],
- node[12],node[13],node[14],node[15],
- node[16],node[17],node[18],node[19] );
+ node[4], node[5], node[6], node[7],
+ node[8], node[9], node[10],node[11],
+ node[12],node[13],node[14],node[15],
+ node[16],node[17],node[18],node[19],ID);
+ else e = mesh->AddVolume (node[0], node[1], node[2], node[3],
+ node[4], node[5], node[6], node[7],
+ node[8], node[9], node[10],node[11],
+ node[12],node[13],node[14],node[15],
+ node[16],node[17],node[18],node[19] );
}
}
+ break;
+
+ case SMDSAbs_Edge:
+ if ( nbnode == 2 ) {
+ if ( ID >= 0 ) e = mesh->AddEdgeWithID(node[0], node[1], ID);
+ else e = mesh->AddEdge (node[0], node[1] );
+ }
+ else if ( nbnode == 3 ) {
+ if ( ID >= 0 ) e = mesh->AddEdgeWithID(node[0], node[1], node[2], ID);
+ else e = mesh->AddEdge (node[0], node[1], node[2] );
+ }
+ break;
+
+ case SMDSAbs_0DElement:
+ if ( nbnode == 1 ) {
+ if ( ID >= 0 ) e = mesh->Add0DElementWithID(node[0], ID);
+ else e = mesh->Add0DElement (node[0] );
+ }
+ break;
+
+ case SMDSAbs_Node:
+ if ( ID >= 0 ) e = mesh->AddNodeWithID(node[0]->X(), node[0]->Y(), node[0]->Z(), ID);
+ else e = mesh->AddNode (node[0]->X(), node[0]->Y(), node[0]->Z());
+ break;
+
+ default:;
}
if ( e ) myLastCreatedElems.Append( e );
return e;
diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx
index a02800b05..f90f792da 100644
--- a/src/SMESH/SMESH_subMesh.cxx
+++ b/src/SMESH/SMESH_subMesh.cxx
@@ -1700,7 +1700,7 @@ bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& t
// Check my state
if ( !_computeError || _computeError->IsOK() )
{
- _computeState = COMPUTE_OK;
+ _computeState = IsMeshComputed() ? COMPUTE_OK : FAILED_TO_COMPUTE;
}
else
{
diff --git a/src/SMESH/SMESH_subMesh.hxx b/src/SMESH/SMESH_subMesh.hxx
index 58318b1e1..54ffcdac0 100644
--- a/src/SMESH/SMESH_subMesh.hxx
+++ b/src/SMESH/SMESH_subMesh.hxx
@@ -193,6 +193,7 @@ public:
void DumpAlgoState(bool isMain);
bool ComputeStateEngine(int event);
+ void ComputeSubMeshStateEngine(int event);
bool Evaluate(MapShapeNbElems& aResMap);
@@ -250,7 +251,6 @@ protected:
void RemoveSubMeshElementsAndNodes();
void UpdateDependantsState(const compute_event theEvent);
void UpdateSubMeshState(const compute_state theState);
- void ComputeSubMeshStateEngine(int event);
void CleanDependants();
void CleanDependsOn();
void SetAlgoState(int state);
diff --git a/src/SMESHFiltersSelection/SMESH_Type.h b/src/SMESHFiltersSelection/SMESH_Type.h
index 89857d89c..ee962f22e 100644
--- a/src/SMESHFiltersSelection/SMESH_Type.h
+++ b/src/SMESHFiltersSelection/SMESH_Type.h
@@ -25,7 +25,6 @@
// Author : Nicolas REJNERI
// Project : SALOME
// Module : SMESH
-// $Header$
//
#ifndef SMESH_TYPE_HEADER
#define SMESH_TYPE_HEADER
@@ -57,7 +56,8 @@ enum MeshObjectType {
GROUP_FACE,
GROUP_VOLUME,
GROUP_0D,
- COMPONENT
+ COMPONENT,
+ IDSOURCE
};
#endif
diff --git a/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx b/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx
index 1fbb37516..a684d7023 100644
--- a/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx
+++ b/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx
@@ -203,6 +203,12 @@ bool SMESH_TypeFilter::isOk (const SUIT_DataOwner* theDataOwner) const
Ok = true;
break;
}
+ case IDSOURCE:
+ {
+ Ok = ( SMESH_TypeFilter(MESHorSUBMESH).isOk( theDataOwner ) ||
+ SMESH_TypeFilter(GROUP) .isOk( theDataOwner ));
+ break;
+ }
}
}
return Ok;
diff --git a/src/SMESHGUI/Makefile.am b/src/SMESHGUI/Makefile.am
index 7e7448f59..6da5d4076 100644
--- a/src/SMESHGUI/Makefile.am
+++ b/src/SMESHGUI/Makefile.am
@@ -94,6 +94,7 @@ salomeinclude_HEADERS = \
SMESHGUI_MeshOrderDlg.h \
SMESHGUI_MeshOrderOp.h \
SMESHGUI_FileValidator.h \
+ SMESHGUI_CopyMeshDlg.h \
SMESH_SMESHGUI.hxx
# Libraries targets
@@ -167,6 +168,7 @@ dist_libSMESH_la_SOURCES = \
SMESHGUI_FindElemByPointDlg.cxx \
SMESHGUI_MeshOrderDlg.cxx \
SMESHGUI_MeshOrderOp.cxx \
+ SMESHGUI_CopyMeshDlg.cxx \
SMESHGUI_FileValidator.cxx
MOC_FILES = \
@@ -224,6 +226,7 @@ MOC_FILES = \
SMESHGUI_Make2DFrom3DOp_moc.cxx \
SMESHGUI_FindElemByPointDlg_moc.cxx \
SMESHGUI_MeshOrderDlg_moc.cxx \
+ SMESHGUI_CopyMeshDlg_moc.cxx \
SMESHGUI_MeshOrderOp_moc.cxx
nodist_libSMESH_la_SOURCES= \
diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx
index efc9c9ea1..8d50908bd 100644
--- a/src/SMESHGUI/SMESHGUI.cxx
+++ b/src/SMESHGUI/SMESHGUI.cxx
@@ -76,6 +76,7 @@
#include "SMESHGUI_TransparencyDlg.h"
//#include "SMESHGUI_WhatIsDlg.h"
#include "SMESHGUI_DuplicateNodesDlg.h"
+#include "SMESHGUI_CopyMeshDlg.h"
#include "SMESHGUI_Utils.h"
#include "SMESHGUI_MeshUtils.h"
@@ -141,6 +142,7 @@
#include
#include
#include
+#include
// SALOME KERNEL includes
#include
@@ -759,6 +761,14 @@
type = QObject::tr( "FREE_BORDERS" );
else if ( dynamic_cast< SMESH::Controls::FreeFaces* >( f.get() ) )
type = QObject::tr( "FREE_FACES" );
+ else if ( dynamic_cast< SMESH::Controls::BareBorderVolume* >( f.get() ) )
+ type = QObject::tr( "BARE_BORDER_VOLUME" );
+ else if ( dynamic_cast< SMESH::Controls::BareBorderFace* >( f.get() ) )
+ type = QObject::tr( "BARE_BORDER_FACE" );
+ else if ( dynamic_cast< SMESH::Controls::OverConstrainedVolume* >( f.get() ) )
+ type = QObject::tr( "OVER_CONSTRAINED_VOLUME" );
+ else if ( dynamic_cast< SMESH::Controls::OverConstrainedFace* >( f.get() ) )
+ type = QObject::tr( "OVER_CONSTRAINED_FACE" );
return type;
}
@@ -779,10 +789,26 @@
if ( aScalarBarActor && aFunctor ) {
SMESH::Controls::NumericalFunctor* aNumFun = dynamic_cast( aFunctor.get() );
if ( aNumFun ) {
- int nbRanges = aScalarBarActor->GetMaximumNumberOfColors();
+ std::vector elements;
+ SMESH::SMESH_Mesh_var mesh = SMESH::IObjectToInterface(anIO);
+ if ( mesh->_is_nil() ) {
+ SMESH::SMESH_IDSource_var idSource =
+ SMESH::IObjectToInterface(anIO);
+ if ( !idSource->_is_nil() )
+ {
+ SMESH::long_array_var ids = idSource->GetIDs();
+ elements.resize( ids->length() );
+ for ( unsigned i = 0; i < elements.size(); ++i )
+ elements[i] = ids[i];
+ }
+ }
+ int nbIntervals = aScalarBarActor->GetMaximumNumberOfColors();
+ vtkLookupTable* lookupTable =
+ static_cast(aScalarBarActor->GetLookupTable());
+ double * minmax = lookupTable->GetRange();
std::vector nbEvents;
std::vector funValues;
- aNumFun->GetHistogram( nbRanges, nbEvents, funValues );
+ aNumFun->GetHistogram( nbIntervals, nbEvents, funValues, elements, minmax );
QString anInitialPath = "";
if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() )
anInitialPath = QDir::currentPath();
@@ -826,11 +852,11 @@
if ( selected.Extent() == 1 ) {
Handle(SALOME_InteractiveObject) anIO = selected.First();
if ( anIO->hasEntry() ) {
- SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() );
- if ( anActor && anActor->GetScalarBarActor() && anActor->GetControlMode() != SMESH_Actor::eNone ) {
- SMESH_ScalarBarActor *aScalarBarActor = anActor->GetScalarBarActor();
- aScalarBarActor->SetDistributionVisibility(!aScalarBarActor->GetDistributionVisibility());
- }
+ SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() );
+ if ( anActor && anActor->GetScalarBarActor() && anActor->GetControlMode() != SMESH_Actor::eNone ) {
+ SMESH_ScalarBarActor *aScalarBarActor = anActor->GetScalarBarActor();
+ aScalarBarActor->SetDistributionVisibility(!aScalarBarActor->GetDistributionVisibility());
+ }
}
}
}
@@ -1178,6 +1204,18 @@
case 6023:
aControl = SMESH_Actor::eMaxElementLength3D;
break;
+ case 6024:
+ aControl = SMESH_Actor::eBareBorderVolume;
+ break;
+ case 6025:
+ aControl = SMESH_Actor::eBareBorderFace;
+ break;
+ case 6026:
+ aControl = SMESH_Actor::eOverConstrainedVolume;
+ break;
+ case 6027:
+ aControl = SMESH_Actor::eOverConstrainedFace;
+ break;
}
anActor->SetControlMode(aControl);
anActor->GetScalarBarActor()->SetTitle( functorToString( anActor->GetFunctor() ).toLatin1().constData() );
@@ -2024,6 +2062,13 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
case 704: // Edit mesh/sub-mesh
startOperation( theCommandID );
break;
+ case 705: // copy mesh
+ {
+ if (checkLock(aStudy)) break;
+ EmitSignalDeactivateDialog();
+ ( new SMESHGUI_CopyMeshDlg( this ) )->show();
+ }
+ break;
case 710: // Build compound mesh
{
if (checkLock(aStudy)) break;
@@ -2973,6 +3018,10 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
case 6021:
case 6022:
case 6023:
+ case 6024:
+ case 6025:
+ case 6026:
+ case 6027:
if ( vtkwnd ) {
LightApp_SelectionMgr* mgr = selectionMgr();
@@ -3189,6 +3238,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createSMESHAction( 702, "CREATE_MESH", "ICON_DLG_INIT_MESH" );
createSMESHAction( 703, "CREATE_SUBMESH", "ICON_DLG_ADD_SUBMESH" );
createSMESHAction( 704, "EDIT_MESHSUBMESH","ICON_DLG_EDIT_MESH" );
+ createSMESHAction( 705, "COPY_MESH", "ICON_COPY_MESH" );
createSMESHAction( 710, "BUILD_COMPOUND", "ICON_BUILD_COMPOUND" );
createSMESHAction( 711, "PRECOMPUTE", "ICON_PRECOMPUTE" );
createSMESHAction( 712, "EVALUATE", "ICON_COMPUTE" );
@@ -3214,6 +3264,10 @@ void SMESHGUI::initialize( CAM_Application* app )
createSMESHAction( 6021, "FREE_FACES", "ICON_FREE_FACES", 0, true );
createSMESHAction( 6022, "MAX_ELEMENT_LENGTH_2D", "ICON_MAX_ELEMENT_LENGTH_2D", 0, true );
createSMESHAction( 6023, "MAX_ELEMENT_LENGTH_3D", "ICON_MAX_ELEMENT_LENGTH_3D", 0, true );
+ createSMESHAction( 6024, "BARE_BORDER_VOLUME","ICON_BARE_BORDER_VOLUME", 0, true );
+ createSMESHAction( 6025, "BARE_BORDER_FACE","ICON_BARE_BORDER_FACE", 0, true );
+ createSMESHAction( 6026, "OVER_CONSTRAINED_VOLUME","ICON_OVER_CONSTRAINED_VOLUME", 0, true );
+ createSMESHAction( 6027, "OVER_CONSTRAINED_FACE","ICON_OVER_CONSTRAINED_FACE", 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 );
@@ -3353,6 +3407,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createMenu( 703, meshId, -1 );
createMenu( 704, meshId, -1 );
createMenu( 710, meshId, -1 );
+ createMenu( 705, meshId, -1 );
createMenu( separator(), meshId, -1 );
createMenu( 701, meshId, -1 );
createMenu( 711, meshId, -1 );
@@ -3371,8 +3426,6 @@ void SMESHGUI::initialize( CAM_Application* app )
createMenu( separator(), meshId, -1 );
createMenu( 814, meshId, -1 );
createMenu( separator(), meshId, -1 );
- createMenu( 813, meshId, -1 );
- createMenu( separator(), meshId, -1 );
createMenu( 900, meshId, -1 );
//createMenu( 902, meshId, -1 );
createMenu( 903, meshId, -1 );
@@ -3385,6 +3438,8 @@ void SMESHGUI::initialize( CAM_Application* app )
createMenu( 6001, edgeId, -1 );
createMenu( 6004, edgeId, -1 );
createMenu( 6021, faceId, -1 );
+ createMenu( 6025, faceId, -1 );
+ createMenu( 6027, faceId, -1 );
createMenu( 6018, faceId, -1 );
createMenu( 6019, faceId, -1 );
createMenu( 6011, faceId, -1 );
@@ -3397,6 +3452,8 @@ void SMESHGUI::initialize( CAM_Application* app )
createMenu( 6017, volumeId, -1 );
createMenu( 6009, volumeId, -1 );
createMenu( 6023, volumeId, -1 );
+ createMenu( 6024, volumeId, -1 );
+ createMenu( 6026, volumeId, -1 );
createMenu( 4000, addId, -1 );
createMenu( 4009, addId, -1 );
@@ -3420,6 +3477,8 @@ void SMESHGUI::initialize( CAM_Application* app )
createMenu( 4042, removeId, -1 );
createMenu( 4044, removeId, -1 );
createMenu( separator(), removeId, -1 );
+ createMenu( 813, removeId, -1 );
+ createMenu( separator(), removeId, -1 );
createMenu( 4043, removeId, -1 );
createMenu( 4051, renumId, -1 );
@@ -3464,6 +3523,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createTool( 703, meshTb );
createTool( 704, meshTb );
createTool( 710, meshTb );
+ createTool( 705, meshTb );
createTool( separator(), meshTb );
createTool( 701, meshTb );
createTool( 711, meshTb );
@@ -3490,6 +3550,8 @@ void SMESHGUI::initialize( CAM_Application* app )
createTool( 6004, ctrlTb );
createTool( separator(), ctrlTb );
createTool( 6021, ctrlTb );
+ createTool( 6025, ctrlTb );
+ createTool( 6027, ctrlTb );
createTool( 6018, ctrlTb );
createTool( 6019, ctrlTb );
createTool( 6011, ctrlTb );
@@ -3503,6 +3565,8 @@ void SMESHGUI::initialize( CAM_Application* app )
createTool( 6017, ctrlTb );
createTool( 6009, ctrlTb );
createTool( 6023, ctrlTb );
+ createTool( 6024, ctrlTb );
+ createTool( 6026, ctrlTb );
createTool( separator(), ctrlTb );
createTool( 4000, addRemTb );
@@ -3805,50 +3869,58 @@ void SMESHGUI::initialize( CAM_Application* app )
aSubId = popupMgr()->insert( tr( "MEN_FACE_CTRL" ), anId, -1 ); // FACE CONTROLS
- popupMgr()->insert( action( 6021 ), aSubId, -1 ); // FREE_FACE
+ popupMgr()->insert ( action( 6021 ), aSubId, -1 ); // FREE_FACE
popupMgr()->setRule( action( 6021 ), aMeshInVtkHasFaces /*aMeshInVtkHasVolumes*/,
QtxPopupMgr::VisibleRule );
popupMgr()->setRule( action( 6021 ), "controlMode = 'eFreeFaces'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 6018 ), aSubId, -1 ); // LENGTH_2D
+ popupMgr()->insert ( action( 6018 ), aSubId, -1 ); // LENGTH_2D
popupMgr()->setRule( action( 6018 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
popupMgr()->setRule( action( 6018 ), "controlMode = 'eLength2D'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 6019 ), aSubId, -1 ); // CONNECTION_2D
+ popupMgr()->insert ( action( 6019 ), aSubId, -1 ); // CONNECTION_2D
popupMgr()->setRule( action( 6019 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
popupMgr()->setRule( action( 6019 ), "controlMode = 'eMultiConnection2D'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 6011 ), aSubId, -1 ); // AREA
+ popupMgr()->insert ( action( 6011 ), aSubId, -1 ); // AREA
popupMgr()->setRule( action( 6011 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
popupMgr()->setRule( action( 6011 ), "controlMode = 'eArea'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 6012 ), aSubId, -1 ); // TAPER
+ popupMgr()->insert ( action( 6012 ), aSubId, -1 ); // TAPER
popupMgr()->setRule( action( 6012 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
popupMgr()->setRule( action( 6012 ), "controlMode = 'eTaper'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 6013 ), aSubId, -1 ); // ASPECT
+ popupMgr()->insert ( action( 6013 ), aSubId, -1 ); // ASPECT
popupMgr()->setRule( action( 6013 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
popupMgr()->setRule( action( 6013 ), "controlMode = 'eAspectRatio'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 6014 ), aSubId, -1 ); // MIN_ANG
+ popupMgr()->insert ( action( 6014 ), aSubId, -1 ); // MIN_ANG
popupMgr()->setRule( action( 6014 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
popupMgr()->setRule( action( 6014 ), "controlMode = 'eMinimumAngle'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 6015 ), aSubId, -1 ); // WARP
+ popupMgr()->insert ( action( 6015 ), aSubId, -1 ); // WARP
popupMgr()->setRule( action( 6015 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
popupMgr()->setRule( action( 6015 ), "controlMode = 'eWarping'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 6016 ), aSubId, -1 ); // SKEW
+ popupMgr()->insert ( action( 6016 ), aSubId, -1 ); // SKEW
popupMgr()->setRule( action( 6016 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
popupMgr()->setRule( action( 6016 ), "controlMode = 'eSkew'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 6022 ), aSubId, -1 ); // MAX_ELEMENT_LENGTH_2D
+ popupMgr()->insert ( action( 6022 ), aSubId, -1 ); // MAX_ELEMENT_LENGTH_2D
popupMgr()->setRule( action( 6022 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
popupMgr()->setRule( action( 6022 ), "controlMode = 'eMaxElementLength2D'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( 6025 ), aSubId, -1 ); // BARE_BORDER_FACE
+ popupMgr()->setRule( action( 6025 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( 6025 ), "controlMode = 'eBareBorderFace'", QtxPopupMgr::ToggleRule );
+
+ popupMgr()->insert ( action( 6027 ), aSubId, -1 ); // OVER_CONSTRAINED_FACE
+ popupMgr()->setRule( action( 6027 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( 6027 ), "controlMode = 'eOverConstrainedFace'", QtxPopupMgr::ToggleRule );
+
aSubId = popupMgr()->insert( tr( "MEN_VOLUME_CTRL" ), anId, -1 ); // VOLUME CONTROLS
- popupMgr()->insert( action( 6017 ), aSubId, -1 ); // ASPECT_3D
+ popupMgr()->insert ( action( 6017 ), aSubId, -1 ); // ASPECT_3D
popupMgr()->setRule( action( 6017 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
popupMgr()->setRule( action( 6017 ), "controlMode = 'eAspectRatio3D'", QtxPopupMgr::ToggleRule );
@@ -3856,10 +3928,18 @@ void SMESHGUI::initialize( CAM_Application* app )
popupMgr()->setRule( action( 6009 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
popupMgr()->setRule( action( 6009 ), "controlMode = 'eVolume3D'", QtxPopupMgr::ToggleRule );
- popupMgr()->insert( action( 6023 ), aSubId, -1 ); // MAX_ELEMENT_LENGTH_3D
+ popupMgr()->insert ( action( 6023 ), aSubId, -1 ); // MAX_ELEMENT_LENGTH_3D
popupMgr()->setRule( action( 6023 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
popupMgr()->setRule( action( 6023 ), "controlMode = 'eMaxElementLength3D'", QtxPopupMgr::ToggleRule );
+ popupMgr()->insert ( action( 6024 ), aSubId, -1 ); // BARE_BORDER_VOLUME
+ popupMgr()->setRule( action( 6024 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( 6024 ), "controlMode = 'eBareBorderVolume'", QtxPopupMgr::ToggleRule );
+
+ popupMgr()->insert ( action( 6026 ), aSubId, -1 ); // OVER_CONSTRAINED_VOLUME
+ popupMgr()->setRule( action( 6026 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+ popupMgr()->setRule( action( 6026 ), "controlMode = 'eOverConstrainedVolume'", QtxPopupMgr::ToggleRule );
+
popupMgr()->insert( separator(), anId, -1 );
popupMgr()->insert( action( 201 ), anId, -1 ); // SCALAR_BAR_PROP
diff --git a/src/SMESHGUI/SMESHGUI_CopyMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_CopyMeshDlg.cxx
new file mode 100644
index 000000000..f4b6950bf
--- /dev/null
+++ b/src/SMESHGUI/SMESHGUI_CopyMeshDlg.cxx
@@ -0,0 +1,667 @@
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 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
+//
+// SMESH SMESHGUI : GUI for SMESH component
+// File : SMESHGUI_CopyMeshDlg.cxx
+
+#include "SMESHGUI_CopyMeshDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_FilterDlg.h"
+
+#include
+#include
+#include
+
+// SALOME GUI includes
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+
+// SALOME KERNEL includes
+#include
+
+// OCCT includes
+#include
+
+// Qt includes
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// IDL includes
+#include
+#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
+/*!
+ \class BusyLocker
+ \brief Simple 'busy state' flag locker.
+ \internal
+*/
+
+namespace
+{
+ class BusyLocker
+ {
+ public:
+ //! Constructor. Sets passed boolean flag to \c true.
+ BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; }
+ //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false.
+ ~BusyLocker() { myBusy = false; }
+ private:
+ bool& myBusy; //! External 'busy state' boolean flag
+ };
+}
+
+#define SPACING 6
+#define MARGIN 11
+
+//To disable automatic genericobj management, the following line should be commented.
+//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
+#define WITHGENERICOBJ
+
+
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+SMESHGUI_CopyMeshDlg::SMESHGUI_CopyMeshDlg( SMESHGUI* theModule )
+ : QDialog( SMESH::GetDesktop( theModule ) ),
+ mySMESHGUI( theModule ),
+ mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+ myFilterDlg(0),
+ mySelectedObject(SMESH::SMESH_IDSource::_nil())
+{
+ QPixmap image (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_COPY_MESH")));
+
+ setModal(false);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+ setWindowTitle(tr("SMESH_COPY_MESH_TITLE"));
+ setSizeGripEnabled(true);
+
+ QVBoxLayout* SMESHGUI_CopyMeshDlgLayout = new QVBoxLayout(this);
+ SMESHGUI_CopyMeshDlgLayout->setSpacing(SPACING);
+ SMESHGUI_CopyMeshDlgLayout->setMargin(MARGIN);
+
+ /***************************************************************/
+ ConstructorsBox = new QGroupBox(tr("SMESH_COPY_MESH_TITLE"), this);
+ QButtonGroup* GroupConstructors = new QButtonGroup(this);
+ QHBoxLayout* ConstructorsBoxLayout = new QHBoxLayout(ConstructorsBox);
+ ConstructorsBoxLayout->setSpacing(SPACING);
+ ConstructorsBoxLayout->setMargin(MARGIN);
+
+ QRadioButton* RadioButton1= new QRadioButton(ConstructorsBox);
+ RadioButton1->setIcon(image);
+ GroupConstructors->addButton(RadioButton1, 0);
+
+ ConstructorsBoxLayout->addWidget(RadioButton1);
+ RadioButton1->setChecked(true);
+ GroupConstructors->addButton(RadioButton1, 0);
+
+ /***************************************************************/
+ GroupArguments = new QGroupBox(tr("SMESH_ARGUMENTS"), this);
+ QGridLayout* GroupArgumentsLayout = new QGridLayout(GroupArguments);
+ GroupArgumentsLayout->setSpacing(SPACING);
+ GroupArgumentsLayout->setMargin(MARGIN);
+
+ myIdValidator = new SMESHGUI_IdValidator(this);
+
+ // Controls for idSource/elements selection
+ myTextLabelElements = new QLabel(tr("OBJECT_NAME"), GroupArguments);
+ myLineEditElements = new QLineEdit(GroupArguments);
+ myLineEditElements->setValidator(myIdValidator);
+ myLineEditElements->setMaxLength(-1);
+ myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+ connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters()));
+
+ // Control for the mesh objects selection
+ myIdSourceCheck = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
+
+ // Name of a mesh to create
+ QLabel* meshNameLabel = new QLabel(tr("NEW_NAME"), GroupArguments);
+ myMeshNameEdit = new QLineEdit(GroupArguments);
+
+ // CheckBox for copying groups
+ myCopyGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments);
+ myCopyGroupsCheck->setChecked(false);
+
+ // CheckBox for keeping ids
+ myKeepIdsCheck = new QCheckBox(tr("SMESH_KEEP_IDS"), GroupArguments);
+ myKeepIdsCheck->setChecked(true);
+
+ // layout
+ GroupArgumentsLayout->addWidget(myTextLabelElements, 0, 0);
+ GroupArgumentsLayout->addWidget(myLineEditElements, 0, 1, 1, 5);
+ GroupArgumentsLayout->addWidget(myFilterBtn, 0, 6);
+ GroupArgumentsLayout->addWidget(myIdSourceCheck, 1, 0, 1, 6);
+ GroupArgumentsLayout->addWidget(meshNameLabel, 2, 0);
+ GroupArgumentsLayout->addWidget(myMeshNameEdit, 2, 1, 1, 5);
+ GroupArgumentsLayout->addWidget(myCopyGroupsCheck, 3, 0, 1, 6);
+ GroupArgumentsLayout->addWidget(myKeepIdsCheck, 4, 0, 1, 6);
+
+ /***************************************************************/
+ GroupButtons = new QGroupBox(this);
+ QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
+ GroupButtonsLayout->setSpacing(SPACING);
+ GroupButtonsLayout->setMargin(MARGIN);
+
+ buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
+ buttonOk->setAutoDefault(true);
+ buttonOk->setDefault(true);
+ buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
+ buttonApply->setAutoDefault(true);
+ buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
+ buttonCancel->setAutoDefault(true);
+ buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
+ buttonHelp->setAutoDefault(true);
+
+ GroupButtonsLayout->addWidget(buttonOk);
+ GroupButtonsLayout->addSpacing(10);
+ GroupButtonsLayout->addWidget(buttonApply);
+ GroupButtonsLayout->addSpacing(10);
+ GroupButtonsLayout->addStretch();
+ GroupButtonsLayout->addWidget(buttonCancel);
+ GroupButtonsLayout->addWidget(buttonHelp);
+
+ /***************************************************************/
+ SMESHGUI_CopyMeshDlgLayout->addWidget(ConstructorsBox);
+ SMESHGUI_CopyMeshDlgLayout->addWidget(GroupArguments);
+ SMESHGUI_CopyMeshDlgLayout->addWidget(GroupButtons);
+
+ /* Initialisations */
+ mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
+
+ mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+
+ // Selection filter
+ myIdSourceFilter = new SMESH_TypeFilter( IDSOURCE );
+
+ myHelpFileName = "copy_mesh_page.html";
+
+ Init();
+
+ /* signals and slots connections */
+ connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()));
+ connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
+ connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
+ connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
+
+ connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()),
+ this, SLOT (DeactivateActiveDialog()));
+ connect(mySelectionMgr, SIGNAL (currentSelectionChanged()),
+ this, SLOT (SelectionIntoArgument()));
+ connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()),/* to close dialog if study change */
+ this, SLOT (ClickOnCancel()));
+
+ connect(myLineEditElements, SIGNAL(textChanged(const QString&)),
+ this, SLOT (onTextChange(const QString&)));
+ connect(myIdSourceCheck, SIGNAL(toggled(bool)),
+ this, SLOT (onSelectIdSource(bool)));
+
+ SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : ~SMESHGUI_CopyMeshDlg()
+// purpose : Destroys the object and frees any allocated resources
+//=================================================================================
+
+SMESHGUI_CopyMeshDlg::~SMESHGUI_CopyMeshDlg()
+{
+ if ( myFilterDlg )
+ {
+ myFilterDlg->setParent( 0 );
+ delete myFilterDlg; myFilterDlg = 0;
+ }
+ if ( myIdSourceFilter )
+ {
+ if ( mySelectionMgr )
+ mySelectionMgr->removeFilter( myIdSourceFilter );
+ delete myIdSourceFilter; myIdSourceFilter=0;
+ }
+}
+
+//=================================================================================
+// function : Init()
+// purpose :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::Init (bool ResetControls)
+{
+ myBusy = false;
+
+ myMeshNameEdit->setText( SMESH::UniqueMeshName("Mesh"));
+ if ( ResetControls )
+ {
+ myLineEditElements->clear();
+ //myElementsId = "";
+ myNbOkElements = 0;
+
+ buttonOk->setEnabled(false);
+ buttonApply->setEnabled(false);
+
+ myActor = 0;
+ myMesh = SMESH::SMESH_Mesh::_nil();
+
+ myIdSourceCheck->setChecked(true);
+ myCopyGroupsCheck->setChecked(false);
+ myKeepIdsCheck->setChecked(false);
+
+ onSelectIdSource( myIdSourceCheck->isChecked() );
+ }
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose :
+//=================================================================================
+
+bool SMESHGUI_CopyMeshDlg::ClickOnApply()
+{
+ if (mySMESHGUI->isActiveStudyLocked())
+ return false;
+
+ if( !isValid() )
+ return false;
+
+ try
+ {
+ SUIT_OverrideCursor aWaitCursor;
+ SMESH::SMESH_IDSource_var aPartToCopy;
+ if ( myIdSourceCheck->isChecked())
+ {
+ aPartToCopy = mySelectedObject;
+ }
+ else
+ {
+ QStringList aListElementsId = myLineEditElements->text().split(" ", QString::SkipEmptyParts);
+ SMESH::long_array_var anElementsId = new SMESH::long_array;
+ anElementsId->length(aListElementsId.count());
+ for (int i = 0; i < aListElementsId.count(); i++)
+ anElementsId[i] = aListElementsId[i].toInt();
+
+ SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+ aPartToCopy = aMeshEditor->MakeIDSource( anElementsId, SMESH::ALL );
+ }
+ QByteArray meshName = myMeshNameEdit->text().toLatin1();
+ bool toCopyGroups = ( myCopyGroupsCheck->isChecked() );
+ bool toKeepIDs = ( myKeepIdsCheck->isChecked() );
+
+ SMESH::SMESH_Gen_var gen = SMESHGUI::GetSMESHGen();
+ SMESH::SMESH_Mesh_var newMesh =
+ gen->CopyMesh(aPartToCopy, meshName.constData(), toCopyGroups, toKeepIDs);
+#ifdef WITHGENERICOBJ
+ // obj has been published in study. Its refcount has been incremented.
+ // It is safe to decrement its refcount
+ // so that it will be destroyed when the entry in study will be removed
+ newMesh->Destroy();
+#endif
+ } catch (...) {
+ }
+
+ mySMESHGUI->updateObjBrowser(true);
+ SMESHGUI::Modified();
+
+ Init(false);
+ mySelectedObject = SMESH::SMESH_IDSource::_nil();
+ SelectionIntoArgument();
+
+ return true;
+}
+
+//=================================================================================
+// function : ClickOnOk()
+// purpose :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::ClickOnOk()
+{
+ if( ClickOnApply() )
+ ClickOnCancel();
+}
+
+//=================================================================================
+// function : ClickOnCancel()
+// purpose :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::ClickOnCancel()
+{
+ disconnect(mySelectionMgr, 0, this, 0);
+ if ( mySelectionMgr )
+ mySelectionMgr->removeFilter( myIdSourceFilter );
+ if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+ aViewWindow->SetSelectionMode( ActorSelection );
+ mySMESHGUI->ResetState();
+ reject();
+}
+
+//=================================================================================
+// function : ClickOnHelp()
+// purpose :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::ClickOnHelp()
+{
+ LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
+ if (app)
+ app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
+ else {
+ QString platform;
+#ifdef WIN32
+ platform = "winapplication";
+#else
+ platform = "application";
+#endif
+ SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
+ tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+ arg(app->resourceMgr()->stringValue("ExternalBrowser",
+ platform)).
+ arg(myHelpFileName));
+ }
+}
+
+//=======================================================================
+// function : onTextChange()
+// purpose :
+//=======================================================================
+
+void SMESHGUI_CopyMeshDlg::onTextChange (const QString& theNewText)
+{
+ QLineEdit* send = (QLineEdit*)sender();
+
+ if (myBusy) return;
+ BusyLocker lock( myBusy );
+
+ //if (send == myLineEditElements)
+ myNbOkElements = 0;
+
+ buttonOk->setEnabled(false);
+ buttonApply->setEnabled(false);
+
+ // hilight entered elements
+ SMDS_Mesh* aMesh = 0;
+ if (myActor)
+ aMesh = myActor->GetObject()->GetMesh();
+
+ QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
+ if (myActor && aMesh)
+ {
+ TColStd_MapOfInteger newIndices;
+ if (send == myLineEditElements) {
+ for (int i = 0; i < aListId.count(); i++)
+ if ( const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()))
+ {
+ newIndices.Add(e->GetID());
+ }
+ }
+ myNbOkElements = newIndices.Extent();
+
+ Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
+ mySelector->AddOrRemoveIndex( anIO, newIndices, false );
+ if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+ aViewWindow->highlight( anIO, true, true );
+ }
+ else
+ {
+ myNbOkElements = aListId.count();
+ }
+
+ if (myNbOkElements) {
+ buttonOk->setEnabled(true);
+ buttonApply->setEnabled(true);
+ }
+}
+
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose : Called when selection as changed or other case
+//=================================================================================
+
+void SMESHGUI_CopyMeshDlg::SelectionIntoArgument()
+{
+ if (myBusy) return;
+ BusyLocker lock( myBusy );
+
+ // clear
+ myActor = 0;
+ QString aString = "";
+
+ myLineEditElements->setText(aString);
+ myNbOkElements = 0;
+ buttonOk->setEnabled(false);
+ buttonApply->setEnabled(false);
+ myFilterBtn->setEnabled(false);
+
+ // get selected mesh
+ SALOME_ListIO aList;
+ mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
+ int nbSel = aList.Extent();
+ if (nbSel != 1)
+ return;
+
+ Handle(SALOME_InteractiveObject) IO = aList.First();
+ mySelectedObject = SMESH::IObjectToInterface( IO );
+ if ( mySelectedObject->_is_nil() )
+ return;
+
+ myMesh = SMESH::GetMeshByIO(IO);
+ if (myMesh->_is_nil())
+ return;
+
+ myActor = SMESH::FindActorByEntry(IO->getEntry());
+ if (!myActor)
+ myActor = SMESH::FindActorByObject(myMesh);
+
+ if (myIdSourceCheck->isChecked())
+ {
+ SMESH::GetNameOfSelectedIObjects( mySelectionMgr, aString );
+ if ( aString.isEmpty() ) aString = " ";
+ }
+ else
+ {
+ SMESH::GetNameOfSelectedElements( mySelector, IO, aString );
+ myNbOkElements = aString.size();
+ myFilterBtn->setEnabled(true);
+ }
+ myLineEditElements->setText( aString );
+ bool ok = !aString.isEmpty();
+
+ buttonOk->setEnabled(ok);
+ buttonApply->setEnabled(ok);
+}
+
+//=======================================================================
+//function : onSelectIdSource
+//purpose :
+//=======================================================================
+void SMESHGUI_CopyMeshDlg::onSelectIdSource (bool toSelectMesh)
+{
+ if (toSelectMesh)
+ myTextLabelElements->setText(tr("OBJECT_NAME"));
+ else
+ myTextLabelElements->setText(tr("ELEM_IDS"));
+
+ if (toSelectMesh) {
+ myLineEditElements->clear();
+ }
+
+ mySelectionMgr->clearFilters();
+ mySelectionMgr->installFilter(myIdSourceFilter);
+ SMESH::SetPointRepresentation(false);
+
+ if (toSelectMesh) {
+ if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+ aViewWindow->SetSelectionMode( ActorSelection );
+ myLineEditElements->setReadOnly(true);
+ myLineEditElements->setValidator(0);
+ }
+ else
+ {
+ if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+ aViewWindow->SetSelectionMode( CellSelection );
+ myLineEditElements->setReadOnly(false);
+ myLineEditElements->setValidator(myIdValidator);
+ onTextChange(myLineEditElements->text());
+ }
+
+ SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : isValid
+// purpose :
+//=================================================================================
+
+bool SMESHGUI_CopyMeshDlg::isValid()
+{
+ if ( myIdSourceCheck->isChecked() )
+ return !mySelectedObject->_is_nil();
+
+ return myNbOkElements > 0;
+}
+
+//=================================================================================
+// function : DeactivateActiveDialog()
+// purpose :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::DeactivateActiveDialog()
+{
+ if (ConstructorsBox->isEnabled()) {
+ ConstructorsBox->setEnabled(false);
+ GroupArguments->setEnabled(false);
+ GroupButtons->setEnabled(false);
+ mySMESHGUI->ResetState();
+ mySMESHGUI->SetActiveDialogBox(0);
+ if ( mySelectionMgr )
+ mySelectionMgr->removeFilter( myIdSourceFilter );
+ }
+}
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::ActivateThisDialog()
+{
+ /* Emit a signal to deactivate the active dialog */
+ mySMESHGUI->EmitSignalDeactivateDialog();
+ ConstructorsBox->setEnabled(true);
+ GroupArguments->setEnabled(true);
+ GroupButtons->setEnabled(true);
+
+ mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+
+ onSelectIdSource( myIdSourceCheck->isChecked() );
+
+ SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : enterEvent()
+// purpose :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::enterEvent (QEvent*)
+{
+ if (!ConstructorsBox->isEnabled())
+ ActivateThisDialog();
+}
+
+//=================================================================================
+// function : closeEvent()
+// purpose :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::closeEvent (QCloseEvent*)
+{
+ /* same than click on cancel button */
+ ClickOnCancel();
+}
+
+//=======================================================================
+//function : hideEvent
+//purpose : caused by ESC key
+//=======================================================================
+void SMESHGUI_CopyMeshDlg::hideEvent (QHideEvent*)
+{
+ if (!isMinimized())
+ ClickOnCancel();
+}
+
+//=================================================================================
+// function : keyPressEvent()
+// purpose :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::keyPressEvent( QKeyEvent* e )
+{
+ QDialog::keyPressEvent( e );
+ if ( e->isAccepted() )
+ return;
+
+ if ( e->key() == Qt::Key_F1 ) {
+ e->accept();
+ ClickOnHelp();
+ }
+}
+
+//=================================================================================
+// function : setFilters()
+// purpose : SLOT. Called when "Filter" button pressed.
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::setFilters()
+{
+ if(myMesh->_is_nil()) {
+ SUIT_MessageBox::critical(this,
+ tr("SMESH_ERROR"),
+ tr("NO_MESH_SELECTED"));
+ return;
+ }
+ if ( !myFilterDlg )
+ myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
+
+ myFilterDlg->SetSelection();
+ myFilterDlg->SetMesh( myMesh );
+ myFilterDlg->SetSourceWg( myLineEditElements );
+
+ myFilterDlg->show();
+}
diff --git a/src/SMESHGUI/SMESHGUI_CopyMeshDlg.h b/src/SMESHGUI/SMESHGUI_CopyMeshDlg.h
new file mode 100644
index 000000000..83fcd095b
--- /dev/null
+++ b/src/SMESHGUI/SMESHGUI_CopyMeshDlg.h
@@ -0,0 +1,125 @@
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 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
+//
+
+// SMESH SMESHGUI : GUI for SMESH component
+// File : SMESHGUI_CopyMeshDlg.h
+//
+#ifndef SMESHGUI_CopyMeshDLG_H
+#define SMESHGUI_CopyMeshDLG_H
+
+// SMESH includes
+#include "SMESH_SMESHGUI.hxx"
+
+// Qt includes
+#include
+
+// IDL includes
+#include
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+class QCheckBox;
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+
+class SMESHGUI;
+class SMESHGUI_IdValidator;
+class SMESHGUI_FilterDlg;
+class SMESH_Actor;
+class SVTK_Selector;
+class LightApp_SelectionMgr;
+class SUIT_SelectionFilter;
+
+//=================================================================================
+// class : SMESHGUI_CopyMeshDlg
+// purpose : copy some elements or a mesh object into a new mesh
+//=================================================================================
+
+class SMESHGUI_EXPORT SMESHGUI_CopyMeshDlg : public QDialog
+{
+ Q_OBJECT
+
+public:
+ SMESHGUI_CopyMeshDlg( SMESHGUI* );
+ ~SMESHGUI_CopyMeshDlg();
+
+private:
+ void Init( bool = true );
+ void closeEvent( QCloseEvent* );
+ void enterEvent( QEvent* ); /* mouse enter the QWidget */
+ void hideEvent( QHideEvent* ); /* ESC key */
+ void keyPressEvent( QKeyEvent* );
+ int GetConstructorId();
+ void setNewMeshName();
+
+ bool isValid();
+
+ SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */
+ SMESHGUI_IdValidator* myIdValidator;
+ LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */
+ int myNbOkElements; /* to check when elements are defined */
+
+ SVTK_Selector* mySelector;
+
+ bool myBusy;
+ SMESH::SMESH_Mesh_var myMesh;
+ SMESH_Actor* myActor;
+ SUIT_SelectionFilter* myIdSourceFilter;
+
+ SMESH::SMESH_IDSource_var mySelectedObject;
+
+ QGroupBox* ConstructorsBox;
+ QGroupBox* GroupArguments;
+ QGroupBox* GroupButtons;
+
+ QPushButton* buttonOk;
+ QPushButton* buttonCancel;
+ QPushButton* buttonApply;
+ QPushButton* buttonHelp;
+
+ QLabel* myTextLabelElements;
+ QLineEdit* myLineEditElements;
+ QLineEdit* myMeshNameEdit;
+ QCheckBox* myIdSourceCheck;
+ QCheckBox* myCopyGroupsCheck;
+ QCheckBox* myKeepIdsCheck;
+
+ QPushButton* myFilterBtn;
+ SMESHGUI_FilterDlg* myFilterDlg;
+
+ QString myHelpFileName;
+
+private slots:
+ void ClickOnOk();
+ void ClickOnCancel();
+ bool ClickOnApply();
+ void ClickOnHelp();
+ void SelectionIntoArgument();
+ void DeactivateActiveDialog();
+ void ActivateThisDialog();
+ void onTextChange( const QString& );
+ void onSelectIdSource( bool );
+ void setFilters();
+};
+
+#endif // SMESHGUI_CopyMeshDLG_H
diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx
index ee88f7662..de2d8e05d 100755
--- a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx
+++ b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx
@@ -1169,18 +1169,22 @@ void SMESHGUI_FilterTable::SetCriterion (const int theRow,
aTable->item( theRow, 2 )->setText( QString( theCriterion.ThresholdID ) );
}
else if (theCriterion.Type != SMESH::FT_RangeOfIds &&
- theCriterion.Type != SMESH::FT_BelongToGeom &&
- theCriterion.Type != SMESH::FT_BelongToPlane &&
- theCriterion.Type != SMESH::FT_BelongToCylinder &&
- theCriterion.Type != SMESH::FT_BelongToGenSurface &&
- theCriterion.Type != SMESH::FT_LyingOnGeom &&
- theCriterion.Type != SMESH::FT_CoplanarFaces &&
- theCriterion.Type != SMESH::FT_FreeBorders &&
- theCriterion.Type != SMESH::FT_FreeEdges &&
- theCriterion.Type != SMESH::FT_FreeNodes &&
- theCriterion.Type != SMESH::FT_FreeFaces &&
- theCriterion.Type != SMESH::FT_BadOrientedVolume &&
- theCriterion.Type != SMESH::FT_LinearOrQuadratic)
+ theCriterion.Type != SMESH::FT_BelongToGeom &&
+ theCriterion.Type != SMESH::FT_BelongToPlane &&
+ theCriterion.Type != SMESH::FT_BelongToCylinder &&
+ theCriterion.Type != SMESH::FT_BelongToGenSurface &&
+ theCriterion.Type != SMESH::FT_LyingOnGeom &&
+ theCriterion.Type != SMESH::FT_CoplanarFaces &&
+ theCriterion.Type != SMESH::FT_FreeBorders &&
+ theCriterion.Type != SMESH::FT_FreeEdges &&
+ theCriterion.Type != SMESH::FT_FreeNodes &&
+ theCriterion.Type != SMESH::FT_FreeFaces &&
+ theCriterion.Type != SMESH::FT_BadOrientedVolume &&
+ theCriterion.Type != SMESH::FT_BareBorderFace &&
+ theCriterion.Type != SMESH::FT_BareBorderVolume &&
+ theCriterion.Type != SMESH::FT_OverConstrainedFace &&
+ theCriterion.Type != SMESH::FT_OverConstrainedVolume &&
+ theCriterion.Type != SMESH::FT_LinearOrQuadratic)
{
aTable->item( theRow, 2 )->setText(QString("%1").arg(theCriterion.Threshold, 0, 'g', 15));
}
@@ -1341,10 +1345,14 @@ void SMESHGUI_FilterTable::updateAdditionalWidget()
aCriterion != SMESH::FT_RangeOfIds &&
aCriterion != SMESH::FT_FreeEdges &&
aCriterion != SMESH::FT_FreeFaces &&
- aCriterion != SMESH::FT_BadOrientedVolume)
+ aCriterion != SMESH::FT_BadOrientedVolume &&
+ aCriterion != SMESH::FT_BareBorderFace &&
+ aCriterion != SMESH::FT_BareBorderVolume &&
+ aCriterion != SMESH::FT_OverConstrainedFace &&
+ aCriterion != SMESH::FT_OverConstrainedVolume)
||
aCriterion == SMESH::FT_CoplanarFaces);
-
+
if (!myAddWidgets.contains(anItem))
{
myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack);
@@ -1520,9 +1528,13 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
if ((aType == SMESH::NODE && aCriterionType == SMESH::FT_FreeNodes ) ||
(aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders ) ||
- (aType == SMESH::FACE && (aCriterionType == SMESH::FT_FreeEdges ||
+ (aType == SMESH::FACE && (aCriterionType == SMESH::FT_BareBorderFace ||
+ aCriterionType == SMESH::FT_OverConstrainedFace ||
+ aCriterionType == SMESH::FT_FreeEdges ||
aCriterionType == SMESH::FT_FreeFaces)) ||
- (aType == SMESH::VOLUME && aCriterionType == SMESH::FT_BadOrientedVolume) ||
+ (aType == SMESH::VOLUME && (aCriterionType == SMESH::FT_BadOrientedVolume ||
+ aCriterionType == SMESH::FT_OverConstrainedVolume ||
+ aCriterionType == SMESH::FT_BareBorderVolume)) ||
aCriterionType == SMESH::FT_LinearOrQuadratic ||
aCriterionType == SMESH::FT_GroupColor ||
aCriterionType == SMESH::FT_ElemGeomType ||
@@ -1808,6 +1820,8 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType)
aCriteria[ SMESH::FT_Length2D ] = tr("LENGTH2D");
aCriteria[ SMESH::FT_MultiConnection2D ] = tr("MULTI2D_BORDERS");
aCriteria[ SMESH::FT_FreeFaces ] = tr("FREE_FACES");
+ aCriteria[ SMESH::FT_BareBorderFace ] = tr("BARE_BORDER_FACE");
+ aCriteria[ SMESH::FT_OverConstrainedFace] = tr("OVER_CONSTRAINED_FACE");
aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR");
aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR");
aCriteria[ SMESH::FT_ElemGeomType ] = tr("GEOM_TYPE");
@@ -1820,16 +1834,18 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType)
static QMap aCriteria;
if (aCriteria.isEmpty())
{
- aCriteria[ SMESH::FT_AspectRatio3D ] = tr("ASPECT_RATIO_3D");
- 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_BadOrientedVolume ] = tr("BAD_ORIENTED_VOLUME");
- aCriteria[ SMESH::FT_Volume3D ] = tr("VOLUME_3D");
- aCriteria[ SMESH::FT_MaxElementLength3D ] = tr("MAX_ELEMENT_LENGTH_3D");
- aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR");
- aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR");
- aCriteria[ SMESH::FT_ElemGeomType ] = tr("GEOM_TYPE");
+ aCriteria[ SMESH::FT_AspectRatio3D ] = tr("ASPECT_RATIO_3D");
+ 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_BadOrientedVolume ] = tr("BAD_ORIENTED_VOLUME");
+ aCriteria[ SMESH::FT_BareBorderVolume ] = tr("BARE_BORDER_VOLUME");
+ aCriteria[ SMESH::FT_OverConstrainedVolume] = tr("OVER_CONSTRAINED_VOLUME");
+ aCriteria[ SMESH::FT_Volume3D ] = tr("VOLUME_3D");
+ aCriteria[ SMESH::FT_MaxElementLength3D ] = tr("MAX_ELEMENT_LENGTH_3D");
+ aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR");
+ aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR");
+ aCriteria[ SMESH::FT_ElemGeomType ] = tr("GEOM_TYPE");
}
return aCriteria;
}
diff --git a/src/SMESHGUI/SMESHGUI_Hypotheses.cxx b/src/SMESHGUI/SMESHGUI_Hypotheses.cxx
index a964d8cfc..e974edc52 100644
--- a/src/SMESHGUI/SMESHGUI_Hypotheses.cxx
+++ b/src/SMESHGUI/SMESHGUI_Hypotheses.cxx
@@ -309,7 +309,7 @@ void SMESHGUI_GenericHypothesisCreator::onDialogFinished( int result )
disconnect( myDlg, SIGNAL( finished( int ) ), this, SLOT( onDialogFinished( int ) ) );
myDlg->close();
- //delete myDlg;
+ //delete myDlg; since WA_DeleteOnClose==true
myDlg = 0;
emit finished( result );
}
diff --git a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx
index 43640501e..b1f9284c6 100644
--- a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx
+++ b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx
@@ -418,7 +418,7 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI*
}
QColor distributionColor = mgr->colorValue("SMESH", "distribution_color",
- QColor(255, 255, 255));
+ QColor(255, 255, 255));
myMonoColorBtn->setColor(distributionColor);
@@ -509,18 +509,6 @@ bool SMESHGUI_Preferences_ScalarBarDlg::onApply()
myScalarBarActor->SetLabelTextProperty( aLabelsTextPrp );
myScalarBarActor->SetNumberOfLabels( myLabelsSpin->value() );
- if( myColorsSpin->value() != myScalarBarActor->GetMaximumNumberOfColors() ) {
- myScalarBarActor->SetMaximumNumberOfColors( myColorsSpin->value() );
- SMESH::Controls::FunctorPtr fn = myActor->GetFunctor();
- SMESH::Controls::NumericalFunctor* aNumericalFunctor = dynamic_cast(fn.get());
- if( aNumericalFunctor ) {
- int nbIntervals = myColorsSpin->value();
- std::vector nbEvents;
- std::vector funValues;
- aNumericalFunctor->GetHistogram(nbIntervals, nbEvents, funValues);
- myScalarBarActor->SetDistribution(nbEvents);
- }
- }
if ( myHorizRadioBtn->isChecked() )
myScalarBarActor->SetOrientationToHorizontal();
@@ -550,9 +538,22 @@ bool SMESHGUI_Preferences_ScalarBarDlg::onApply()
double aMax = myMaxEdit->text().toDouble();
vtkLookupTable* myLookupTable =
static_cast(myScalarBarActor->GetLookupTable());
+ double oldMinMax[2] = { myLookupTable->GetRange()[0], myLookupTable->GetRange()[1] };
+ bool rangeChanges = ( fabs( oldMinMax[0] - aMin ) + fabs( oldMinMax[1] - aMax ) >
+ 0.001 * ( aMax-aMin + oldMinMax[1]-oldMinMax[0] ));
+
+ bool nbColorsChanged = (myColorsSpin->value() != myScalarBarActor->GetMaximumNumberOfColors());
+ if(nbColorsChanged)
+ myScalarBarActor->SetMaximumNumberOfColors(myColorsSpin->value());
+
+
myLookupTable->SetRange( aMin, aMax );
myLookupTable->SetNumberOfTableValues(myColorsSpin->value());
myLookupTable->Build();
+
+ if( nbColorsChanged || rangeChanges)
+ myActor->UpdateDistribution();
+
SMESH::RepaintCurrentView();
return true;
}
@@ -655,17 +656,17 @@ void SMESHGUI_Preferences_ScalarBarDlg::onSelectionChanged()
myIniH = myScalarBarActor->GetHeight();
setOriginAndSize( myIniX, myIniY, myIniW, myIniH );
- myDistributionGrp->setChecked((bool)myScalarBarActor->GetDistributionVisibility());
- int coloringType = myScalarBarActor->GetDistributionColoringType();
- myScalarBarActor->GetDistributionColor( aTColor );
- myMonoColorBtn->setColor( QColor( (int)( aTColor[0]*255 ), (int)( aTColor[1]*255 ), (int)( aTColor[2]*255 ) ) );
- if ( coloringType == SMESH_MONOCOLOR_TYPE ) {
- myDMonoColor->setChecked(true);
- onDistributionChanged(myDistribColorGrp->id(myDMonoColor));
- } else {
- myDMultiColor->setChecked(true);
- onDistributionChanged(myDistribColorGrp->id(myDMultiColor));
- }
+ myDistributionGrp->setChecked((bool)myScalarBarActor->GetDistributionVisibility());
+ int coloringType = myScalarBarActor->GetDistributionColoringType();
+ myScalarBarActor->GetDistributionColor( aTColor );
+ myMonoColorBtn->setColor( QColor( (int)( aTColor[0]*255 ), (int)( aTColor[1]*255 ), (int)( aTColor[2]*255 ) ) );
+ if ( coloringType == SMESH_MONOCOLOR_TYPE ) {
+ myDMonoColor->setChecked(true);
+ onDistributionChanged(myDistribColorGrp->id(myDMonoColor));
+ } else {
+ myDMultiColor->setChecked(true);
+ onDistributionChanged(myDistribColorGrp->id(myDMultiColor));
+ }
myRangeGrp->setEnabled( true );
myFontGrp->setEnabled( true );
myLabColorGrp->setEnabled( true );
diff --git a/src/SMESHGUI/SMESHGUI_Utils.cxx b/src/SMESHGUI/SMESHGUI_Utils.cxx
index dfe778831..331ad9f92 100644
--- a/src/SMESHGUI/SMESHGUI_Utils.cxx
+++ b/src/SMESHGUI/SMESHGUI_Utils.cxx
@@ -214,7 +214,7 @@ namespace SMESH
QString IOR = app->orb()->object_to_string( theObject );
SalomeApp_Study* study = dynamic_cast( app->activeStudy() );
if ( study && !IOR.isEmpty() )
- res = study->studyDS()->FindObjectIOR( IOR.toLatin1().constData() );
+ res = study->studyDS()->FindObjectIOR( IOR.toLatin1().constData() );
}
return res;
}
diff --git a/src/SMESHGUI/SMESH_images.ts b/src/SMESHGUI/SMESH_images.ts
index 856e88f32..3eff547c5 100644
--- a/src/SMESHGUI/SMESH_images.ts
+++ b/src/SMESHGUI/SMESH_images.ts
@@ -53,6 +53,10 @@
ICON_BUILD_COMPOUND
mesh_build_compound.png
+
+ ICON_COPY_MESH
+ copy_mesh.png
+
ICON_COMPUTE
mesh_compute.png
@@ -109,6 +113,10 @@
ICON_DLG_BUILD_COMPOUND_MESH
mesh_build_compound.png
+
+ ICON_DLG_COPY_MESH
+ copy_mesh.png
+
ICON_DLG_ELEM0D
mesh_vertex.png
@@ -457,6 +465,22 @@
ICON_VOLUME_3D
mesh_volume_3d.png
+
+ ICON_BARE_BORDER_VOLUME
+ bare_border_volume.png
+
+
+ ICON_BARE_BORDER_FACE
+ bare_border_face.png
+
+
+ ICON_OVER_CONSTRAINED_VOLUME
+ over_constrained_volume.png
+
+
+ ICON_OVER_CONSTRAINED_FACE
+ over_constrained_face.png
+
ICON_WARP
mesh_wrap.png
diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts
index 81e2619ee..fdac42bca 100644
--- a/src/SMESHGUI/SMESH_msg_en.ts
+++ b/src/SMESHGUI/SMESH_msg_en.ts
@@ -187,6 +187,10 @@
MEN_BUILD_COMPOUND
Build Compound
+
+ MEN_COPY_MESH
+ Copy Mesh
+
MEN_CLIP
Clipping
@@ -395,6 +399,22 @@
STB_FIND_ELEM
Find Element by Point
+
+ MEN_BARE_BORDER_VOLUME
+ Volumes with bare border
+
+
+ MEN_BARE_BORDER_FACE
+ Faces with bare border
+
+
+ MEN_OVER_CONSTRAINED_VOLUME
+ Over-constrained volumes
+
+
+ MEN_OVER_CONSTRAINED_FACE
+ Over-constrained faces
+
MEN_FREE_BORDER
Free Borders
@@ -1040,6 +1060,14 @@ Please enter correct values and try again
SMESH_BUILD_COMPOUND_TITLE
Create a Compound
+
+ SMESH_COPY_MESH_TITLE
+ Copy Mesh
+
+
+ SMESH_KEEP_IDS
+ Preserve IDs of elements
+
SMESH_BUT_ADD
A&dd
@@ -2274,6 +2302,10 @@ Please check preferences of Mesh module.
STB_BUILD_COMPOUND
Build Compound Mesh
+
+ STB_COPY_MESH
+ Copy Mesh
+
STB_CLIP
Clipping
@@ -2434,6 +2466,22 @@ Please check preferences of Mesh module.
STB_FACES
Faces
+
+ STB_BARE_BORDER_VOLUME
+ Volumes with bare border
+
+
+ STB_BARE_BORDER_FACE
+ Faces with bare border
+
+
+ STB_OVER_CONSTRAINED_VOLUME
+ Over-constrained volumes
+
+
+ STB_OVER_CONSTRAINED_FACE
+ Over-constrained faces
+
STB_FREE_BORDER
Free Borders
@@ -2810,6 +2858,10 @@ Please check preferences of Mesh module.
TOP_BUILD_COMPOUND
Build Compound Mesh
+
+ TOP_COPY_MESH
+ Copy Mesh
+
TOP_CLIP
Clipping
@@ -2970,6 +3022,22 @@ Please check preferences of Mesh module.
TOP_FACES
Faces
+
+ TOP_BARE_BORDER_VOLUME
+ Volumes with bare border
+
+
+ TOP_BARE_BORDER_FACE
+ Faces with bare border
+
+
+ TOP_OVER_CONSTRAINED_VOLUME
+ Over-constrained volumes
+
+
+ TOP_OVER_CONSTRAINED_FACE
+ Over-constrained faces
+
TOP_FREE_BORDER
Free Borders
@@ -4320,6 +4388,22 @@ Please check input data and try again
BAD_ORIENTED_VOLUME
Bad oriented volume
+
+ BARE_BORDER_VOLUME
+ Volumes with bare border
+
+
+ BARE_BORDER_FACE
+ Faces with bare border
+
+
+ OVER_CONSTRAINED_VOLUME
+ Over-constrained volumes
+
+
+ OVER_CONSTRAINED_FACE
+ Over-constrained faces
+
BELONG_TO_CYLINDER
Belong to Cylinder
@@ -5847,6 +5931,21 @@ It is impossible to read point coordinates from file
Distance
+
+ SMESHGUI_CopyMeshDlg
+
+ OBJECT_NAME
+ Source Object
+
+
+ ELEM_IDS
+ Source Element IDs
+
+
+ NEW_NAME
+ New Mesh Name
+
+
SMESHGUI_MeasureDlg
diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx
index dfb378f24..c6bc91e8d 100644
--- a/src/SMESH_I/SMESH_2smeshpy.cxx
+++ b/src/SMESH_I/SMESH_2smeshpy.cxx
@@ -247,7 +247,8 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
// SMESH_Mesh method?
map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( objID );
- if ( id_mesh != myMeshes.end() ) {
+ if ( id_mesh != myMeshes.end() )
+ {
// check for mesh editor object
if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation
_pyID editorID = aCommand->GetResultValue();
@@ -268,7 +269,8 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
// SMESH_MeshEditor method?
map< _pyID, Handle(_pyMeshEditor) >::iterator id_editor = myMeshEditors.find( objID );
- if ( id_editor != myMeshEditors.end() ) {
+ if ( id_editor != myMeshEditors.end() )
+ {
id_editor->second->Process( aCommand );
TCollection_AsciiString processedCommand = aCommand->GetString();
// some commands of SMESH_MeshEditor create meshes
@@ -277,6 +279,15 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
aCommand->GetString() = processedCommand; // discard changes made by _pyMesh
myMeshes.insert( make_pair( mesh->GetID(), mesh ));
}
+ if ( aCommand->GetMethod() == "MakeBoundaryMesh") {
+ _pyID meshID = aCommand->GetResultValue(0);
+ if ( !myMeshes.count( meshID ) )
+ {
+ Handle(_pyMesh) mesh = new _pyMesh( aCommand, meshID );
+ aCommand->GetString() = processedCommand; // discard changes made by _pyMesh
+ myMeshes.insert( make_pair( meshID, mesh ));
+ }
+ }
return aCommand;
}
// SMESH_Hypothesis method?
@@ -352,7 +363,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
myMeshes.insert( make_pair( mesh->GetID(), mesh ));
return;
}
- if ( method == "CreateMeshesFromUNV" || method == "CreateMeshesFromSTL")
+ if ( method == "CreateMeshesFromUNV" || method == "CreateMeshesFromSTL" || method == "CopyMesh" )
{
Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() );
myMeshes.insert( make_pair( mesh->GetID(), mesh ));
@@ -1125,7 +1136,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
"SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes",
"GetLastCreatedElems",
"MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh",
- "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh"
+ "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh"
,"" }; // <- mark of the end
sameMethods.Insert( names );
}
diff --git a/src/SMESH_I/SMESH_DumpPython.cxx b/src/SMESH_I/SMESH_DumpPython.cxx
index 3fd8ff22f..a8e4205b2 100644
--- a/src/SMESH_I/SMESH_DumpPython.cxx
+++ b/src/SMESH_I/SMESH_DumpPython.cxx
@@ -232,7 +232,10 @@ namespace SMESH
if(!aSObject->_is_nil() || CORBA::is_nil( theArg ))
return *this << aSObject;
SMESH::long_array_var anElementsId = theArg->GetIDs();
- return *this << anElementsId;
+ SMESH::SMESH_Mesh_var mesh = theArg->GetMesh();
+ SMESH::array_of_ElementType_var types = theArg->GetTypes();
+ SMESH::ElementType type = types->length() ? types[0] : SMESH::ALL;
+ return *this << mesh << ".GetIDSource(" << anElementsId << ", " << type << ")";
}
TPythonDump&
@@ -266,43 +269,47 @@ namespace SMESH
if ( theArg ) {
FunctorType aFunctorType = theArg->GetFunctorType();
switch(aFunctorType){
- case FT_AspectRatio: myStream<< "anAspectRatio"; break;
- case FT_AspectRatio3D: myStream<< "anAspectRatio3D"; break;
- case FT_Warping: myStream<< "aWarping"; break;
- case FT_MinimumAngle: myStream<< "aMinimumAngle"; break;
- case FT_Taper: myStream<< "aTaper"; break;
- case FT_Skew: myStream<< "aSkew"; break;
- case FT_Area: myStream<< "aArea"; break;
- case FT_Volume3D: myStream<< "aVolume3D"; break;
- case FT_MaxElementLength2D:myStream<< "aMaxElementLength2D";break;
- case FT_MaxElementLength3D:myStream<< "aMaxElementLength3D";break;
- case FT_FreeBorders: myStream<< "aFreeBorders"; break;
- case FT_FreeEdges: myStream<< "aFreeEdges"; break;
- case FT_FreeNodes: myStream<< "aFreeNodes"; break;
- case FT_FreeFaces: myStream<< "aFreeFaces"; break;
- case FT_MultiConnection: myStream<< "aMultiConnection"; break;
- case FT_MultiConnection2D:myStream<< "aMultiConnection2D";break;
- case FT_Length: myStream<< "aLength"; break;
- case FT_Length2D: myStream<< "aLength"; break;
- case FT_BelongToGeom: myStream<< "aBelongToGeom"; break;
- case FT_BelongToPlane: myStream<< "aBelongToPlane"; break;
- case FT_BelongToCylinder: myStream<< "aBelongToCylinder"; break;
- case FT_BelongToGenSurface:myStream<<"aBelongToGenSurface";break;
- case FT_LyingOnGeom: myStream<< "aLyingOnGeom"; break;
- case FT_CoplanarFaces: myStream<< "aCoplanarFaces"; break;
- case FT_RangeOfIds: myStream<< "aRangeOfIds"; break;
- case FT_BadOrientedVolume:myStream<< "aBadOrientedVolume";break;
- case FT_LinearOrQuadratic:myStream<< "aLinearOrQuadratic";break;
- case FT_GroupColor: myStream<< "aGroupColor"; break;
- case FT_ElemGeomType: myStream<< "anElemGeomType"; break;
- case FT_LessThan: myStream<< "aLessThan"; break;
- case FT_MoreThan: myStream<< "aMoreThan"; break;
- case FT_EqualTo: myStream<< "anEqualTo"; break;
- case FT_LogicalNOT: myStream<< "aLogicalNOT"; break;
- case FT_LogicalAND: myStream<< "aLogicalAND"; break;
- case FT_LogicalOR: myStream<< "aLogicalOR"; break;
+ case FT_AspectRatio: myStream<< "anAspectRatio"; break;
+ case FT_AspectRatio3D: myStream<< "anAspectRatio3D"; break;
+ case FT_Warping: myStream<< "aWarping"; break;
+ case FT_MinimumAngle: myStream<< "aMinimumAngle"; break;
+ case FT_Taper: myStream<< "aTaper"; break;
+ case FT_Skew: myStream<< "aSkew"; break;
+ case FT_Area: myStream<< "aArea"; break;
+ case FT_Volume3D: myStream<< "aVolume3D"; break;
+ case FT_MaxElementLength2D: myStream<< "aMaxElementLength2D"; break;
+ case FT_MaxElementLength3D: myStream<< "aMaxElementLength3D"; break;
+ case FT_FreeBorders: myStream<< "aFreeBorders"; break;
+ case FT_FreeEdges: myStream<< "aFreeEdges"; break;
+ case FT_FreeNodes: myStream<< "aFreeNodes"; break;
+ case FT_FreeFaces: myStream<< "aFreeFaces"; break;
+ case FT_MultiConnection: myStream<< "aMultiConnection"; break;
+ case FT_MultiConnection2D: myStream<< "aMultiConnection2D"; break;
+ case FT_Length: myStream<< "aLength"; break;
+ case FT_Length2D: myStream<< "aLength2D"; break;
+ case FT_BelongToGeom: myStream<< "aBelongToGeom"; break;
+ case FT_BelongToPlane: myStream<< "aBelongToPlane"; break;
+ case FT_BelongToCylinder: myStream<< "aBelongToCylinder"; break;
+ case FT_BelongToGenSurface: myStream<< "aBelongToGenSurface"; break;
+ case FT_LyingOnGeom: myStream<< "aLyingOnGeom"; break;
+ case FT_CoplanarFaces: myStream<< "aCoplanarFaces"; break;
+ case FT_RangeOfIds: myStream<< "aRangeOfIds"; break;
+ case FT_BadOrientedVolume: myStream<< "aBadOrientedVolume"; break;
+ case FT_BareBorderVolume: myStream<< "aBareBorderVolume"; break;
+ case FT_BareBorderFace: myStream<< "aBareBorderFace"; break;
+ case FT_OverConstrainedVolume: myStream<< "aOverConstrainedVolume"; break;
+ case FT_OverConstrainedFace: myStream<< "aOverConstrainedFace"; break;
+ case FT_LinearOrQuadratic: myStream<< "aLinearOrQuadratic"; break;
+ case FT_GroupColor: myStream<< "aGroupColor"; break;
+ case FT_ElemGeomType: myStream<< "anElemGeomType"; break;
+ case FT_LessThan: myStream<< "aLessThan"; break;
+ case FT_MoreThan: myStream<< "aMoreThan"; break;
+ case FT_EqualTo: myStream<< "anEqualTo"; break;
+ case FT_LogicalNOT: myStream<< "aLogicalNOT"; break;
+ case FT_LogicalAND: myStream<< "aLogicalAND"; break;
+ case FT_LogicalOR: myStream<< "aLogicalOR"; break;
case FT_Undefined:
- default: myStream<< "anUndefined"; break;
+ default: myStream<< "anUndefined"; break;
}
myStream< nbEvents;
std::vector funValues;
- myNumericalFunctorPtr->GetHistogram(nbIntervals,nbEvents,funValues);
+ std::vector elements;
+ myNumericalFunctorPtr->GetHistogram(nbIntervals,nbEvents,funValues,elements);
nbIntervals = CORBA::Short( std::min( nbEvents.size(), funValues.size() - 1));
SMESH::Histogram_var histogram = new SMESH::Histogram;
@@ -937,6 +939,66 @@ FunctorType BadOrientedVolume_i::GetFunctorType()
return SMESH::FT_BadOrientedVolume;
}
+/*
+ Class : BareBorderVolume_i
+ Description : Verify whether a mesh volume has a free facet without a face on it
+*/
+BareBorderVolume_i::BareBorderVolume_i()
+{
+ Controls::PredicatePtr control( new Controls::BareBorderVolume() );
+ myFunctorPtr = myPredicatePtr = control;
+};
+
+FunctorType BareBorderVolume_i::GetFunctorType()
+{
+ return SMESH::FT_BareBorderVolume;
+}
+
+/*
+ Class : BareBorderFace_i
+ Description : Verify whether a mesh face has a free border without an edge on it
+*/
+BareBorderFace_i::BareBorderFace_i()
+{
+ Controls::PredicatePtr control( new Controls::BareBorderFace() );
+ myFunctorPtr = myPredicatePtr = control;
+};
+
+FunctorType BareBorderFace_i::GetFunctorType()
+{
+ return SMESH::FT_BareBorderFace;
+}
+
+/*
+ Class : OverConstrainedVolume_i
+ Description : Verify whether a mesh volume has only one facet shared with other volumes
+*/
+OverConstrainedVolume_i::OverConstrainedVolume_i()
+{
+ Controls::PredicatePtr control( new Controls::OverConstrainedVolume() );
+ myFunctorPtr = myPredicatePtr = control;
+};
+
+FunctorType OverConstrainedVolume_i::GetFunctorType()
+{
+ return SMESH::FT_OverConstrainedVolume;
+}
+
+/*
+ Class : OverConstrainedFace_i
+ Description : Verify whether a mesh face has only one border shared with other faces
+*/
+OverConstrainedFace_i::OverConstrainedFace_i()
+{
+ Controls::PredicatePtr control( new Controls::OverConstrainedFace() );
+ myFunctorPtr = myPredicatePtr = control;
+};
+
+FunctorType OverConstrainedFace_i::GetFunctorType()
+{
+ return SMESH::FT_OverConstrainedFace;
+}
+
/*
Class : BelongToGeom_i
Description : Predicate for selection on geometrical support
@@ -2036,6 +2098,38 @@ BadOrientedVolume_ptr FilterManager_i::CreateBadOrientedVolume()
return anObj._retn();
}
+BareBorderVolume_ptr FilterManager_i::CreateBareBorderVolume()
+{
+ SMESH::BareBorderVolume_i* aServant = new SMESH::BareBorderVolume_i();
+ SMESH::BareBorderVolume_var anObj = aServant->_this();
+ TPythonDump()<_this();
+ TPythonDump()<_this();
+ TPythonDump()<_this();
+ TPythonDump()<GetElementType();
+ return true;
+ }
+ case FT_BareBorderVolume:
+ {
+ BareBorderVolume_i* aPred = dynamic_cast( thePred );
+
+ CORBA::ULong i = theCriteria->length();
+ theCriteria->length( i + 1 );
+
+ theCriteria[ i ] = createCriterion();
+
+ theCriteria[ i ].Type = FT_BareBorderVolume;
+ theCriteria[ i ].TypeOfElement = aPred->GetElementType();
+
+ return true;
+ }
+ case FT_BareBorderFace:
+ {
+ BareBorderFace_i* aPred = dynamic_cast( thePred );
+
+ CORBA::ULong i = theCriteria->length();
+ theCriteria->length( i + 1 );
+
+ theCriteria[ i ] = createCriterion();
+
+ theCriteria[ i ].Type = FT_BareBorderFace;
+ theCriteria[ i ].TypeOfElement = aPred->GetElementType();
+
+ return true;
+ }
+ case FT_OverConstrainedVolume:
+ {
+ OverConstrainedVolume_i* aPred = dynamic_cast( thePred );
+
+ CORBA::ULong i = theCriteria->length();
+ theCriteria->length( i + 1 );
+
+ theCriteria[ i ] = createCriterion();
+
+ theCriteria[ i ].Type = FT_OverConstrainedVolume;
+ theCriteria[ i ].TypeOfElement = aPred->GetElementType();
+
+ return true;
+ }
+ case FT_OverConstrainedFace:
+ {
+ OverConstrainedFace_i* aPred = dynamic_cast( thePred );
+
+ CORBA::ULong i = theCriteria->length();
+ theCriteria->length( i + 1 );
+
+ theCriteria[ i ] = createCriterion();
+
+ theCriteria[ i ].Type = FT_OverConstrainedFace;
+ theCriteria[ i ].TypeOfElement = aPred->GetElementType();
+
return true;
}
case FT_LessThan:
@@ -2723,6 +2873,26 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
aPredicate = aFilterMgr->CreateBadOrientedVolume();
}
break;
+ case SMESH::FT_BareBorderVolume:
+ {
+ aPredicate = aFilterMgr->CreateBareBorderVolume();
+ }
+ break;
+ case SMESH::FT_BareBorderFace:
+ {
+ aPredicate = aFilterMgr->CreateBareBorderFace();
+ }
+ break;
+ case SMESH::FT_OverConstrainedVolume:
+ {
+ aPredicate = aFilterMgr->CreateOverConstrainedVolume();
+ }
+ break;
+ case SMESH::FT_OverConstrainedFace:
+ {
+ aPredicate = aFilterMgr->CreateOverConstrainedFace();
+ }
+ break;
case SMESH::FT_LinearOrQuadratic:
{
SMESH::LinearOrQuadratic_ptr tmpPred = aFilterMgr->CreateLinearOrQuadratic();
@@ -2963,7 +3133,11 @@ static inline LDOMString toString( CORBA::Long theType )
case FT_BelongToCylinder: return "Belong to Cylinder";
case FT_BelongToGenSurface: return "Belong to Generic Surface";
case FT_LyingOnGeom : return "Lying on Geom";
- case FT_BadOrientedVolume: return "Bad Oriented Volume";
+ case FT_BadOrientedVolume:return "Bad Oriented Volume";
+ case FT_BareBorderVolume: return "Volumes with bare border";
+ case FT_BareBorderFace : return "Faces with bare border";
+ case FT_OverConstrainedVolume: return "Over-constrained Volumes";
+ case FT_OverConstrainedFace : return "Over-constrained Faces";
case FT_RangeOfIds : return "Range of IDs";
case FT_FreeBorders : return "Free borders";
case FT_FreeEdges : return "Free edges";
@@ -3017,6 +3191,10 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
// else if ( theStr.equals( "Length2D" ) ) return FT_Length2D;
else if ( theStr.equals( "Range of IDs" ) ) return FT_RangeOfIds;
else if ( theStr.equals( "Bad Oriented Volume" ) ) return FT_BadOrientedVolume;
+ else if ( theStr.equals( "Volumes with bare border" ) ) return FT_BareBorderVolume;
+ else if ( theStr.equals( "Faces with bare border" ) ) return FT_BareBorderFace;
+ else if ( theStr.equals( "Over-constrained Volumes" ) ) return FT_OverConstrainedVolume;
+ else if ( theStr.equals( "Over-constrained Faces" ) ) return FT_OverConstrainedFace;
else if ( theStr.equals( "Less than" ) ) return FT_LessThan;
else if ( theStr.equals( "More than" ) ) return FT_MoreThan;
else if ( theStr.equals( "Equal to" ) ) return FT_EqualTo;
diff --git a/src/SMESH_I/SMESH_Filter_i.hxx b/src/SMESH_I/SMESH_Filter_i.hxx
index bef8c2252..9ca20ddb4 100644
--- a/src/SMESH_I/SMESH_Filter_i.hxx
+++ b/src/SMESH_I/SMESH_Filter_i.hxx
@@ -44,6 +44,7 @@ class SMESHDS_Mesh;
namespace SMESH
{
+ // ================================================================================
namespace Controls
{
@@ -123,8 +124,10 @@ namespace SMESH
Controls::ElementsOnShapePtr myElementsOnShapePtr; // only if myIsSubshape == false
};
typedef boost::shared_ptr LyingOnGeomPtr;
- }
-
+
+ } // namespace Controls
+
+ // ================================================================================
/*
FUNCTORS
*/
@@ -387,6 +390,54 @@ namespace SMESH
FunctorType GetFunctorType();
};
+ /*
+ Class : BareBorderVolume_i
+ Description : Verify whether a mesh volume has a free facet without a face on it
+ */
+ class SMESH_I_EXPORT BareBorderVolume_i: public virtual POA_SMESH::BareBorderVolume,
+ public virtual Predicate_i
+ {
+ public:
+ BareBorderVolume_i();
+ FunctorType GetFunctorType();
+ };
+
+ /*
+ Class : BareBorderFace_i
+ Description : Verify whether a mesh face has a free border without an edge on it
+ */
+ class SMESH_I_EXPORT BareBorderFace_i: public virtual POA_SMESH::BareBorderFace,
+ public virtual Predicate_i
+ {
+ public:
+ BareBorderFace_i();
+ FunctorType GetFunctorType();
+ };
+
+ /*
+ Class : OverConstrainedVolume_i
+ Description : Verify whether a mesh volume has only one facet shared with other volumes
+ */
+ class SMESH_I_EXPORT OverConstrainedVolume_i: public virtual POA_SMESH::OverConstrainedVolume,
+ public virtual Predicate_i
+ {
+ public:
+ OverConstrainedVolume_i();
+ FunctorType GetFunctorType();
+ };
+
+ /*
+ Class : OverConstrainedFace_i
+ Description : Verify whether a mesh face has only one border shared with other faces
+ */
+ class SMESH_I_EXPORT OverConstrainedFace_i: public virtual POA_SMESH::OverConstrainedFace,
+ public virtual Predicate_i
+ {
+ public:
+ OverConstrainedFace_i();
+ FunctorType GetFunctorType();
+ };
+
/*
Class : BelongToGeom_i
Description : Predicate for selection on geometrical support
@@ -954,6 +1005,10 @@ namespace SMESH
RangeOfIds_ptr CreateRangeOfIds();
BadOrientedVolume_ptr CreateBadOrientedVolume();
+ BareBorderFace_ptr CreateBareBorderFace();
+ BareBorderVolume_ptr CreateBareBorderVolume();
+ OverConstrainedFace_ptr CreateOverConstrainedFace();
+ OverConstrainedVolume_ptr CreateOverConstrainedVolume();
LinearOrQuadratic_ptr CreateLinearOrQuadratic();
GroupColor_ptr CreateGroupColor();
ElemGeomType_ptr CreateElemGeomType();
diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx
index 47e0fad99..41aa724c5 100644
--- a/src/SMESH_I/SMESH_Gen_i.cxx
+++ b/src/SMESH_I/SMESH_Gen_i.cxx
@@ -91,9 +91,10 @@
#include "SMDS_EdgePosition.hxx"
#include "SMDS_FacePosition.hxx"
-#include "SMDS_VertexPosition.hxx"
-#include "SMDS_SpacePosition.hxx"
#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_SetIterator.hxx"
+#include "SMDS_SpacePosition.hxx"
+#include "SMDS_VertexPosition.hxx"
#include CORBA_SERVER_HEADER(SMESH_Group)
#include CORBA_SERVER_HEADER(SMESH_Filter)
@@ -901,7 +902,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName
aServant->ImportUNVFile( theFileName );
// Dump creation of groups
- aServant->GetGroups();
+ SMESH::ListOfGroups_var groups = aServant->GetGroups();
aServant->GetImpl().GetMeshDS()->Modified();
return aMesh._retn();
@@ -982,7 +983,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
}
// Dump creation of groups
for ( int i = 0; i < aResult->length(); ++i )
- aResult[ i ]->GetGroups();
+ SMESH::ListOfGroups_var groups = aResult[ i ]->GetGroups();
return aResult._retn();
}
@@ -2211,6 +2212,212 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
return aNewMesh._retn();
}
+//================================================================================
+/*!
+ * \brief Create a mesh by copying a part of another mesh
+ * \param meshPart - a part of mesh to copy
+ * \param toCopyGroups - to create in the new mesh groups
+ * the copied elements belongs to
+ * \param toKeepIDs - to preserve IDs of the copied elements or not
+ * \retval SMESH::SMESH_Mesh_ptr - the new mesh
+ */
+//================================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
+ const char* meshName,
+ CORBA::Boolean toCopyGroups,
+ CORBA::Boolean toKeepIDs)
+{
+ Unexpect aCatch(SALOME_SalomeException);
+
+ TPythonDump* pyDump = new TPythonDump; // prevent dump from CreateMesh()
+
+ // 1. Get source mesh
+
+ if ( CORBA::is_nil( meshPart ))
+ THROW_SALOME_CORBA_EXCEPTION( "bad IDSource", SALOME::BAD_PARAM );
+
+ SMESH::SMESH_Mesh_var srcMesh = meshPart->GetMesh();
+ SMESH_Mesh_i* srcMesh_i = SMESH::DownCast( srcMesh );
+ if ( !srcMesh_i )
+ THROW_SALOME_CORBA_EXCEPTION( "bad mesh of IDSource", SALOME::BAD_PARAM );
+
+ SMESHDS_Mesh* srcMeshDS = srcMesh_i->GetImpl().GetMeshDS();
+
+ // 2. Make a new mesh
+
+ SMESH::SMESH_Mesh_var newMesh = CreateMesh(GEOM::GEOM_Object::_nil());
+ SMESH_Mesh_i* newMesh_i = SMESH::DownCast( newMesh );
+ if ( !newMesh_i )
+ THROW_SALOME_CORBA_EXCEPTION( "can't create a mesh", SALOME::INTERNAL_ERROR );
+ SALOMEDS::SObject_var meshSO = ObjectToSObject(myCurrentStudy, newMesh );
+ if ( !meshSO->_is_nil() )
+ {
+ SetName( meshSO, meshName, "Mesh" );
+ SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
+ }
+ SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS();
+ ::SMESH_MeshEditor editor( &newMesh_i->GetImpl() );
+
+ // 3. Get elements to copy
+
+ SMDS_ElemIteratorPtr srcElemIt;
+ TIDSortedElemSet srcElems;
+ SMESH::array_of_ElementType_var srcElemTypes = meshPart->GetTypes();
+ if ( SMESH::DownCast( meshPart ))
+ {
+ srcElemIt = srcMeshDS->elementsIterator();
+ }
+ else
+ {
+ SMESH::long_array_var ids = meshPart->GetIDs();
+ if ( srcElemTypes->length() == 1 && srcElemTypes[0] == SMESH::NODE ) // group of nodes
+ {
+ for (int i=0; i < ids->length(); i++)
+ if ( const SMDS_MeshElement * elem = srcMeshDS->FindNode( ids[i] ))
+ srcElems.insert( elem );
+ }
+ else
+ {
+ for (int i=0; i < ids->length(); i++)
+ if ( const SMDS_MeshElement * elem = srcMeshDS->FindElement( ids[i] ))
+ srcElems.insert( elem );
+ }
+ if ( srcElems.empty() )
+ return newMesh._retn();
+
+ typedef SMDS_SetIterator< SMDS_pElement, TIDSortedElemSet::const_iterator > ElIter;
+ srcElemIt = SMDS_ElemIteratorPtr( new ElIter( srcElems.begin(), srcElems.end() ));
+ }
+
+ // 4. Copy elements
+
+ typedef map TE2EMap;
+ TE2EMap e2eMapByType[ SMDSAbs_NbElementTypes ];
+ TE2EMap& n2nMap = e2eMapByType[ SMDSAbs_Node ];
+ int iN;
+ const SMDS_MeshNode *nSrc, *nTgt;
+ vector< const SMDS_MeshNode* > nodes;
+ while ( srcElemIt->more() )
+ {
+ const SMDS_MeshElement * elem = srcElemIt->next();
+ nodes.resize( elem->NbNodes());
+ SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
+ if ( toKeepIDs ) {
+ for ( iN = 0; nIt->more(); ++iN )
+ {
+ nSrc = static_cast( nIt->next() );
+ nTgt = newMeshDS->FindNode( nSrc->GetID());
+ if ( !nTgt )
+ nTgt = newMeshDS->AddNodeWithID( nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID());
+ nodes[ iN ] = nTgt;
+ }
+ }
+ else {
+ for ( iN = 0; nIt->more(); ++iN )
+ {
+ nSrc = static_cast( nIt->next() );
+ TE2EMap::iterator n2n = n2nMap.insert( make_pair( nSrc, SMDS_pNode(0) )).first;
+ if ( !n2n->second )
+ n2n->second = newMeshDS->AddNode( nSrc->X(), nSrc->Y(), nSrc->Z() );
+ nodes[ iN ] = (const SMDS_MeshNode*) n2n->second;
+ }
+ }
+ if ( elem->GetType() != SMDSAbs_Node )
+ {
+ int ID = toKeepIDs ? elem->GetID() : 0;
+ const SMDS_MeshElement * newElem = editor.AddElement( nodes,
+ elem->GetType(),
+ elem->IsPoly(),
+ ID);
+ if ( toCopyGroups && !toKeepIDs )
+ e2eMapByType[ elem->GetType() ].insert( make_pair( elem, newElem ));
+ }
+ }
+
+ // 5. Copy groups
+
+ int nbNewGroups = 0;
+ if ( toCopyGroups )
+ {
+ SMESH_Mesh::GroupIteratorPtr gIt = srcMesh_i->GetImpl().GetGroups();
+ while ( gIt->more() )
+ {
+ SMESH_Group* group = gIt->next();
+ const SMESHDS_GroupBase* groupDS = group->GetGroupDS();
+
+ // Check group type. We copy nodal groups containing nodes of copied element
+ SMDSAbs_ElementType groupType = groupDS->GetType();
+ if ( groupType != SMDSAbs_Node &&
+ newMeshDS->GetMeshInfo().NbElements( groupType ) == 0 )
+ continue; // group type differs from types of meshPart
+
+ // Find copied elements in the group
+ vector< const SMDS_MeshElement* > groupElems;
+ SMDS_ElemIteratorPtr eIt = groupDS->GetElements();
+ if ( toKeepIDs )
+ {
+ const SMDS_MeshElement* foundElem;
+ if ( groupType == SMDSAbs_Node )
+ {
+ while ( eIt->more() )
+ if (( foundElem = newMeshDS->FindNode( eIt->next()->GetID() )))
+ groupElems.push_back( foundElem );
+ }
+ else
+ {
+ while ( eIt->more() )
+ if (( foundElem = newMeshDS->FindElement( eIt->next()->GetID() )))
+ groupElems.push_back( foundElem );
+ }
+ }
+ else
+ {
+ TE2EMap & e2eMap = e2eMapByType[ groupDS->GetType() ];
+ if ( e2eMap.empty() ) continue;
+ int minID = e2eMap.begin()->first->GetID();
+ int maxID = e2eMap.rbegin()->first->GetID();
+ TE2EMap::iterator e2e;
+ while ( eIt->more() && groupElems.size() < e2eMap.size())
+ {
+ const SMDS_MeshElement* e = eIt->next();
+ if ( e->GetID() < minID || e->GetID() > maxID ) continue;
+ if ((e2e = e2eMap.find( e )) != e2eMap.end())
+ groupElems.push_back( e2e->second );
+ }
+ }
+ // Make a new group
+ if ( !groupElems.empty() )
+ {
+ SMESH::SMESH_Group_var newGroupObj =
+ newMesh->CreateGroup( SMESH::ElementType(groupType), group->GetName() );
+ if ( SMESH_GroupBase_i* newGroup_i = SMESH::DownCast( newGroupObj))
+ {
+ SMESHDS_GroupBase * newGroupDS = newGroup_i->GetGroupDS();
+ SMDS_MeshGroup& smdsGroup = ((SMESHDS_Group*)newGroupDS)->SMDSGroup();
+ for ( unsigned i = 0; i < groupElems.size(); ++i )
+ smdsGroup.Add( groupElems[i] );
+
+ nbNewGroups++;
+ }
+ }
+ }
+ }
+
+ *pyDump << newMesh << " = " << this
+ << ".CopyMesh( " << meshPart << ", "
+ << "'" << meshName << "', "
+ << toCopyGroups << ", "
+ << toKeepIDs << ")";
+
+ delete pyDump; pyDump = 0; // allow dump in GetGroups()
+
+ if ( nbNewGroups > 0 ) // dump created groups
+ SMESH::ListOfGroups_var groups = newMesh->GetGroups();
+
+ return newMesh._retn();
+}
+
//================================================================================
/*!
* SMESH_Gen_i::GetMEDVersion
diff --git a/src/SMESH_I/SMESH_Gen_i.hxx b/src/SMESH_I/SMESH_Gen_i.hxx
index b2c90805c..b4003818d 100644
--- a/src/SMESH_I/SMESH_Gen_i.hxx
+++ b/src/SMESH_I/SMESH_Gen_i.hxx
@@ -236,6 +236,12 @@ public:
SMESH::SMESH_Mesh_ptr CreateMeshesFromSTL( const char* theFileName )
throw ( SALOME::SALOME_Exception );
+ // Copy a part of mesh
+ SMESH::SMESH_Mesh_ptr CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
+ const char* meshName,
+ CORBA::Boolean toCopyGroups,
+ CORBA::Boolean toKeepIDs);
+
// Compute mesh on a shape
CORBA::Boolean Compute( SMESH::SMESH_Mesh_ptr theMesh,
GEOM::GEOM_Object_ptr theShapeObject )
diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx
index d6185e107..13e8d0a39 100644
--- a/src/SMESH_I/SMESH_MeshEditor_i.cxx
+++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx
@@ -5353,7 +5353,7 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
SMESH_Group* smesh_group = 0;
if ( strlen(groupName) )
{
- group_var = mesh_i->CreateGroup( SMESH::ElementType(elemType),groupName);
+ group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
if ( SMESH_GroupBase_i* group_i = SMESH::DownCast( group_var ))
smesh_group = group_i->GetSmeshGroup();
}
@@ -5369,6 +5369,8 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
storeResult( aMeshEditor );
}
+ const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
+
// result of MakeBoundaryMesh() is a tuple (mesh, group)
if ( mesh_var->_is_nil() )
pyDump << myMesh_i->_this() << ", ";
@@ -5380,9 +5382,9 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
pyDump << group_var << " = ";
pyDump << this << ".MakeBoundaryMesh( "
<< idSource << ", "
- << dim << ", "
- << groupName << ", "
- << meshName<< ", "
+ << "SMESH." << dimName[int(dim)] << ", "
+ << "'" << groupName << "', "
+ << "'" << meshName<< "', "
<< toCopyElements << ", "
<< toCopyExistingBondary << ")";
diff --git a/src/SMESH_SWIG/smeshDC.py b/src/SMESH_SWIG/smeshDC.py
index f07cf3c23..cfcb25ec5 100644
--- a/src/SMESH_SWIG/smeshDC.py
+++ b/src/SMESH_SWIG/smeshDC.py
@@ -663,27 +663,6 @@ class smeshDC(SMESH._objref_SMESH_Gen):
aMesh = Mesh(self, self.geompyD, aSmeshMesh)
return aMesh
- ## From SMESH_Gen interface
- # @return the list of integer values
- # @ingroup l1_auxiliary
- def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
- return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
-
- ## From SMESH_Gen interface. Creates a pattern
- # @return an instance of SMESH_Pattern
- #
- # Example of Patterns usage
- # @ingroup l2_modif_patterns
- 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)
-
## Concatenate the given meshes into one mesh.
# @return an instance of Mesh class
# @param meshes the meshes to combine into one mesh
@@ -707,6 +686,41 @@ class smeshDC(SMESH._objref_SMESH_Gen):
aMesh = Mesh(self, self.geompyD, aSmeshMesh)
return aMesh
+ ## Create a mesh by copying a part of another mesh.
+ # @param meshPart a part of mesh to copy, either a Mesh, a sub-mesh or a group;
+ # to copy nodes or elements not contained in any mesh object,
+ # pass result of Mesh.GetIDSource( list_of_ids, type ) as meshPart
+ # @param meshName a name of the new mesh
+ # @param toCopyGroups to create in the new mesh groups the copied elements belongs to
+ # @param toKeepIDs to preserve IDs of the copied elements or not
+ # @return an instance of Mesh class
+ def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
+ if (isinstance( meshPart, Mesh )):
+ meshPart = meshPart.GetMesh()
+ mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
+ return Mesh(self, self.geompyD, mesh)
+
+ ## From SMESH_Gen interface
+ # @return the list of integer values
+ # @ingroup l1_auxiliary
+ def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
+ return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
+
+ ## From SMESH_Gen interface. Creates a pattern
+ # @return an instance of SMESH_Pattern
+ #
+ # Example of Patterns usage
+ # @ingroup l2_modif_patterns
+ 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:
# ------------------------------
@@ -735,6 +749,8 @@ class smeshDC(SMESH._objref_SMESH_Gen):
# @param UnaryOp FT_LogicalNOT or FT_Undefined
# @param BinaryOp a binary logical operation FT_LogicalAND, FT_LogicalOR or
# FT_Undefined (must be for the last criterion of all criteria)
+ # @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface,
+ # FT_LyingOnGeom, FT_CoplanarFaces criteria
# @return SMESH.Filter.Criterion
# @ingroup l1_controls
def GetCriterion(self,elementType,
@@ -742,10 +758,12 @@ class smeshDC(SMESH._objref_SMESH_Gen):
Compare = FT_EqualTo,
Treshold="",
UnaryOp=FT_Undefined,
- BinaryOp=FT_Undefined):
+ BinaryOp=FT_Undefined,
+ Tolerance=1e-07):
aCriterion = self.GetEmptyCriterion()
aCriterion.TypeOfElement = elementType
aCriterion.Type = self.EnumToLong(CritType)
+ aCriterion.Tolerance = Tolerance
aTreshold = Treshold
@@ -810,7 +828,9 @@ class smeshDC(SMESH._objref_SMESH_Gen):
return None
pass
elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_BadOrientedVolume, FT_FreeNodes,
- FT_FreeFaces, FT_LinearOrQuadratic]:
+ FT_FreeFaces, FT_LinearOrQuadratic,
+ FT_BareBorderFace, FT_BareBorderVolume,
+ FT_OverConstrainedFace, FT_OverConstrainedVolume]:
# At this point the treshold is unnecessary
if aTreshold == FT_LogicalNOT:
aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
@@ -845,14 +865,17 @@ class smeshDC(SMESH._objref_SMESH_Gen):
# @param Compare belongs to {FT_LessThan, FT_MoreThan, FT_EqualTo}
# @param Treshold the threshold value (range of id ids as string, shape, numeric)
# @param UnaryOp FT_LogicalNOT or FT_Undefined
+ # @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface,
+ # FT_LyingOnGeom, FT_CoplanarFaces criteria
# @return SMESH_Filter
# @ingroup l1_controls
def GetFilter(self,elementType,
CritType=FT_Undefined,
Compare=FT_EqualTo,
Treshold="",
- UnaryOp=FT_Undefined):
- aCriterion = self.GetCriterion(elementType, CritType, Compare, Treshold, UnaryOp, FT_Undefined)
+ UnaryOp=FT_Undefined,
+ Tolerance=1e-07):
+ aCriterion = self.GetCriterion(elementType, CritType, Compare, Treshold, UnaryOp, FT_Undefined,Tolerance)
aFilterMgr = self.CreateFilterManager()
aFilter = aFilterMgr.CreateFilter()
aCriteria = []
@@ -1744,6 +1767,8 @@ class Mesh:
# @param Compare belongs to {FT_LessThan, FT_MoreThan, FT_EqualTo}
# @param Treshold the threshold value (range of id ids as string, shape, numeric)
# @param UnaryOp FT_LogicalNOT or FT_Undefined
+ # @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface,
+ # FT_LyingOnGeom, FT_CoplanarFaces criteria
# @return SMESH_Group
# @ingroup l2_grps_create
def MakeGroup(self,
@@ -1752,8 +1777,9 @@ class Mesh:
CritType=FT_Undefined,
Compare=FT_EqualTo,
Treshold="",
- UnaryOp=FT_Undefined):
- aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Treshold, UnaryOp, FT_Undefined)
+ UnaryOp=FT_Undefined,
+ Tolerance=1e-07):
+ aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Treshold, UnaryOp, FT_Undefined,Tolerance)
group = self.MakeGroupByCriterion(groupName, aCriterion)
return group
@@ -1969,6 +1995,13 @@ class Mesh:
def GetMeshEditor(self):
return self.mesh.GetMeshEditor()
+ ## Wrap a list of IDs of elements or nodes into SMESH_IDSource which
+ # can be passed as argument to accepting mesh, group or sub-mesh
+ # @return an instance of SMESH_IDSource
+ # @ingroup l1_auxiliary
+ def GetIDSource(self, ids, elemType):
+ return self.GetMeshEditor().MakeIDSource(ids, elemType)
+
## Gets MED Mesh
# @return an instance of SALOME_MED::MESH
# @ingroup l1_auxiliary
@@ -3213,7 +3246,7 @@ class Mesh:
## Generates new elements by extrusion of the elements with given ids
# @param IDsOfElements the list of elements ids for extrusion
- # @param StepVector vector, defining the direction and value of extrusion
+ # @param StepVector vector or DirStruct, defining the direction and value of extrusion
# @param NbOfSteps the number of steps
# @param MakeGroups forces the generation of new groups from existing ones
# @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
@@ -3700,7 +3733,7 @@ class Mesh:
if ( isinstance( theObject, Mesh )):
theObject = theObject.GetMesh()
if ( isinstance( theObject, list )):
- theObject = self.editor.MakeIDSource(theObject, SMESH.ALL)
+ theObject = self.GetIDSource(theObject, SMESH.ALL)
thePoint, Parameters = ParsePointStruct(thePoint)
self.mesh.SetParameters(Parameters)
@@ -3721,7 +3754,7 @@ class Mesh:
if (isinstance(theObject, Mesh)):
theObject = theObject.GetMesh()
if ( isinstance( theObject, list )):
- theObject = self.editor.MakeIDSource(theObject,SMESH.ALL)
+ theObject = self.GetIDSource(theObject,SMESH.ALL)
mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
MakeGroups, NewMeshName)
@@ -3855,7 +3888,7 @@ class Mesh:
if not isinstance( exceptNodes, list):
exceptNodes = [ exceptNodes ]
if exceptNodes and isinstance( exceptNodes[0], int):
- exceptNodes = [ self.editor.MakeIDSource( exceptNodes, SMESH.NODE)]
+ exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE)]
return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,exceptNodes)
## Merges nodes
@@ -4340,8 +4373,11 @@ class Mesh_Algorithm:
pass
self.mesh.smeshpyD.SetName(hypo, hyp + a)
pass
+ geomName=""
+ if self.geom:
+ geomName = GetName(self.geom)
status = self.mesh.mesh.AddHypothesis(self.geom, hypo)
- TreatHypoStatus( status, GetName(hypo), GetName(self.geom), 0 )
+ TreatHypoStatus( status, GetName(hypo), geomName, 0 )
return hypo
## Returns entry of the shape to mesh in the study
@@ -4884,20 +4920,31 @@ class Mesh_Triangle(Mesh_Algorithm):
self.Parameters().SetOptionValue(optionName,level)
## Sets QuadAllowed flag.
- # Only for algoType == NETGEN || NETGEN_2D || BLSURF
+ # Only for algoType == NETGEN(NETGEN_1D2D) || NETGEN_2D || BLSURF
# @ingroup l3_hypos_netgen l3_hypos_blsurf
def SetQuadAllowed(self, toAllow=True):
if self.algoType == NETGEN_2D:
- if toAllow: # add QuadranglePreference
- self.Hypothesis("QuadranglePreference", UseExisting=1, CompareMethod=self.CompareEqualHyp)
- else: # remove QuadranglePreference
+ if not self.params:
+ # use simple hyps
+ hasSimpleHyps = False
+ simpleHyps = ["QuadranglePreference","LengthFromEdges","MaxElementArea"]
for hyp in self.mesh.GetHypothesisList( self.geom ):
- if hyp.GetName() == "QuadranglePreference":
- self.mesh.RemoveHypothesis( self.geom, hyp )
+ if hyp.GetName() in simpleHyps:
+ hasSimpleHyps = True
+ if hyp.GetName() == "QuadranglePreference":
+ if not toAllow: # remove QuadranglePreference
+ self.mesh.RemoveHypothesis( self.geom, hyp )
+ pass
+ return
pass
pass
+ if hasSimpleHyps:
+ if toAllow: # add QuadranglePreference
+ self.Hypothesis("QuadranglePreference", UseExisting=1, CompareMethod=self.CompareEqualHyp)
+ pass
+ return
pass
- return
+ pass
if self.Parameters():
self.params.SetQuadAllowed(toAllow)
return
@@ -4906,30 +4953,25 @@ class Mesh_Triangle(Mesh_Algorithm):
#
# @ingroup l3_hypos_netgen
def Parameters(self, which=SOLE):
- if self.params:
- return self.params
- if self.algoType == NETGEN:
- if which == SIMPLE:
- self.params = self.Hypothesis("NETGEN_SimpleParameters_2D", [],
+ if not self.params:
+ if self.algoType == NETGEN:
+ if which == SIMPLE:
+ self.params = self.Hypothesis("NETGEN_SimpleParameters_2D", [],
+ "libNETGENEngine.so", UseExisting=0)
+ else:
+ self.params = self.Hypothesis("NETGEN_Parameters_2D", [],
+ "libNETGENEngine.so", UseExisting=0)
+ elif self.algoType == MEFISTO:
+ print "Mefisto algo support no multi-parameter hypothesis"
+ elif self.algoType == NETGEN_2D:
+ self.params = self.Hypothesis("NETGEN_Parameters_2D_ONLY", [],
"libNETGENEngine.so", UseExisting=0)
+ elif self.algoType == BLSURF:
+ self.params = self.Hypothesis("BLSURF_Parameters", [],
+ "libBLSURFEngine.so", UseExisting=0)
else:
- self.params = self.Hypothesis("NETGEN_Parameters_2D", [],
- "libNETGENEngine.so", UseExisting=0)
- return self.params
- elif self.algoType == MEFISTO:
- print "Mefisto algo support no multi-parameter hypothesis"
- return None
- elif self.algoType == NETGEN_2D:
- print "NETGEN_2D_ONLY algo support no multi-parameter hypothesis"
- print "NETGEN_2D_ONLY uses 'MaxElementArea' and 'LengthFromEdges' ones"
- return None
- elif self.algoType == BLSURF:
- self.params = self.Hypothesis("BLSURF_Parameters", [],
- "libBLSURFEngine.so", UseExisting=0)
- return self.params
- else:
- print "Mesh_Triangle with algo type %s does not have such a parameter, check algo type"%self.algoType
- return None
+ print "Mesh_Triangle with algo type %s does not have such a parameter, check algo type"%self.algoType
+ return self.params
## Sets MaxSize
#
@@ -5166,33 +5208,34 @@ class Mesh_Tetrahedron(Mesh_Algorithm):
#
# @ingroup l3_hypos_netgen
def Parameters(self, which=SOLE):
- if self.params:
- return self.params
+ if not self.params:
- if self.algoType == FULL_NETGEN:
- if which == SIMPLE:
- self.params = self.Hypothesis("NETGEN_SimpleParameters_3D", [],
+ if self.algoType == FULL_NETGEN:
+ if which == SIMPLE:
+ self.params = self.Hypothesis("NETGEN_SimpleParameters_3D", [],
+ "libNETGENEngine.so", UseExisting=0)
+ else:
+ self.params = self.Hypothesis("NETGEN_Parameters", [],
+ "libNETGENEngine.so", UseExisting=0)
+
+ if self.algoType == NETGEN:
+ self.params = self.Hypothesis("NETGEN_Parameters_3D", [],
"libNETGENEngine.so", UseExisting=0)
+
+ elif self.algoType == GHS3D:
+ self.params = self.Hypothesis("GHS3D_Parameters", [],
+ "libGHS3DEngine.so", UseExisting=0)
+
+ elif self.algoType == GHS3DPRL:
+ self.params = self.Hypothesis("GHS3DPRL_Parameters", [],
+ "libGHS3DPRLEngine.so", UseExisting=0)
else:
- self.params = self.Hypothesis("NETGEN_Parameters", [],
- "libNETGENEngine.so", UseExisting=0)
- return self.params
+ print "Algo supports no multi-parameter hypothesis"
- if self.algoType == GHS3D:
- self.params = self.Hypothesis("GHS3D_Parameters", [],
- "libGHS3DEngine.so", UseExisting=0)
- return self.params
-
- if self.algoType == GHS3DPRL:
- self.params = self.Hypothesis("GHS3DPRL_Parameters", [],
- "libGHS3DPRLEngine.so", UseExisting=0)
- return self.params
-
- print "Algo supports no multi-parameter hypothesis"
- return None
+ return self.params
## Sets MaxSize
- # Parameter of FULL_NETGEN
+ # Parameter of FULL_NETGEN and NETGEN
# @ingroup l3_hypos_netgen
def SetMaxSize(self, theSize):
self.Parameters().SetMaxSize(theSize)
@@ -5204,7 +5247,7 @@ class Mesh_Tetrahedron(Mesh_Algorithm):
self.Parameters().SetSecondOrder(theVal)
## Sets Optimize flag
- # Parameter of FULL_NETGEN
+ # Parameter of FULL_NETGEN and NETGEN
# @ingroup l3_hypos_netgen
def SetOptimize(self, theVal):
self.Parameters().SetOptimize(theVal)
diff --git a/src/StdMeshers/StdMeshers_Import_1D.cxx b/src/StdMeshers/StdMeshers_Import_1D.cxx
index b3dac25ab..9f4759a59 100644
--- a/src/StdMeshers/StdMeshers_Import_1D.cxx
+++ b/src/StdMeshers/StdMeshers_Import_1D.cxx
@@ -120,6 +120,7 @@ namespace // INTERNAL STUFF
enum _ListenerDataType
{
WAIT_HYP_MODIF=1, // data indicating awaiting for valid parameters of src hyp
+ LISTEN_SRC_MESH, // data storing submesh depending on source mesh state
SRC_HYP // data storing ImportSource hyp
};
//================================================================================
@@ -130,10 +131,29 @@ namespace // INTERNAL STUFF
struct _ListenerData : public SMESH_subMeshEventListenerData
{
const StdMeshers_ImportSource1D* _srcHyp;
- _ListenerData(const StdMeshers_ImportSource1D* h):
+ _ListenerData(const StdMeshers_ImportSource1D* h, _ListenerDataType type=SRC_HYP):
SMESH_subMeshEventListenerData(/*isDeletable=*/true), _srcHyp(h)
{
- myType = SRC_HYP;
+ myType = type;
+ }
+ };
+ //================================================================================
+ /*!
+ * \brief Comparator of sub-meshes
+ */
+ struct _SubLess
+ {
+ bool operator()(const SMESH_subMesh* sm1, const SMESH_subMesh* sm2 ) const
+ {
+ if ( sm1 == sm2 ) return false;
+ if ( !sm1 || !sm2 ) return sm1 < sm2;
+ const TopoDS_Shape& s1 = sm1->GetSubShape();
+ const TopoDS_Shape& s2 = sm2->GetSubShape();
+ TopAbs_ShapeEnum t1 = s1.IsNull() ? TopAbs_SHAPE : s1.ShapeType();
+ TopAbs_ShapeEnum t2 = s2.IsNull() ? TopAbs_SHAPE : s2.ShapeType();
+ if ( t1 == t2)
+ return (sm1 < sm2);
+ return t1 < t2; // to have: face < edge
}
};
//================================================================================
@@ -146,10 +166,10 @@ namespace // INTERNAL STUFF
StdMeshers_Import_1D::TNodeNodeMap _n2n;
StdMeshers_Import_1D::TElemElemMap _e2e;
- set< SMESH_subMesh*> _subM; // submeshes relating to this srcMesh
- set< SMESH_subMesh*> _copyMeshSubM; // submeshes requesting mesh copying
- set< SMESH_subMesh*> _copyGroupSubM; // submeshes requesting mesh copying
- set< SMESH_subMesh*> _computedSubM;
+ set< SMESH_subMesh*, _SubLess > _subM; // submeshes relating to this srcMesh
+ set< SMESH_subMesh*, _SubLess > _copyMeshSubM; // submeshes requesting mesh copying
+ set< SMESH_subMesh*, _SubLess > _copyGroupSubM; // submeshes requesting mesh copying
+ set< SMESH_subMesh*, _SubLess > _computedSubM;
SMESHDS_SubMesh* _importMeshSubDS; // submesh storing a copy of _srcMesh
int _importMeshSubID; // id of _importMeshSubDS
@@ -196,10 +216,30 @@ namespace // INTERNAL STUFF
if ( toCopyGroups ) _copyGroupSubM.insert( sm );
else _copyGroupSubM.erase( sm );
}
+ void addComputed( SMESH_subMesh* sm )
+ {
+ SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
+ /*complexShapeFirst=*/true);
+ while ( smIt->more() )
+ {
+ sm = smIt->next();
+ switch ( sm->GetSubShape().ShapeType() )
+ {
+ case TopAbs_EDGE:
+ case TopAbs_FACE:
+ _subM.insert( sm );
+ if ( !sm->IsEmpty() )
+ _computedSubM.insert( sm );
+ case TopAbs_VERTEX:
+ break;
+ default:;
+ }
+ }
+ }
};
//================================================================================
/*!
- * Listener notified on events of an imported submesh
+ * Listener notified on events relating to imported submesh
*/
class _Listener : public SMESH_subMeshEventListener
{
@@ -212,198 +252,248 @@ namespace // INTERNAL STUFF
// return poiter to a static listener
static _Listener* get() { static _Listener theListener; return &theListener; }
- //--------------------------------------------------------------------------------
- /*!
- * \brief Find or create ImportData for given meshes
- */
- static _ImportData* getImportData(const SMESH_Mesh* srcMesh,
- SMESH_Mesh* tgtMesh)
- {
- list< _ImportData >& dList = get()->_tgtMesh2ImportData[tgtMesh];
- list< _ImportData >::iterator d = dList.begin();
- for ( ; d != dList.end(); ++d )
- if ( d->_srcMesh == srcMesh )
- return &*d;
- dList.push_back(_ImportData(srcMesh));
- return &dList.back();
- }
+ static _ImportData* getImportData(const SMESH_Mesh* srcMesh, SMESH_Mesh* tgtMesh);
- //--------------------------------------------------------------------------------
- /*!
- * \brief Remember an imported mesh and groups
- * \param smDS - submesh DS holding the imported mesh
- * \param sm - submesh computed by Import algo
- * \param srcMeshDS - source mesh
- * \param srcHyp - ImportSource hypothesis
- */
- static _ImportData* storeImportSubmesh(SMESH_subMesh* importSub,
- const SMESH_Mesh* srcMesh,
- const StdMeshers_ImportSource1D* srcHyp)
- {
- // set listener to hear events of the submesh computed by "Import" algo
- importSub->SetEventListener( get(), new _ListenerData(srcHyp), importSub );
+ static void storeImportSubmesh(SMESH_subMesh* importSub,
+ const SMESH_Mesh* srcMesh,
+ const StdMeshers_ImportSource1D* srcHyp);
- // set a listener to hear events of the source mesh
- SMESH_subMesh* smToNotify = importSub;
- SMESH_subMesh* smToListen = srcMesh->GetSubMeshContaining(1);
- importSub->SetEventListener
- ( new SMESH_subMeshEventListener(/*isDeletable=*/true),
- SMESH_subMeshEventListenerData::MakeData( smToNotify ),
- smToListen );
+ virtual void ProcessEvent(const int event,
+ const int eventType,
+ SMESH_subMesh* subMesh,
+ SMESH_subMeshEventListenerData* data,
+ const SMESH_Hypothesis* hyp);
+ void removeSubmesh( SMESH_subMesh* sm, _ListenerData* data );
+ void clearSubmesh ( SMESH_subMesh* sm, _ListenerData* data, bool clearAllSub );
- // remeber the submesh
- _ImportData* iData = _Listener::getImportData( srcMesh, importSub->GetFather());
- iData->_subM.insert( importSub );
- iData->trackHypParams( importSub, srcHyp );
- if ( !importSub->IsEmpty() )
- iData->_computedSubM.insert( importSub );
- if ( !iData->_copyMeshSubM.empty() && iData->_importMeshSubID < 1 )
- {
- SMESH_Mesh* tgtMesh = importSub->GetFather();
- iData->_importMeshSubID = getSubmeshIDForCopiedMesh( srcMesh->GetMeshDS(),tgtMesh);
- iData->_importMeshSubDS = tgtMesh->GetMeshDS()->NewSubMesh( iData->_importMeshSubID );
- }
- if ( !importSub->IsEmpty() )
- iData->_computedSubM.insert( importSub );
-
- return iData;
- }
- //--------------------------------------------------------------------------------
- /*!
- * \brief mark sm as missing src hyp with valid groups
- */
+ // mark sm as missing src hyp with valid groups
static void waitHypModification(SMESH_subMesh* sm)
{
sm->SetEventListener
(get(), SMESH_subMeshEventListenerData::MakeData( sm, WAIT_HYP_MODIF ), sm);
}
+ };
+ //--------------------------------------------------------------------------------
+ /*!
+ * \brief Find or create ImportData for given meshes
+ */
+ _ImportData* _Listener::getImportData(const SMESH_Mesh* srcMesh,
+ SMESH_Mesh* tgtMesh)
+ {
+ list< _ImportData >& dList = get()->_tgtMesh2ImportData[tgtMesh];
+ list< _ImportData >::iterator d = dList.begin();
+ for ( ; d != dList.end(); ++d )
+ if ( d->_srcMesh == srcMesh )
+ return &*d;
+ dList.push_back(_ImportData(srcMesh));
+ return &dList.back();
+ }
- //--------------------------------------------------------------------------------
- /*!
- * \brief Remove imported mesh and/or groups as soon as no more imported submeshes
- * remain computed
- * \param sm - submesh loosing Import algo
- * \param data - data holding imported groups
- */
- void removeSubmesh( SMESH_subMesh* sm, _ListenerData* data )
+ //--------------------------------------------------------------------------------
+ /*!
+ * \brief Remember an imported sub-mesh and set needed even listeners
+ * \param importSub - submesh computed by Import algo
+ * \param srcMesh - source mesh
+ * \param srcHyp - ImportSource hypothesis
+ */
+ void _Listener::storeImportSubmesh(SMESH_subMesh* importSub,
+ const SMESH_Mesh* srcMesh,
+ const StdMeshers_ImportSource1D* srcHyp)
+ {
+ // set listener to hear events of the submesh computed by "Import" algo
+ importSub->SetEventListener( get(), new _ListenerData(srcHyp), importSub );
+
+ // set a listener to hear events of the source mesh
+ SMESH_subMesh* smToNotify = importSub;
+ SMESH_subMesh* smToListen = srcMesh->GetSubMeshContaining(1);
+ SMESH_subMeshEventListenerData* data = new _ListenerData(srcHyp, LISTEN_SRC_MESH);
+ data->mySubMeshes.push_back( smToNotify );
+ importSub->SetEventListener( get(), data, smToListen );
+
+ // remeber the submesh importSub and its sub-submeshes
+ _ImportData* iData = _Listener::getImportData( srcMesh, importSub->GetFather());
+ iData->trackHypParams( importSub, srcHyp );
+ iData->addComputed( importSub );
+ if ( !iData->_copyMeshSubM.empty() && iData->_importMeshSubID < 1 )
{
- list< _ImportData > & dList = _tgtMesh2ImportData[ sm->GetFather() ];
- list< _ImportData >::iterator d = dList.begin();
- for ( ; d != dList.end(); ++d )
- if ( (*d)._subM.erase( sm ))
- {
- d->_computedSubM.erase( sm );
- bool rmMesh = d->_copyMeshSubM.erase( sm ) && d->_copyMeshSubM.empty();
- bool rmGroups = (d->_copyGroupSubM.erase( sm ) && d->_copyGroupSubM.empty()) || rmMesh;
- if ( rmMesh )
- d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
- if ( rmGroups && data )
- d->removeGroups( sm, data->_srcHyp );
- }
+ SMESH_Mesh* tgtMesh = importSub->GetFather();
+ iData->_importMeshSubID = getSubmeshIDForCopiedMesh( srcMesh->GetMeshDS(),tgtMesh);
+ iData->_importMeshSubDS = tgtMesh->GetMeshDS()->NewSubMesh( iData->_importMeshSubID );
}
- //--------------------------------------------------------------------------------
- /*!
- * \brief Remove imported mesh and/or groups and
- * clear all submeshes with common source mesh
- * \param sm - cleared submesh
- * \param data - data holding imported groups
- */
- void clearSubmesh( SMESH_subMesh* sm, _ListenerData* data )
- {
- list< _ImportData > & dList = _tgtMesh2ImportData[ sm->GetFather() ];
- list< _ImportData >::iterator d = dList.begin();
- for ( ; d != dList.end(); ++d )
+ }
+ //--------------------------------------------------------------------------------
+ /*!
+ * \brief Remove imported mesh and/or groups if needed
+ * \param sm - submesh loosing Import algo
+ * \param data - data holding imported groups
+ */
+ void _Listener::removeSubmesh( SMESH_subMesh* sm, _ListenerData* data )
+ {
+ list< _ImportData > & dList = _tgtMesh2ImportData[ sm->GetFather() ];
+ list< _ImportData >::iterator d = dList.begin();
+ for ( ; d != dList.end(); ++d )
+ if ( (*d)._subM.erase( sm ))
{
- if ( !d->_subM.count( sm )) continue;
- if ( (*d)._computedSubM.erase( sm ) )
+ d->_computedSubM.erase( sm );
+ bool rmMesh = d->_copyMeshSubM.erase( sm ) && d->_copyMeshSubM.empty();
+ bool rmGroups = (d->_copyGroupSubM.erase( sm ) && d->_copyGroupSubM.empty()) || rmMesh;
+ if ( rmMesh )
+ d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
+ if ( rmGroups && data )
+ d->removeGroups( sm, data->_srcHyp );
+ }
+ }
+ //--------------------------------------------------------------------------------
+ /*!
+ * \brief Clear submeshes and remove imported mesh and/or groups if necessary
+ * \param sm - cleared submesh
+ * \param data - data holding imported groups
+ */
+ void _Listener::clearSubmesh(SMESH_subMesh* sm, _ListenerData* data, bool clearAllSub)
+ {
+ list< _ImportData > & dList = _tgtMesh2ImportData[ sm->GetFather() ];
+ list< _ImportData >::iterator d = dList.begin();
+ for ( ; d != dList.end(); ++d )
+ {
+ if ( !d->_subM.count( sm )) continue;
+ if ( (*d)._computedSubM.erase( sm ) )
+ {
+ bool copyMesh = !d->_copyMeshSubM.empty();
+ if ( copyMesh || clearAllSub )
{
- bool copyMesh = !d->_copyMeshSubM.empty();
- if ( copyMesh )
- {
- // clear submeshes
- if ( !d->_computedSubM.empty() )
- {
- set< SMESH_subMesh*> subs;
- subs.swap( d->_computedSubM ); // avoid recursion via events
- while ( !subs.empty() )
- {
- SMESH_subMesh* subM = *subs.begin(); subs.erase( subs.begin() );
- _ListenerData* hypData = (_ListenerData*) subM->GetEventListenerData( get() );
- if ( hypData )
- d->removeGroups( sm, hypData->_srcHyp );
-
- subM->ComputeStateEngine( SMESH_subMesh::CLEAN );
- }
- }
- // remove imported mesh and groups
- d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
+ // remove imported mesh and groups
+ d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
- if ( data )
- d->removeGroups( sm, data->_srcHyp );
+ if ( data )
+ d->removeGroups( sm, data->_srcHyp );
+
+ // clear the rest submeshes
+ if ( !d->_computedSubM.empty() )
+ {
+ set< SMESH_subMesh*, _SubLess> subs;
+ subs.swap( d->_computedSubM ); // avoid recursion via events
+ while ( !subs.empty() )
+ {
+ SMESH_subMesh* subM = *subs.begin(); subs.erase( subs.begin() );
+ _ListenerData* hypData = (_ListenerData*) subM->GetEventListenerData( get() );
+ if ( hypData )
+ d->removeGroups( sm, hypData->_srcHyp );
+
+ subM->ComputeStateEngine( SMESH_subMesh::CLEAN );
+ if ( subM->GetSubShape().ShapeType() == TopAbs_FACE )
+ subM->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
+ }
}
}
- if ( data )
- d->trackHypParams( sm, data->_srcHyp );
- d->_n2n.clear();
- d->_e2e.clear();
+ sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
+ if ( sm->GetSubShape().ShapeType() == TopAbs_FACE )
+ sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
+ }
+ if ( data )
+ d->trackHypParams( sm, data->_srcHyp );
+ d->_n2n.clear();
+ d->_e2e.clear();
+ }
+ }
+ //--------------------------------------------------------------------------------
+ /*!
+ * \brief Remove imported mesh and/or groups
+ */
+ void _Listener::ProcessEvent(const int event,
+ const int eventType,
+ SMESH_subMesh* subMesh,
+ SMESH_subMeshEventListenerData* data,
+ const SMESH_Hypothesis* /*hyp*/)
+ {
+ if ( data && data->myType == WAIT_HYP_MODIF )
+ {
+ // event of Import submesh
+ if ( SMESH_subMesh::MODIF_HYP == event &&
+ SMESH_subMesh::ALGO_EVENT == eventType )
+ {
+ // re-call SetEventListener() to take into account valid parameters
+ // of ImportSource hypothesis
+ SMESH_Gen* gen = subMesh->GetFather()->GetGen();
+ if ( SMESH_Algo* algo = gen->GetAlgo(*subMesh->GetFather(), subMesh->GetSubShape()))
+ algo->SetEventListener( subMesh );
}
}
- //--------------------------------------------------------------------------------
- /*!
- * \brief Remove imported mesh and/or groups
- */
- virtual void ProcessEvent(const int event,
- const int eventType,
- SMESH_subMesh* subMesh,
- SMESH_subMeshEventListenerData* data,
- const SMESH_Hypothesis* /*hyp*/)
+ else if ( data && data->myType == LISTEN_SRC_MESH )
{
- if ( data && data->myType == WAIT_HYP_MODIF )
+ // event of source mesh
+ if ( SMESH_subMesh::COMPUTE_EVENT == eventType )
{
- if ( SMESH_subMesh::MODIF_HYP == event &&
- SMESH_subMesh::ALGO_EVENT == eventType )
- {
- SMESH_Gen* gen = subMesh->GetFather()->GetGen();
- if ( SMESH_Algo* algo = gen->GetAlgo(*subMesh->GetFather(), subMesh->GetSubShape()))
- algo->SetEventListener( subMesh );
+ switch ( event ) {
+ case SMESH_subMesh::CLEAN:
+ // source mesh cleaned -> clean target mesh
+ clearSubmesh( data->mySubMeshes.front(), (_ListenerData*) data, /*all=*/true );
+ break;
+ case SMESH_subMesh::SUBMESH_COMPUTED: {
+ // source mesh computed -> reset FAILED state of Import submeshes to
+ // READY_TO_COMPUTE
+ SMESH_Mesh* srcMesh = subMesh->GetFather();
+ if ( srcMesh->NbEdges() > 0 || srcMesh->NbFaces() > 0 )
+ {
+ SMESH_Mesh* m = data->mySubMeshes.front()->GetFather();
+ if ( SMESH_subMesh* sm1 = m->GetSubMeshContaining(1))
+ {
+ sm1->ComputeStateEngine(SMESH_subMesh::SUBMESH_COMPUTED );
+ sm1->ComputeSubMeshStateEngine( SMESH_subMesh::SUBMESH_COMPUTED );
+ }
+ }
+ break;
+ }
+ default:;
}
}
- else
+ }
+ else // event of Import submesh
+ {
+ // find out what happens: import hyp modified or removed
+ bool removeImport = false, modifHyp = false;
+ if ( SMESH_subMesh::ALGO_EVENT == eventType )
+ modifHyp = true;
+ if ( subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK )
+ {
+ removeImport = true;
+ }
+ else if ( SMESH_subMesh::REMOVE_ALGO == event ||
+ SMESH_subMesh::REMOVE_FATHER_ALGO == event )
{
SMESH_Gen* gen = subMesh->GetFather()->GetGen();
SMESH_Algo* algo = gen->GetAlgo(*subMesh->GetFather(),subMesh->GetSubShape() );
+ removeImport = ( strncmp( "Import", algo->GetName(), 6 ) != 0 );
+ }
- if ( subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK ||
- strncmp( "Import", algo->GetName(), 6 ) != 0 )
- {
- // treate removal of Import algo from subMesh
- removeSubmesh( subMesh, (_ListenerData*) data );
- }
- else if ( subMesh->IsEmpty() )
- {
- // treate modification of ImportSource hypothesis
- clearSubmesh( subMesh, (_ListenerData*) data );
- }
- else if ( SMESH_subMesh::CHECK_COMPUTE_STATE == event &&
- SMESH_subMesh::COMPUTE_EVENT == eventType )
- {
- // check compute state of all submeshes impoting from same src mesh;
- // this is to take into account 1D computed submeshes hidden by 2D import algo;
- // else source mesh is not copied as _subM.size != _computedSubM.size()
- list< _ImportData > & dList = _tgtMesh2ImportData[ subMesh->GetFather() ];
- list< _ImportData >::iterator d = dList.begin();
- for ( ; d != dList.end(); ++d )
- if ( d->_subM.count( subMesh ))
- {
- set::iterator smIt = d->_subM.begin();
- for( ; smIt != d->_subM.end(); ++smIt )
- if ( (*smIt)->IsMeshComputed() )
- d->_computedSubM.insert( *smIt);
- }
- }
+ if ( removeImport )
+ {
+ // treate removal of Import algo from subMesh
+ removeSubmesh( subMesh, (_ListenerData*) data );
+ }
+ else if ( modifHyp )
+ {
+ // treate modification of ImportSource hypothesis
+ clearSubmesh( subMesh, (_ListenerData*) data, /*all=*/false );
+ }
+ else if ( SMESH_subMesh::CHECK_COMPUTE_STATE == event &&
+ SMESH_subMesh::COMPUTE_EVENT == eventType )
+ {
+ // check compute state of all submeshes impoting from same src mesh;
+ // this is to take into account 1D computed submeshes hidden by 2D import algo;
+ // else source mesh is not copied as _subM.size != _computedSubM.size()
+ list< _ImportData > & dList = _tgtMesh2ImportData[ subMesh->GetFather() ];
+ list< _ImportData >::iterator d = dList.begin();
+ for ( ; d != dList.end(); ++d )
+ if ( d->_subM.count( subMesh ))
+ {
+ set::iterator smIt = d->_subM.begin();
+ for( ; smIt != d->_subM.end(); ++smIt )
+ if ( (*smIt)->IsMeshComputed() )
+ d->_computedSubM.insert( *smIt);
+ }
}
}
- }; // class _Listener
+ }
//================================================================================
/*!
@@ -495,7 +585,7 @@ namespace // INTERNAL STUFF
_ImportData* iData = _Listener::getImportData(srcMesh,tgtMesh);
SMESH_subMesh* importedSM = tgtMesh->GetSubMesh( tgtShape );
- iData->_computedSubM.insert( importedSM );
+ iData->addComputed( importedSM );
if ( iData->_computedSubM.size() != iData->_subM.size() )
return 0; // not all submeshes computed yet
@@ -543,8 +633,8 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th
subShapeIDs.insert( shapeID );
// get nodes on vertices
- list < SMESH_MeshEditor::TNodeXYZ > vertexNodes;
- list < SMESH_MeshEditor::TNodeXYZ >::iterator vNIt;
+ list < SMESH_MeshEditor::TNodeXYZ > vertexNodes;
+ list < SMESH_MeshEditor::TNodeXYZ >::iterator vNIt;
TopExp_Explorer vExp( theShape, TopAbs_VERTEX );
for ( ; vExp.More(); vExp.Next() )
{
diff --git a/src/StdMeshers/StdMeshers_Import_1D2D.cxx b/src/StdMeshers/StdMeshers_Import_1D2D.cxx
index 5d89cd128..2d98c671f 100644
--- a/src/StdMeshers/StdMeshers_Import_1D2D.cxx
+++ b/src/StdMeshers/StdMeshers_Import_1D2D.cxx
@@ -153,8 +153,8 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
const bool toCheckOri = (helper.NbAncestors( geomFace, theMesh, TopAbs_SOLID ) == 1 );
Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace );
- if ( helper.GetSubShapeOri( tgtMesh->ShapeToMesh(), geomFace) == TopAbs_REVERSED )
- surface->UReverse();
+ const bool reverse =
+ ( helper.GetSubShapeOri( tgtMesh->ShapeToMesh(), geomFace) == TopAbs_REVERSED );
gp_Pnt p; gp_Vec du, dv;
set subShapeIDs;
@@ -262,7 +262,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
{
uv = helper.GetNodeUV( geomFace, newNodes[++iNode] );
surface->D1( uv.X(),uv.Y(), p, du,dv );
- geomNorm = du ^ dv;
+ geomNorm = reverse ? dv^du : du^dv;
}
while ( geomNorm.SquareMagnitude() < 1e-6 && iNode+1 < face->NbCornerNodes());
@@ -341,7 +341,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
int nbFaces = link2Nb->second;
if ( nbFaces == 1 )
{
- // check if the link lie on face boundary
+ // check if a not shared link lie on face boundary
bool nodesOnBoundary = true;
list< TopoDS_Shape > bndShapes;
for ( int is1stN = 0; is1stN < 2 && nodesOnBoundary; ++is1stN )
@@ -356,6 +356,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
if ( Abs(u-f) < 2 * faceTol || Abs(u-l) < 2 * faceTol )
// duplicated node on vertex
return error("Source elements overlap one another");
+ tgtSM->RemoveNode( n, /*isNodeDeleted=*/false );
tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)n, edges[iE], u );
break;
}
@@ -371,10 +372,10 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
}
}
if ( !nodesOnBoundary )
- break; // free internal link
+ break; // error: free internal link
if ( bndShapes.front().ShapeType() == TopAbs_EDGE &&
bndShapes.front() != bndShapes.back() )
- break; // link nodes on different geom edges
+ break; // error: link nodes on different geom edges
// find geom edge the link is on
if ( bndShapes.back().ShapeType() != TopAbs_EDGE )
@@ -389,7 +390,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
geomEdge.Nullify();
}
if ( geomEdge.IsNull() )
- break; // vertices belong to different edges -> free internal link
+ break; // vertices belong to different edges -> error: free internal link
bndShapes.push_back( geomEdge );
}
@@ -407,15 +408,13 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
TopoDS_Edge geomEdge = TopoDS::Edge(bndShapes.back());
helper.CheckNodeU( geomEdge, link._medium, u, 10*faceTol, /*force=*/true );
+ tgtSM->RemoveNode( link._medium, /*isNodeDeleted=*/false );
tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)link._medium, geomEdge, u );
}
else
{
edge = tgtMesh->AddEdge( newNodes[0], newNodes[1]);
}
- // remove nodes from submesh of theShape
- for ( unsigned i = 0; i < newNodes.size(); ++i )
- tgtSM->RemoveNode( newNodes[i], /*isNodeDeleted=*/false );
if ( !edge )
return false;
diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx
index 86edbacfd..7749da81c 100644
--- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx
+++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx
@@ -1082,6 +1082,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
TopTools_IndexedMapOfShape vMap1, vMap2;
TopExp::MapShapes( theShape1, TopAbs_VERTEX, vMap1 );
TopExp::MapShapes( theShape2, TopAbs_VERTEX, vMap2 );
+ TopoDS_Vertex VV1[2], VV2[2];
if ( vMap1.Extent() != vMap2.Extent() )
RETURN_BAD_RESULT("Different nb of vertices");
@@ -1095,6 +1096,32 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
return FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap);
}
+ // Try to associate by common vertices of an edge
+ for ( int i = 1; i <= vMap1.Extent(); ++i )
+ {
+ const TopoDS_Shape& v1 = vMap1(i);
+ if ( vMap2.Contains( v1 ))
+ {
+ // find an egde sharing v1 and sharing at the same time another common vertex
+ PShapeIteratorPtr edgeIt = SMESH_MesherHelper::GetAncestors( v1, *theMesh1, TopAbs_EDGE);
+ bool edgeFound = false;
+ while ( edgeIt->more() && !edgeFound )
+ {
+ TopoDS_Edge edge = TopoDS::Edge( edgeIt->next()->Oriented(TopAbs_FORWARD));
+ TopExp::Vertices(edge, VV1[0], VV1[1]);
+ if ( !VV1[0].IsSame( VV1[1] ))
+ edgeFound = ( vMap2.Contains( VV1[ v1.IsSame(VV1[0]) ? 1:0]));
+ }
+ if ( edgeFound )
+ {
+ InsertAssociation( VV1[0], VV1[0], theMap, bidirect );
+ InsertAssociation( VV1[1], VV1[1], theMap, bidirect );
+ if (FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap ))
+ return true;
+ }
+ }
+ }
+
// Find transformation to make the shapes be of similar size at same location
Bnd_Box box[2];
@@ -1116,7 +1143,6 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
// Find 2 closest vertices
- TopoDS_Vertex VV1[2], VV2[2];
// get 2 linked vertices of shape 1 not belonging to an inner wire of a face
TopoDS_Shape edge = theShape1;
TopExp_Explorer expF( theShape1, TopAbs_FACE ), expE;