Salome HOME
Merge branch 'V9_6_BR'
[modules/smesh.git] / src / SMESH_SWIG / smeshBuilder.py
index 381bb20ca6dfb8b08b35c35e6c2bc758dbf3f0e3..c99e958214e6c0d16b649cb24eeb24c9e4cf9d11 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2020  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -38,8 +38,9 @@ SMESH.MED_MINOR_7 = 27 # back compatibility
 SMESH.MED_MINOR_8 = 28 # back compatibility
 SMESH.MED_MINOR_9 = 29 # back compatibility
 
-from   SMESH import *
-from   salome.smesh.smesh_algorithm import Mesh_Algorithm
+from SMESH import *
+from salome.smesh.smesh_algorithm import Mesh_Algorithm
+from StdMeshers import BlockCS
 
 import SALOME
 import SALOMEDS
@@ -305,7 +306,7 @@ def AssureGeomPublished(mesh, geom, name=''):
     """
     if not mesh.smeshpyD.IsEnablePublish():
         return
-    if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
+    if not hasattr( geom, "GetShapeType" ):
         return
     if not geom.GetStudyEntry():
         ## get a name
@@ -318,27 +319,13 @@ def AssureGeomPublished(mesh, geom, name=''):
         mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
     return
 
-def FirstVertexOnCurve(mesh, edge):
-    """
-    Returns:
-        the first vertex of a geometrical edge by ignoring orientation
-    """
-    vv = mesh.geompyD.SubShapeAll( edge, geomBuilder.geomBuilder.ShapeType["VERTEX"])
-    if not vv:
-        raise TypeError("Given object has no vertices")
-    if len( vv ) == 1: return vv[0]
-    v0   = mesh.geompyD.MakeVertexOnCurve(edge,0.)
-    xyz  = mesh.geompyD.PointCoordinates( v0 ) # coords of the first vertex
-    xyz1 = mesh.geompyD.PointCoordinates( vv[0] )
-    xyz2 = mesh.geompyD.PointCoordinates( vv[1] )
-    dist1, dist2 = 0,0
-    for i in range(3):
-        dist1 += abs( xyz[i] - xyz1[i] )
-        dist2 += abs( xyz[i] - xyz2[i] )
-    if dist1 < dist2:
-        return vv[0]
-    else:
-        return vv[1]
+# def FirstVertexOnCurve(mesh, edge):
+#     """
+#     Returns:
+#         the first vertex of a geometrical edge by ignoring orientation
+#     """
+#     return mesh.geompyD.GetVertexByIndex( edge, 0, False )
+
 
 smeshInst = None
 """
@@ -475,6 +462,24 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
             obj,name = name,obj
         return Mesh(self, self.geompyD, obj, name)
 
+    def RemoveMesh( self, mesh ):
+        """
+        Delete a mesh
+        """
+        if isinstance( mesh, Mesh ):
+            mesh = mesh.GetMesh()
+            pass
+        if not isinstance( mesh, SMESH._objref_SMESH_Mesh ):
+            raise TypeError("%s is not a mesh" % mesh )
+        so = salome.ObjectToSObject( mesh )
+        if so:
+            sb = salome.myStudy.NewBuilder()
+            sb.RemoveObjectWithChildren( so )
+        else:
+            mesh.UnRegister()
+            pass
+        return
+
     def EnumToLong(self,theItem):
         """
         Return a long value from enumeration
@@ -513,8 +518,8 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
         Returns:
                 :class:`SMESH.PointStruct`
         """
-
-        [x, y, z] = self.geompyD.PointCoordinates(theVertex)
+        geompyD = theVertex.GetGen()
+        [x, y, z] = geompyD.PointCoordinates(theVertex)
         return PointStruct(x,y,z)
 
     def GetDirStruct(self,theVector):
@@ -527,13 +532,13 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
         Returns:
                 :class:`SMESH.DirStruct`
         """
-
-        vertices = self.geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
+        geompyD = theVector.GetGen()
+        vertices = geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
         if(len(vertices) != 2):
             print("Error: vector object is incorrect.")
             return None
