Salome HOME
IPAL54364: Add Gravity Center measurement
[modules/smesh.git] / src / SMESH_SWIG / smeshBuilder.py
index 5b94cd28d9a4c294bf24914b3cb5c63bc7462608..270d5946bf631382e392f4febd7163d812c59347 100644 (file)
@@ -966,6 +966,8 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
             functor = aFilterMgr.CreateLength()
         elif theCriterion == FT_Length2D:
             functor = aFilterMgr.CreateLength2D()
+        elif theCriterion == FT_Deflection2D:
+            functor = aFilterMgr.CreateDeflection2D()
         elif theCriterion == FT_NodeConnectivityNumber:
             functor = aFilterMgr.CreateNodeConnectivityNumber()
         elif theCriterion == FT_BallDiameter:
@@ -1153,6 +1155,18 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
         aMeasurements.UnRegister()
         return value
 
+    ## Get gravity center of all nodes of the mesh object.
+    #  @param obj mesh, submesh or group
+    #  @return three components of the gravity center: x,y,z
+    #  @ingroup l1_measurements
+    def GetGravityCenter(self, obj):
+        if isinstance(obj, Mesh): obj = obj.mesh
+        if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
+        aMeasurements = self.CreateMeasurements()
+        pointStruct = aMeasurements.GravityCenter(obj)
+        aMeasurements.UnRegister()
+        return pointStruct.x, pointStruct.y, pointStruct.z
+
     pass # end of class smeshBuilder
 
 import omniORB
@@ -1793,9 +1807,14 @@ class Mesh:
     #  @param auto_groups boolean parameter for creating/not creating
     #  the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
     #  the typical use is auto_groups=False.
-    #  @param version MED format version (MED_V2_1 or MED_V2_2,
-    #                 the latter meaning any current version). The parameter is
-    #                 obsolete since MED_V2_1 is no longer supported.
+    #  @param version MED format version
+    #         - MED_V2_1 is obsolete.
+    #         - MED_V2_2 means current version (kept for compatibility reasons)
+    #         - MED_LATEST means current version.
+    #         - MED_MINOR_x where x from 0 to 9 indicates the minor version of MED
+    #           to use for writing MED files, for backward compatibility :
+    #           for instance, with SALOME 8.4 use MED 3.2 (minor=2) instead of 3.3,
+    #           to allow the file to be read with SALOME 8.3.
     #  @param overwrite boolean parameter for overwriting/not overwriting the file
     #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
     #  @param autoDimension if @c True (default), a space dimension of a MED mesh can be either
@@ -1811,7 +1830,7 @@ class Mesh:
     #         - 'f' stands for "_faces _" field;
     #         - 's' stands for "_solids _" field.
     #  @ingroup l2_impexp