-        p1 = self.geompyD.PointCoordinates(vertices[0])
-        p2 = self.geompyD.PointCoordinates(vertices[1])
+        p1 = geompyD.PointCoordinates(vertices[0])
+        p2 = geompyD.PointCoordinates(vertices[1])
         pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
         dirst = DirStruct(pnt)
         return dirst
@@ -563,28 +568,29 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
             :class:`SMESH.AxisStruct`
         """
         import GEOM
-        edges = self.geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
+        geompyD = theObj.GetGen()
+        edges = geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
         axis = None
         if len(edges) > 1:
-            vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
-            vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
-            vertex1 = self.geompyD.PointCoordinates(vertex1)
-            vertex2 = self.geompyD.PointCoordinates(vertex2)
-            vertex3 = self.geompyD.PointCoordinates(vertex3)
-            vertex4 = self.geompyD.PointCoordinates(vertex4)
+            vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
+            vertex3, vertex4 = geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
+            vertex1 = geompyD.PointCoordinates(vertex1)
+            vertex2 = geompyD.PointCoordinates(vertex2)
+            vertex3 = geompyD.PointCoordinates(vertex3)
+            vertex4 = geompyD.PointCoordinates(vertex4)
             v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
             v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
             normal = [ v1[1]*v2[2]-v2[1]*v1[2], v1[2]*v2[0]-v2[2]*v1[0], v1[0]*v2[1]-v2[0]*v1[1] ]
             axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
             axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
         elif len(edges) == 1:
-            vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
-            p1 = self.geompyD.PointCoordinates( vertex1 )
-            p2 = self.geompyD.PointCoordinates( vertex2 )
+            vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
+            p1 = geompyD.PointCoordinates( vertex1 )
+            p2 = geompyD.PointCoordinates( vertex2 )
             axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
             axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
         elif theObj.GetShapeType() == GEOM.VERTEX:
-            x,y,z = self.geompyD.PointCoordinates( theObj )
+            x,y,z = geompyD.PointCoordinates( theObj )
             axis = AxisStruct( x,y,z, 1,0,0,)
             axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
         return axis
@@ -812,7 +818,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
 
         Parameters:
                 sourceMesh: the mesh to copy definition of.
-                newGeom: the new geomtry.
+                newGeom: the new geometry.
                 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
                 toCopyGroups: to create groups in the new mesh.
                 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
@@ -823,7 +829,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
                 *invalidEntries* are study entries of objects whose
                 counterparts are not found in the *newGeom*, followed by entries
                 of mesh sub-objects that are invalid because they depend on a not found
-                preceeding sub-shape
+                preceding sub-shape
         """
         if isinstance( sourceMesh, Mesh ):
             sourceMesh = sourceMesh.GetMesh()
@@ -954,7 +960,8 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
                     name = aCriterion.ThresholdStr
                     if not name:
                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
-                    aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
+                    geompyD = aThreshold.GetGen()
+                    aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
             # or a name of GEOM object
             elif isinstance( aThreshold, str ):
                 aCriterion.ThresholdStr = aThreshold
@@ -1005,7 +1012,8 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
                     name = aThreshold.GetName()
                     if not name:
                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
-                    aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
+                    geompyD = aThreshold.GetGen()
+                    aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
             elif isinstance(aThreshold, int): # node id
                 aCriterion.Threshold = aThreshold
             elif isinstance(aThreshold, list): # 3 point coordinates
@@ -1232,11 +1240,30 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
 
         return hyp
 
+    def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
+        """
+        Create hypothesis initialized according to parameters
+
+        Parameters:
+                hypType (string): hypothesis type
+                libName (string): plug-in library name
+                mesh: optional mesh by which a hypotheses can initialize self
+                shape: optional geometry  by size of which a hypotheses can initialize self
+                initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
+
+        Returns:
+                created hypothesis instance
+        """
+        if isinstance( mesh, Mesh ):
+            mesh = mesh.GetMesh()
+        if isinstance( initParams, (bool,int)):
+            initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
+        return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
+                                                                    mesh, shape, initParams )
+
     def GetMeshInfo(self, obj):
         """
         Get the mesh statistic.
-        Use :meth:`smeshBuilder.EnumToLong` to get an integer from 
-        an item of :class:`SMESH.EntityType`.
 
         Returns:
                 dictionary { :class:`SMESH.EntityType` - "count of elements" }
@@ -1617,14 +1644,15 @@ class Mesh(metaclass = MeshMeta):
         Parameters:
                 theMesh: a :class:`SMESH.SMESH_Mesh` object
         """