-    def ExportMED(self, f, auto_groups=0, version=MED_V2_2,
+    def ExportMED(self, f, auto_groups=0, version=MED_LATEST,
                   overwrite=1, meshPart=None, autoDimension=True, fields=[], geomAssocFields=''):
         if meshPart or fields or geomAssocFields:
             unRegister = genObjUnRegister()
@@ -1879,8 +1898,11 @@ class Mesh:
     #  @param f is the file name
     #  @param overwrite boolean parameter for overwriting/not overwriting the file
     #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
+    #  @param groupElemsByType if true all elements of same entity type are exported at ones,
+    #         else elements are exported in order of their IDs which can cause creation
+    #         of multiple cgns sections
     #  @ingroup l2_impexp
-    def ExportCGNS(self, f, overwrite=1, meshPart=None):
+    def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
         unRegister = genObjUnRegister()
         if isinstance( meshPart, list ):
             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
@@ -1889,7 +1911,7 @@ class Mesh:
             meshPart = meshPart.mesh
         elif not meshPart:
             meshPart = self.mesh
-        self.mesh.ExportCGNS(meshPart, f, overwrite)
+        self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
 
     ## Export the mesh in a file in GMF format.
     #  GMF files must have .mesh extension for the ASCII format and .meshb for
@@ -1912,9 +1934,14 @@ class Mesh:
     #  Export the mesh in a file in MED format
     #  allowing to overwrite the file if it exists or add the exported data to its contents
     #  @param f the file name
-    #  @param version MED format version (MED_V2_1 or MED_V2_2,
-    #                 the latter meaning any current version). The parameter is
-    #                 obsolete since MED_V2_1 is no longer supported.
+    #  @param version MED format version:
+    #         - MED_V2_1 is obsolete.
+    #         - MED_V2_2 means current version (kept for compatibility reasons)
+    #         - MED_LATEST means current version.
+    #         - MED_MINOR_x where x from 0 to 9 indicates the minor version of MED
+    #           to use for writing MED files, for backward compatibility :
+    #           for instance, with SALOME 8.4 use MED 3.2 (minor=2) instead of 3.3,
+    #           to allow the file to be read with SALOME 8.3.
     #  @param opt boolean parameter for creating/not creating
     #         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
     #  @param overwrite boolean parameter for overwriting/not overwriting the file
@@ -1924,7 +1951,7 @@ class Mesh:
     #         - 3D in the rest cases.<br>
     #         If @a autoDimension is @c False, the space dimension is always 3.
     #  @ingroup l2_impexp
-    def ExportToMED(self, f, version=MED_V2_2, opt=0, overwrite=1, autoDimension=True):
+    def ExportToMED(self, f, version=MED_LATEST, opt=0, overwrite=1, autoDimension=True):
         self.mesh.ExportToMEDX(f, opt, version, overwrite, autoDimension)
 
     # Operations with groups:
@@ -2010,6 +2037,8 @@ class Mesh:
     #  @ingroup l2_grps_create
     def MakeGroupByIds(self, groupName, elementType, elemIDs):
         group = self.mesh.CreateGroup(elementType, groupName)
+        if isinstance( elemIDs, Mesh ):
+            elemIDs = elemIDs.GetMesh()
         if hasattr( elemIDs, "GetIDs" ):
             if hasattr( elemIDs, "SetMesh" ):
                 elemIDs.SetMesh( self.GetMesh() )
@@ -2296,10 +2325,10 @@ class Mesh:
         return self.editor.MakeIDSource(ids, elemType)
 
 
-    # Get informations about mesh contents:
+    # Get information about mesh contents:
     # ------------------------------------
 
-    ## Get the mesh stattistic
+    ## Get the mesh statistic
     #  @return dictionary type element - count of elements
     #  @ingroup l1_meshinfo
     def GetMeshInfo(self, obj = None):
@@ -2687,9 +2716,14 @@ class Mesh:
 
     ## Return an element based on all given nodes.
     #  @ingroup l1_meshinfo
-    def FindElementByNodes(self,nodes):
+    def FindElementByNodes(self, nodes):
         return self.mesh.FindElementByNodes(nodes)
 
+    ## Return elements including all given nodes.
+    #  @ingroup l1_meshinfo
+    def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
+        return self.mesh.GetElementsByNodes( nodes, elemType )
+
     ## Return true if the given element is a polygon
     #  @ingroup l1_meshinfo
     def IsPoly(self, id):
@@ -3107,6 +3141,16 @@ class Mesh:
     def GetPointState(self, x, y, z):
         return self.editor.GetPointState(x, y, z)
 
+    ## Check if a 2D mesh is manifold
+    #  @ingroup l1_controls
+    def IsManifold(self):
+        return self.editor.IsManifold()
+
+    ## Check if orientation of 2D elements is coherent
+    #  @ingroup l1_controls
+    def IsCoherentOrientation2D(self):
+        return self.editor.IsCoherentOrientation2D()
+
     ## Find the node closest to a point and moves it to a point location
     #  @param x  the X coordinate of a point
     #  @param y  the Y coordinate of a point
@@ -3227,7 +3271,7 @@ class Mesh:
     #          Type SMESH.FunctorType._items in the Python Console to see all items.
     #          Note that not all items correspond to numerical functors.
     #  @param MaxAngle      is the maximum angle between element normals at which the fusion
-    #          is still performed; theMaxAngle is mesured in radians.
+    #          is still performed; theMaxAngle is measured in radians.
     #          Also it could be a name of variable which defines angle in degrees.
     #  @return TRUE in case of success, FALSE otherwise.
     #  @ingroup l2_modif_unitetri
@@ -3246,7 +3290,7 @@ class Mesh:
     #          Type SMESH.FunctorType._items in the Python Console to see all items.
     #          Note that not all items correspond to numerical functors.
     #  @param MaxAngle   a max angle between element normals at which the fusion
-    #          is still performed; theMaxAngle is mesured in radians.
+    #          is still performed; theMaxAngle is measured in radians.
     #  @return TRUE in case of success, FALSE otherwise.
     #  @ingroup l2_modif_unitetri
     def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
@@ -3258,7 +3302,7 @@ class Mesh:
         return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
 
     ## Split quadrangles into triangles.
-    #  @param IDsOfElements the faces to be splitted.
+    #  @param IDsOfElements the faces to be split.
     #  @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to
     #         choose a diagonal for splitting. If @a theCriterion is None, which is a default
     #         value, then quadrangles will be split by the smallest diagonal.
@@ -3294,7 +3338,7 @@ class Mesh:
 
     ## Split each of given quadrangles into 4 triangles. A node is added at the center of
     #  a quadrangle.
-    #  @param theElements the faces to be splitted. This can be either mesh, sub-mesh,
+    #  @param theElements the faces to be split. This can be either mesh, sub-mesh,
     #         group or a list of face IDs. By default all quadrangles are split
     #  @ingroup l2_modif_cutquadr
     def QuadTo4Tri (self, theElements=[]):
@@ -3309,7 +3353,7 @@ class Mesh:
         return self.editor.QuadTo4Tri( theElements )
 
     ## Split quadrangles into triangles.
-    #  @param IDsOfElements the faces to be splitted
+    #  @param IDsOfElements the faces to be split
     #  @param Diag13        is used to choose a diagonal for splitting.
     #  @return TRUE in case of success, FALSE otherwise.
     #  @ingroup l2_modif_cutquadr
@@ -3330,7 +3374,7 @@ class Mesh:
         return self.editor.SplitQuadObject(theObject, Diag13)
 
     ## Find a better splitting of the given quadrangle.
-    #  @param IDOfQuad   the ID of the quadrangle to be splitted.
+    #  @param IDOfQuad   the ID of the quadrangle to be split.
     #  @param theCriterion  is a numerical functor, in terms of enum SMESH.FunctorType, used to
     #         choose a diagonal for splitting.
     #         Type SMESH.FunctorType._items in the Python Console to see all items.
@@ -3882,6 +3926,7 @@ class Mesh:
     #         - a GEOM point
     #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion example
     def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
                               scaleFactors=[], linearVariation=False, basePoint=[] ):
         unRegister = genObjUnRegister()