-
-
         # do not call Register() as this prevents mesh servant deletion at closing study
         #if self.mesh: self.mesh.UnRegister()
         self.mesh = theMesh
         if self.mesh:
             #self.mesh.Register()
             self.geom = self.mesh.GetShapeToMesh()
+            if self.geom:
+                self.geompyD = self.geom.GetGen()
+                pass
         pass
 
     def GetMesh(self):
@@ -1833,10 +1861,7 @@ class Mesh(metaclass = MeshMeta):
         """
 
         if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
-            if self.geom == 0:
-                geom = self.mesh.GetShapeToMesh()
-            else:
-                geom = self.geom
+            geom = self.mesh.GetShapeToMesh()
         ok = False
         try:
             if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
@@ -2056,10 +2081,20 @@ class Mesh(metaclass = MeshMeta):
 
     def SetMeshOrder(self, submeshes):
         """
-        Set order in which concurrent sub-meshes should be meshed
+        Set priority of sub-meshes. It works in two ways:
+        
+        * For sub-meshes with assigned algorithms of same dimension generating mesh of
+          *several dimensions*, it sets the order in which the sub-meshes are computed.
+        * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
+          when looking for meshing parameters to apply to a sub-shape. To impose the 
+          order in which sub-meshes with uni-dimensional algorithms are computed, 
+          call **submesh.Compute()** in a desired order.
 
         Parameters:
                 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
+
+        Warning: the method is for setting the order for all sub-meshes at once:
+                 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
         """
 
         return self.mesh.SetMeshOrder(submeshes)
@@ -2263,10 +2298,13 @@ class Mesh(metaclass = MeshMeta):
                 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.
-                minor (int): define the minor version (y, where version is x.y.z) of MED file format.
-                        The minor must be between 0 and the current minor version of MED file library.
-                        If minor is equal to -1, the minor version is not changed (default).
-                        The major version (x, where version is x.y.z) cannot be changed.
+                version (int): define the version (xy, where version is x.y.z) of MED file format.
+                        For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
+                        The rules of compatibility to write a mesh in an older version than 
+                        the current version depend on the current version. For instance, 
+                        with med 4.0 it is possible to write/append med files in 4.0.0 (default)
+                        or 3.2.1 or 3.3.1 formats.
+                        If the version is equal to -1, the version is not changed (default).
                 overwrite (boolean): parameter for overwriting/not overwriting the file
                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
@@ -2294,7 +2332,7 @@ class Mesh(metaclass = MeshMeta):
         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
         fileName        = args[0]
         auto_groups     = args[1] if len(args) > 1 else False
-        minor           = args[2] if len(args) > 2 else -1
+        version         = args[2] if len(args) > 2 else -1
         overwrite       = args[3] if len(args) > 3 else True
         meshPart        = args[4] if len(args) > 4 else None
         autoDimension   = args[5] if len(args) > 5 else True
@@ -2303,7 +2341,8 @@ class Mesh(metaclass = MeshMeta):
         z_tolerance     = args[8] if len(args) > 8 else -1.
         # process keywords arguments
         auto_groups     = kwargs.get("auto_groups", auto_groups)
-        minor           = kwargs.get("minor", minor)
+        version         = kwargs.get("version", version)
+        version         = kwargs.get("minor", version)
         overwrite       = kwargs.get("overwrite", overwrite)
         meshPart        = kwargs.get("meshPart", meshPart)
         autoDimension   = kwargs.get("autoDimension", autoDimension)
@@ -2321,10 +2360,11 @@ class Mesh(metaclass = MeshMeta):
             z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
             self.mesh.SetParameters(Parameters)
 
-            self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
+            self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
+                                       version, overwrite, autoDimension,
                                        fields, geomAssocFields, z_tolerance)
         else:
-            self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
+            self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
 
     def ExportSAUV(self, f, auto_groups=0):
         """