@@ -3922,6 +3967,7 @@ class Mesh:
     #  @param IsNodes is True if elements with given ids are nodes
     #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion example
     def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
         n,e,f = [],[],[]
         if IsNodes: n = IDsOfElements
@@ -3948,6 +3994,7 @@ class Mesh:
     #  @return the list of created groups (SMESH_GroupBase) if \a MakeGroups=True,
     #          empty list otherwise.
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion example
     def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
                           ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
         unRegister = genObjUnRegister()
@@ -3977,6 +4024,7 @@ class Mesh:
     #  @param IsNodes is True if elements to extrude are nodes
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion example
     def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
         n,e,f = [],[],[]
         if IsNodes: n    = theObject
@@ -3993,6 +4041,7 @@ class Mesh:
     #  @param MakeGroups to generate new groups from existing ones
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion example
     def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
         return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
 
@@ -4006,6 +4055,7 @@ class Mesh:
     #  @param MakeGroups forces the generation of new groups from existing ones
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion example
     def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
         return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
 
@@ -4050,6 +4100,7 @@ class Mesh:
     #  @param MakeGroups forces the generation of new groups from existing ones
     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion_along_path example
     def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
                                   NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
                                   HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
@@ -4093,6 +4144,7 @@ class Mesh:
     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion_along_path example
     def ExtrusionAlongPathX(self, Base, Path, NodeStart,
                             HasAngles=False, Angles=[], LinearVariation=False,
                             HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
@@ -4125,6 +4177,7 @@ class Mesh:
     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion_along_path example
     def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
                            HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
                            MakeGroups=False, LinearVariation=False):
@@ -4155,6 +4208,7 @@ class Mesh:
     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion_along_path example
     def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
                                  HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
                                  MakeGroups=False, LinearVariation=False):
@@ -4184,6 +4238,7 @@ class Mesh:
     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion_along_path example
     def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
                                    HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
                                    MakeGroups=False, LinearVariation=False):
@@ -4213,6 +4268,7 @@ class Mesh:
     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
+    #  @ref tui_extrusion_along_path example
     def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
                                    HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
                                    MakeGroups=False, LinearVariation=False):
@@ -4566,10 +4622,12 @@ class Mesh:
     #  @param NodesToKeep nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
     #         If @a NodesToKeep does not include a node to keep for some group to merge,
     #         then the first node in the group is kept.
+    #  @param AvoidMakingHoles prevent merging nodes which cause removal of elements becoming
+    #         invalid
     #  @ingroup l2_modif_trsf