@@ -2595,14 +2635,22 @@ class Mesh(metaclass = MeshMeta):
         tgeo = str(shape.GetShapeType())
         if tgeo == "VERTEX":
             typ = NODE
-        elif tgeo == "EDGE":
+        elif tgeo == "EDGE" or tgeo == "WIRE":
             typ = EDGE
         elif tgeo == "FACE" or tgeo == "SHELL":
             typ = FACE
         elif tgeo == "SOLID" or tgeo == "COMPSOLID":
             typ = VOLUME
         elif tgeo == "COMPOUND":
-            sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
+            try:
+              sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
+            except:
+              # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
+              # simplification of access in geomBuilder: omniORB.registerObjref
+              from SHAPERSTUDY_utils import getEngine
+              gen = getEngine()
+              if gen:
+                sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
             if not sub:
                 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
             return self._groupTypeFromShape( sub[0] )
@@ -2757,6 +2805,10 @@ class Mesh(metaclass = MeshMeta):
 
         Parameters:
                 group (SMESH.SMESH_GroupBase): group to remove
+
+        Note:
+                This operation can create gaps in numeration of nodes or elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         self.mesh.RemoveGroupWithContents(group)
@@ -3091,8 +3143,6 @@ class Mesh(metaclass = MeshMeta):
     def GetMeshInfo(self, obj = None):
         """
         Get the mesh statistic.
-        Use :meth:`smeshBuilder.EnumToLong` to get an integer from 
-        an item of :class:`SMESH.EntityType`.
 
         Returns:
                 dictionary { :class:`SMESH.EntityType` - "count of elements" }
@@ -3957,6 +4007,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True or False
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         return self.editor.RemoveElements(IDsOfElements)
@@ -3970,6 +4024,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True or False
+
+        Note:
+                This operation can create gaps in numeration of nodes.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         return self.editor.RemoveNodes(IDsOfNodes)
@@ -3980,6 +4038,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             number of the removed nodes
+
+        Note:
+                This operation can create gaps in numeration of nodes.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         return self.editor.RemoveOrphanNodes()
@@ -4388,7 +4450,8 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
              A list of edge groups and a list of corresponding node groups,
-             where the group is a list of IDs of edges or elements.
+             where the group is a list of IDs of edges or nodes, like follows
+             [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
              If a group is closed, the first and last nodes of the group are same.
         """
         if isinstance( edges, Mesh ):
@@ -4454,6 +4517,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             False if proper faces were not found
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         return self.editor.DeleteDiag(NodeID1, NodeID2)
@@ -4493,8 +4560,8 @@ class Mesh(metaclass = MeshMeta):
         Reorient faces contained in *the2DObject*.
 
         Parameters:
-                the2DObject: is a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
-                theDirection: is a desired direction of normal of *theFace*.
+                the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
+                theDirection: a desired direction of normal of *theFace*.
                         It can be either a GEOM vector or a list of coordinates [x,y,z].
                 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
                         compared with theDirection. It can be either ID of face or a point
@@ -4584,6 +4651,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True in case of success, False otherwise.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
@@ -4608,6 +4679,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True in case of success, False otherwise.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
@@ -4631,6 +4706,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True in case of success, False otherwise.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
@@ -4654,6 +4733,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True in case of success, False otherwise.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         if ( isinstance( theObject, Mesh )):
             theObject = theObject.GetMesh()
@@ -4671,6 +4754,10 @@ class Mesh(metaclass = MeshMeta):
                 theElements: the faces to be splitted. This can be either 
                         :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
                         or a list of face IDs. By default all quadrangles are split
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         unRegister = genObjUnRegister()
         if isinstance( theElements, Mesh ):
@@ -4692,6 +4779,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True in case of success, False otherwise.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
@@ -4708,6 +4799,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True in case of success, False otherwise.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         if ( isinstance( theObject, Mesh )):
             theObject = theObject.GetMesh()
@@ -4728,6 +4823,10 @@ class Mesh(metaclass = MeshMeta):
             * 1 if 1-3 diagonal is better, 
             * 2 if 2-4 diagonal is better, 
             * 0 if error occurs.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
 
@@ -4740,6 +4839,10 @@ class Mesh(metaclass = MeshMeta):
                 method:  flags passing splitting method:
                         smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
                         smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         unRegister = genObjUnRegister()
         if isinstance( elems, Mesh ):