-    def MergeNodes (self, GroupsOfNodes, NodesToKeep=[]):
+    def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
         # NodesToKeep are converted to SMESH_IDSource in meshEditor.MergeNodes()
-        self.editor.MergeNodes(GroupsOfNodes,NodesToKeep)
+        self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
 
     ## Find the elements built on the same nodes.
     #  @param MeshOrSubMeshOrGroup Mesh or SubMesh, or Group of elements for searching
@@ -4595,6 +4653,24 @@ class Mesh:
     def MergeEqualElements(self):
         self.editor.MergeEqualElements()
 
+    ## Returns all or only closed free borders
+    #  @return list of SMESH.FreeBorder's
+    #  @ingroup l2_modif_trsf
+    def FindFreeBorders(self, ClosedOnly=True):
+        return self.editor.FindFreeBorders( ClosedOnly )
+
+    ## Fill with 2D elements a hole defined by a SMESH.FreeBorder.
+    #  @param FreeBorder either a SMESH.FreeBorder or a list on node IDs. These nodes
+    #         must describe all sequential nodes of the hole border. The first and the last
+    #         nodes must be the same. Use FindFreeBorders() to get nodes of holes.
+    #  @ingroup l2_modif_trsf
+    def FillHole(self, holeNodes):
+        if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
+            holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
+        if not isinstance( holeNodes, SMESH.FreeBorder ):
+            raise TypeError, "holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes
+        self.editor.FillHole( holeNodes )
+
     ## Return groups of FreeBorder's coincident within the given tolerance.
     #  @param tolerance the tolerance. If the tolerance <= 0.0 then one tenth of an average
     #         size of elements adjacent to free borders being compared is used.
@@ -4870,12 +4946,12 @@ class Mesh:
 
     ## Identify the elements that will be affected by node duplication (actual duplication is not performed.
     #  This method is the first step of DoubleNodeElemGroupsInRegion.
-    #  @param theElems - list of groups of elements (edges or faces) to be replicated
+    #  @param theElems - list of groups of nodes or elements (edges or faces) to be replicated
     #  @param theNodesNot - list of groups of nodes not to replicated
     #  @param theShape - shape to detect affected elements (element which geometric center
     #         located on or inside shape).
     #         The replicated nodes should be associated to affected elements.
-    #  @return groups of affected elements
+    #  @return groups of affected elements in order: volumes, faces, edges
     #  @ingroup l2_modif_duplicat
     def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
         return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
@@ -4910,7 +4986,40 @@ class Mesh:
     def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
         return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
 
-    def _getFunctor(self, funcType ):
+    ## Create a polyline consisting of 1D mesh elements each lying on a 2D element of
+    #  the initial mesh. Positions of new nodes are found by cutting the mesh by the
+    #  plane passing through pairs of points specified by each PolySegment structure.
+    #  If there are several paths connecting a pair of points, the shortest path is
+    #  selected by the module. Position of the cutting plane is defined by the two
+    #  points and an optional vector lying on the plane specified by a PolySegment.
+    #  By default the vector is defined by Mesh module as following. A middle point
+    #  of the two given points is computed. The middle point is projected to the mesh.
+    #  The vector goes from the middle point to the projection point. In case of planar
+    #  mesh, the vector is normal to the mesh.
+    #  @param segments - PolySegment's defining positions of cutting planes.
+    #         Return the used vector which goes from the middle point to its projection.
+    #  @param groupName - optional name of a group where created mesh segments will
+    #         be added.
+    #  @ingroup l2_modif_duplicat
+    def MakePolyLine(self, segments, groupName='', isPreview=False ):
+        editor = self.editor
+        if isPreview:
+            editor = self.mesh.GetMeshEditPreviewer()
+        segmentsRes = editor.MakePolyLine( segments, groupName )
+        for i, seg in enumerate( segmentsRes ):
+            segments[i].vector = seg.vector
+        if isPreview:
+            return editor.GetPreviewData()
+        return None        
+
+    ## Return a cached numerical functor by its type.
+    #  @param theCriterion functor type - an item of SMESH.FunctorType enumeration.
+    #          Type SMESH.FunctorType._items in the Python Console to see all items.
+    #          Note that not all items correspond to numerical functors.
+    #  @return SMESH_NumericalFunctor. The functor is already initialized
+    #          with a mesh
+    #  @ingroup l1_measurements
+    def GetFunctor(self, funcType ):
         fn = self.functors[ funcType._v ]
         if not fn:
             fn = self.smeshpyD.GetFunctor(funcType)