@@ -4764,6 +4867,10 @@ class Mesh(metaclass = MeshMeta):
         Parameters:
             elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
                 if None (default), all bi-quadratic elements will be split
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         unRegister = genObjUnRegister()
         if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
@@ -4795,6 +4902,10 @@ class Mesh(metaclass = MeshMeta):
                 allDomains: if :code:`False`, only hexahedra adjacent to one closest
                         to *startHexPoint* are split, else *startHexPoint*
                         is used to find the facet to split in all domains present in *elems*.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         # IDSource
         unRegister = genObjUnRegister()
@@ -4824,6 +4935,10 @@ class Mesh(metaclass = MeshMeta):
     def SplitQuadsNearTriangularFacets(self):
         """
         Split quadrangle faces near triangular facets of volumes
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         faces_array = self.GetElementsByType(SMESH.FACE)
         for face_id in faces_array:
@@ -4868,6 +4983,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True in case of success, False otherwise.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 #    Pattern:
 #                     5.---------.6
@@ -4932,6 +5051,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             True in case of success, False otherwise.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 #        Pattern:     5.---------.6
 #                     /|#       /|
@@ -5089,6 +5212,10 @@ class Mesh(metaclass = MeshMeta):
 
         Warning:
             If *theSubMesh* is provided, the mesh can become non-conformal
+
+        Note:
+                This operation can create gaps in numeration of nodes or elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         if isinstance( theSubMesh, Mesh ):
@@ -5116,6 +5243,10 @@ class Mesh(metaclass = MeshMeta):
 
         Warning:
             If *theSubMesh* is provided, the mesh can become non-conformal
+
+        Note:
+                This operation can create gaps in numeration of nodes or elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         if theSubMesh:
@@ -5489,6 +5620,8 @@ class Mesh(metaclass = MeshMeta):
         if isinstance( Elements, list ):
             if not Elements:
                 raise RuntimeError("Elements empty!")
+            if isinstance( Elements[0], Mesh ):
+                Elements = [ Elements[0].GetMesh() ]
             if isinstance( Elements[0], int ):
                 Elements = self.GetIDSource( Elements, SMESH.ALL )
                 unRegister.set( Elements )
@@ -6255,8 +6388,8 @@ class Mesh(metaclass = MeshMeta):
         theValue,Parameters,hasVars = ParseParameters(Value)
         mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
         self.mesh.SetParameters(Parameters)
-        if mesh_groups[0]:
-            return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
+        if mesh_groups[0]:
+            return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
         return mesh_groups
 
     def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
@@ -6326,6 +6459,10 @@ class Mesh(metaclass = MeshMeta):
                 then the first node in the group is kept.
             AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
                 invalid
+
+        Note:
+                This operation can create gaps in numeration of nodes or elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
         self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
 
@@ -6375,6 +6512,10 @@ class Mesh(metaclass = MeshMeta):
             ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
                 If *ElementsToKeep* does not include an element to keep for some group to merge,
                 then the first element in the group is kept.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         unRegister = genObjUnRegister()
@@ -6390,6 +6531,10 @@ class Mesh(metaclass = MeshMeta):
     def MergeEqualElements(self):
         """
         Leave one element and remove all other elements built on the same nodes.
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         self.editor.MergeEqualElements()
@@ -6422,7 +6567,7 @@ class Mesh(metaclass = MeshMeta):
             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, groupName )
+        return self.editor.FillHole( holeNodes, groupName )
 
     def FindCoincidentFreeBorders (self, tolerance=0.):
         """
@@ -6459,6 +6604,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             a number of successfully sewed groups
+
+        Note:
+                This operation can create gaps in numeration of nodes or elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         if freeBorders and isinstance( freeBorders, list ):
@@ -6490,6 +6639,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
+
+        Note:
+                This operation can create gaps in numeration of nodes or elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
@@ -6503,6 +6656,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
@@ -6515,6 +6672,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
+
+        Note:
+                This operation can create gaps in numeration of elements.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
@@ -6533,6 +6694,10 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
+
+        Note:
+                This operation can create gaps in numeration of nodes.
+                Call :meth:`RenumberElements` to remove the gaps.
         """
 
         return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
@@ -6541,7 +6706,7 @@ class Mesh(metaclass = MeshMeta):
 
     def ChangeElemNodes(self, ide, newIDs):
         """
-        Set new nodes for the given element.
+        Set new nodes for the given element. Number of nodes should be kept.
 
         Parameters:
             ide: the element ID
@@ -6902,7 +7067,7 @@ class Mesh(metaclass = MeshMeta):
     def MakeSlot(self, segmentGroup, width ):
         """
         Create a slot of given width around given 1D elements lying on a triangle mesh.
-        The slot is consrtucted by cutting faces by cylindrical surfaces made
+        The slot is constructed by cutting faces by cylindrical surfaces made
         around each segment. Segments are expected to be created by MakePolyLine().
 
         Returns:
@@ -6951,52 +7116,90 @@ class Mesh(metaclass = MeshMeta):
 
     def GetLength(self, elemId=None):
         """
-        Get length of 1D element or sum of lengths of all 1D mesh elements
+        Get length of given 1D elements or of all 1D mesh elements
 
         Parameters:
-            elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
+            elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum length of all 1D elements will be calculated.
 
         Returns:
-            element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise
+            Sum of lengths of given elements
         """
 
         length = 0
         if elemId == None:
             length = self.smeshpyD.GetLength(self)
+        elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
+            length = self.smeshpyD.GetLength(elemId)
+        elif elemId == []:
+            length = 0
+        elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
+            for obj in elemId:
+                length += self.smeshpyD.GetLength(obj)
+        elif isinstance(elemId, list) and isinstance(elemId[0], int):
+            unRegister = genObjUnRegister()
+            obj = self.GetIDSource( elemId )
+            unRegister.set( obj )
+            length = self.smeshpyD.GetLength( obj )
         else:
             length = self.FunctorValue(SMESH.FT_Length, elemId)
         return length
 
     def GetArea(self, elemId=None):
         """
-        Get area of 2D element or sum of areas of all 2D mesh elements
-        elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
+        Get area of given 2D elements or of all 2D mesh elements
+
+        Parameters:
+            elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum area of all 2D elements will be calculated.
 
         Returns:
-            element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
+            Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
         """
 
         area = 0
         if elemId == None:
             area = self.smeshpyD.GetArea(self)
+        elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
+            area = self.smeshpyD.GetArea(elemId)
+        elif elemId == []:
+            area = 0
+        elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
+            for obj in elemId:
+                area += self.smeshpyD.GetArea(obj)
+        elif isinstance(elemId, list) and isinstance(elemId[0], int):
+            unRegister = genObjUnRegister()
+            obj = self.GetIDSource( elemId )
+            unRegister.set( obj )
+            area = self.smeshpyD.GetArea( obj )
         else:
             area = self.FunctorValue(SMESH.FT_Area, elemId)
         return area
 
     def GetVolume(self, elemId=None):
         """
-        Get volume of 3D element or sum of volumes of all 3D mesh elements
+        Get volume of given 3D elements or of all 3D mesh elements
 
         Parameters:
-            elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
+            elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum volume of all 3D elements will be calculated.
 
         Returns:
-            element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
+            Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
         """
 
         volume = 0
         if elemId == None:
-            volume = self.smeshpyD.GetVolume(self)
+            volume= self.smeshpyD.GetVolume(self)
+        elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
+            volume= self.smeshpyD.GetVolume(elemId)
+        elif elemId == []:
+            volume = 0
+        elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
+            for obj in elemId:
+                volume+= self.smeshpyD.GetVolume(obj)
+        elif isinstance(elemId, list) and isinstance(elemId[0], int):
+            unRegister = genObjUnRegister()
+            obj = self.GetIDSource( elemId )
+            unRegister.set( obj )
+            volume= self.smeshpyD.GetVolume( obj )
         else:
             volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
         return volume
@@ -7429,7 +7632,7 @@ class genObjUnRegister:
             if genObj and hasattr( genObj, "UnRegister" ):
                 genObj.UnRegister()
 
-for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
+for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
     """
     Bind methods creating mesher plug-ins to the Mesh class
     """