@@ -4926,7 +5035,7 @@ class Mesh:
     #  @return the functor value or zero in case of invalid arguments
     #  @ingroup l1_measurements
     def FunctorValue(self, funcType, elemId, isElem=True):
-        fn = self._getFunctor( funcType )
+        fn = self.GetFunctor( funcType )
         if fn.GetElementType() == self.GetElementType(elemId, isElem):
             val = fn.GetValue(elemId)
         else:
@@ -5032,7 +5141,7 @@ class Mesh:
             unRegister.set( meshPart )
         if isinstance( meshPart, Mesh ):
             meshPart = meshPart.mesh
-        fun = self._getFunctor( funType )
+        fun = self.GetFunctor( funType )
         if fun:
             if meshPart:
                 if hasattr( meshPart, "SetMesh" ):
@@ -5125,17 +5234,18 @@ class meshEditor(SMESH._objref_SMESH_MeshEditor):
     def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
         if len( args ) == 2: args += False,
         return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
-    def MergeNodes(self,*args): # a 2nd arg added (NodesToKeep)
+    def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
         if len( args ) == 1:
-            return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [] )
+            return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
         NodesToKeep = args[1]
+        AvoidMakingHoles = args[2] if len( args ) == 3 else False
         unRegister  = genObjUnRegister()
         if NodesToKeep:
             if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
                 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
             if not isinstance( NodesToKeep, list ):
                 NodesToKeep = [ NodesToKeep ]
-        return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep )
+        return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
     pass
 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
 
@@ -5174,10 +5284,11 @@ omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
 ## Private class used to bind methods creating algorithms to the class Mesh
 #
 class algoCreator:
-    def __init__(self):
+    def __init__(self, method):
         self.mesh = None
         self.defaultAlgoType = ""
         self.algoTypeToClass = {}
+        self.method = method
 
     # Store a python class of algorithm
     def add(self, algoClass):
@@ -5191,25 +5302,48 @@ class algoCreator:
 
     # Create a copy of self and assign mesh to the copy
     def copy(self, mesh):
-        other = algoCreator()
+        other = algoCreator( self.method )
         other.defaultAlgoType = self.defaultAlgoType
-        other.algoTypeToClass  = self.algoTypeToClass
+        other.algoTypeToClass = self.algoTypeToClass
         other.mesh = mesh
         return other
 
     # Create an instance of algorithm
     def __call__(self,algo="",geom=0,*args):
-        algoType = self.defaultAlgoType
-        for arg in args + (algo,geom):
-            if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ):
-                geom = arg
-            if isinstance( arg, str ) and arg:
+        algoType = ""
+        shape = 0
+        if isinstance( algo, str ):
+            algoType = algo
+        elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
+               not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
+            shape = algo
+        elif algo:
+            args += (algo,)
+
+        if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
+            shape = geom
+        elif not algoType and isinstance( geom, str ):
+            algoType = geom
+        elif geom:
+            args += (geom,)
+        for arg in args:
+            if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
+                shape = arg
+            elif isinstance( arg, str ) and not algoType:
                 algoType = arg
+            else:
+                import traceback, sys
+                msg = "Warning. Unexpected argument in mesh.%s() --->  %s" % ( self.method, arg )
+                sys.stderr.write( msg + '\n' )
+                tb = traceback.extract_stack(None,2)
+                traceback.print_list( [tb[0]] )
+        if not algoType:
+            algoType = self.defaultAlgoType
         if not algoType and self.algoTypeToClass:
-            algoType = self.algoTypeToClass.keys()[0]
+            algoType = sorted( self.algoTypeToClass.keys() )[0]
         if self.algoTypeToClass.has_key( algoType ):
             #print "Create algo",algoType
-            return self.algoTypeToClass[ algoType ]( self.mesh, geom )
+            return self.algoTypeToClass[ algoType ]( self.mesh, shape )
         raise RuntimeError, "No class found for algo type %s" % algoType
         return None
 
@@ -5291,7 +5425,7 @@ for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
         if type( algo ).__name__ == 'classobj' and hasattr( algo, "meshMethod" ):
             #print "                     meshMethod:" , str(algo.meshMethod)
             if not hasattr( Mesh, algo.meshMethod ):
-                setattr( Mesh, algo.meshMethod, algoCreator()
+                setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
                 pass
             getattr( Mesh, algo.meshMethod ).add( algo )
             pass