Salome HOME
23636: EDF 18217 - Problem when suppressing CAD
[modules/smesh.git] / src / SMESH_SWIG / smeshBuilder.py
old mode 100644 (file)
new mode 100755 (executable)
index 025fa02..ffeaa7c
@@ -24,9 +24,19 @@ import salome
 from salome.geom import geomBuilder
 
 import SMESH # This is necessary for back compatibility
 from salome.geom import geomBuilder
 
 import SMESH # This is necessary for back compatibility
-import omniORB                                   # back compatibility
-SMESH.MED_V2_1 = omniORB.EnumItem("MED_V2_1", 0) # back compatibility
-SMESH.MED_V2_2 = omniORB.EnumItem("MED_V2_2", 1) # back compatibility
+import omniORB                                       # back compatibility
+SMESH.MED_V2_1    = 11 #omniORB.EnumItem("MED_V2_1", 11) # back compatibility: use number > MED minor version
+SMESH.MED_V2_2    = 12 #omniORB.EnumItem("MED_V2_2", 12) # back compatibility: latest minor will be used
+SMESH.MED_MINOR_0 = 20 # back compatibility
+SMESH.MED_MINOR_1 = 21 # back compatibility
+SMESH.MED_MINOR_2 = 22 # back compatibility
+SMESH.MED_MINOR_3 = 23 # back compatibility
+SMESH.MED_MINOR_4 = 24 # back compatibility
+SMESH.MED_MINOR_5 = 25 # back compatibility
+SMESH.MED_MINOR_6 = 26 # back compatibility
+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
@@ -293,6 +303,8 @@ def AssureGeomPublished(mesh, geom, name=''):
     """
     Private method. Add geom (sub-shape of the main shape) into the study if not yet there
     """
     """
     Private method. Add geom (sub-shape of the main shape) into the study if not yet there
     """
+    if not mesh.smeshpyD.IsEnablePublish():
+        return
     if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
         return
     if not geom.GetStudyEntry():
     if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
         return
     if not geom.GetStudyEntry():
@@ -619,6 +631,8 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
         if not geompyD:
             from salome.geom import geomBuilder
             geompyD = geomBuilder.geom
         if not geompyD:
             from salome.geom import geomBuilder
             geompyD = geomBuilder.geom
+            if not geompyD:
+                geompyD = geomBuilder.New()
             pass
         self.geompyD=geompyD
         self.SetGeomEngine(geompyD)
             pass
         self.geompyD=geompyD
         self.SetGeomEngine(geompyD)
@@ -719,10 +733,10 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
 
     def Concatenate( self, meshes, uniteIdenticalGroups,
                      mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
 
     def Concatenate( self, meshes, uniteIdenticalGroups,
                      mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
-                     name = ""):
+                     name = "", meshToAppendTo = None):
         """
         """
-        Concatenate the given meshes into one mesh. All groups of input meshes will be
-        present in the new mesh.
+        Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
+        All groups of input meshes will be present in the new mesh.
 
         Parameters:
                 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
 
         Parameters:
                 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
@@ -731,24 +745,38 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
                 mergeTolerance: tolerance for merging nodes
                 allGroups: forces creation of groups corresponding to every input mesh
                 name: name of a new mesh
                 mergeTolerance: tolerance for merging nodes
                 allGroups: forces creation of groups corresponding to every input mesh
                 name: name of a new mesh
+                meshToAppendTo: a mesh to append all given meshes
 
         Returns:
                 an instance of class :class:`Mesh`
 
         Returns:
                 an instance of class :class:`Mesh`
+
+        See also: 
+                :meth:`Mesh.Append`
         """
 
         if not meshes: return None
         """
 
         if not meshes: return None
-        for i,m in enumerate(meshes):
-            if isinstance(m, Mesh):
+        if not isinstance( meshes, list ):
+            meshes = [ meshes ]
+        for i,m in enumerate( meshes ):
+            if isinstance( m, Mesh ):
                 meshes[i] = m.GetMesh()
                 meshes[i] = m.GetMesh()
-        mergeTolerance,Parameters,hasVars = ParseParameters(mergeTolerance)
-        meshes[0].SetParameters(Parameters)
+        mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
+        if hasattr(meshes[0], "SetParameters"):
+            meshes[0].SetParameters( Parameters )
+        else:
+            meshes[0].GetMesh().SetParameters( Parameters )
+        if isinstance( meshToAppendTo, Mesh ):
+            meshToAppendTo = meshToAppendTo.GetMesh()
         if allGroups:
             aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
         if allGroups:
             aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
-                self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
+                self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
+                mergeTolerance,meshToAppendTo )
         else:
             aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
         else:
             aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
-                self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
-        aMesh = Mesh(self, self.geompyD, aSmeshMesh, name=name)
+                self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
+                mergeTolerance,meshToAppendTo )
+
+        aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
         return aMesh
 
     def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
         return aMesh
 
     def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
@@ -768,11 +796,46 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
                 an instance of class :class:`Mesh`
         """
 
                 an instance of class :class:`Mesh`
         """
 
-        if (isinstance( meshPart, Mesh )):
+        if isinstance( meshPart, Mesh ):
             meshPart = meshPart.GetMesh()
         mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
         return Mesh(self, self.geompyD, mesh)
 
             meshPart = meshPart.GetMesh()
         mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
         return Mesh(self, self.geompyD, mesh)
 
+    def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
+                          toReuseHypotheses=True, toCopyElements=True):
+        """
+        Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
+        It is supposed that the new geometry is a modified geometry of *sourceMesh*.
+        To facilitate and speed up the operation, consider using
+        "Set presentation parameters and sub-shapes from arguments" option in
+        a dialog of geometrical operation used to create the new geometry.
+
+        Parameters:
+                sourceMesh: the mesh to copy definition of.
+                newGeom: the new geomtry.
+                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*.
+                toCopyElements: to copy mesh elements present on non-modified sub-shapes of 
+                                *sourceMesh*.
+        Returns:
+                tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
+                *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
+        """
+        if isinstance( sourceMesh, Mesh ):
+            sourceMesh = sourceMesh.GetMesh()
+
+        ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
+           SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
+                                                     toCopyGroups,
+                                                     toReuseHypotheses,
+                                                     toCopyElements)
+        return ( ok, Mesh(self, self.geompyD, newMesh),
+                 newGroups, newSubMeshes, newHypotheses, invalidEntries )
+
     def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
         """
         Return IDs of sub-shapes
     def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
         """
         Return IDs of sub-shapes
@@ -1130,6 +1193,8 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
             functor = aFilterMgr.CreateLength()
         elif theCriterion == FT_Length2D:
             functor = aFilterMgr.CreateLength2D()
             functor = aFilterMgr.CreateLength()
         elif theCriterion == FT_Length2D:
             functor = aFilterMgr.CreateLength2D()
+        elif theCriterion == FT_Length3D:
+            functor = aFilterMgr.CreateLength3D()
         elif theCriterion == FT_Deflection2D:
             functor = aFilterMgr.CreateDeflection2D()
         elif theCriterion == FT_NodeConnectivityNumber:
         elif theCriterion == FT_Deflection2D:
             functor = aFilterMgr.CreateDeflection2D()
         elif theCriterion == FT_NodeConnectivityNumber:
@@ -1379,13 +1444,16 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
 
     def GetGravityCenter(self, obj):
         """
 
     def GetGravityCenter(self, obj):
         """
-        Get gravity center of all nodes of the mesh object.
+        Get gravity center of all nodes of a mesh object.
         
         Parameters:            
                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
 
         Returns:        
         
         Parameters:            
                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
 
         Returns:        
-            Three components of the gravity center (x,y,z)
+                Three components of the gravity center (x,y,z)
+
+        See also: 
+                :meth:`Mesh.BaryCenter`
         """
         if isinstance(obj, Mesh): obj = obj.mesh
         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
         """
         if isinstance(obj, Mesh): obj = obj.mesh
         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
@@ -1394,6 +1462,28 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
         aMeasurements.UnRegister()
         return pointStruct.x, pointStruct.y, pointStruct.z
 
         aMeasurements.UnRegister()
         return pointStruct.x, pointStruct.y, pointStruct.z
 
+    def GetAngle(self, p1, p2, p3 ):
+        """
+        Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
+
+        Parameters:            
+                p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct 
+                          or list [x,y,z]
+
+        Returns:        
+            Angle in radians
+        """
+        if isinstance( p1, list ): p1 = PointStruct(*p1)
+        if isinstance( p2, list ): p2 = PointStruct(*p2)
+        if isinstance( p3, list ): p3 = PointStruct(*p3)
+
+        aMeasurements = self.CreateMeasurements()
+        angle = aMeasurements.Angle(p1,p2,p3)
+        aMeasurements.UnRegister()
+
+        return angle
+
+
     pass # end of class smeshBuilder
 
 import omniORB
     pass # end of class smeshBuilder
 
 import omniORB
@@ -1414,7 +1504,6 @@ def New( instance=None, instanceGeom=None):
         smesh = smeshBuilder.New()
 
     Parameters:
         smesh = smeshBuilder.New()
 
     Parameters:
-        study:         SALOME study, generally obtained by salome.myStudy.
         instance:      CORBA proxy of SMESH Engine. If None, the default Engine is used.
         instanceGeom:  CORBA proxy of GEOM  Engine. If None, the default Engine is used.
     Returns:
         instance:      CORBA proxy of SMESH Engine. If None, the default Engine is used.
         instanceGeom:  CORBA proxy of GEOM  Engine. If None, the default Engine is used.
     Returns:
@@ -1423,6 +1512,10 @@ def New( instance=None, instanceGeom=None):
     global engine
     global smeshInst
     global doLcc
     global engine
     global smeshInst
     global doLcc
+    if instance and isinstance( instance, SALOMEDS._objref_Study ):
+        import sys
+        sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
+        instance = None
     engine = instance
     if engine is None:
         doLcc = True
     engine = instance
     if engine is None:
         doLcc = True
@@ -1544,6 +1637,18 @@ class Mesh(metaclass = MeshMeta):
 
         return self.mesh
 
 
         return self.mesh
 
+    def GetEngine(self):
+        """
+        Return a smeshBuilder instance created this mesh
+        """
+        return self.smeshpyD
+
+    def GetGeomEngine(self):
+        """
+        Return a geomBuilder instance
+        """
+        return self.geompyD
+
     def GetName(self):
         """
         Get the name of the mesh
     def GetName(self):
         """
         Get the name of the mesh
@@ -1583,7 +1688,7 @@ class Mesh(metaclass = MeshMeta):
 
                    algo1D = mesh.Segment(geom=Edge_1)
 
 
                    algo1D = mesh.Segment(geom=Edge_1)
 
-                creates a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
+                create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
                 The created sub-mesh can be retrieved from the algorithm::
 
                    submesh = algo1D.GetSubMesh()
                 The created sub-mesh can be retrieved from the algorithm::
 
                    submesh = algo1D.GetSubMesh()
@@ -1613,6 +1718,12 @@ class Mesh(metaclass = MeshMeta):
 
         self.mesh = self.smeshpyD.CreateMesh(geom)
 
 
         self.mesh = self.smeshpyD.CreateMesh(geom)
 
+    def HasShapeToMesh(self):
+        """
+        Return ``True`` if this mesh is based on geometry
+        """
+        return self.mesh.HasShapeToMesh()
+
     def Load(self):
         """
         Load mesh from the study after opening the study
     def Load(self):
         """
         Load mesh from the study after opening the study
@@ -1818,9 +1929,6 @@ class Mesh(metaclass = MeshMeta):
             pass
         if salome.sg.hasDesktop():
             if not isinstance( refresh, list): # not a call from subMesh.Compute()
             pass
         if salome.sg.hasDesktop():
             if not isinstance( refresh, list): # not a call from subMesh.Compute()
-                smeshgui = salome.ImportComponentGUI("SMESH")
-                smeshgui.Init()
-                smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok, (self.NbNodes()==0) )
                 if refresh: salome.sg.updateObjBrowser()
 
         return ok
                 if refresh: salome.sg.updateObjBrowser()
 
         return ok
@@ -1966,9 +2074,6 @@ class Mesh(metaclass = MeshMeta):
 
         self.mesh.Clear()
         if ( salome.sg.hasDesktop() ):
 
         self.mesh.Clear()
         if ( salome.sg.hasDesktop() ):
-            smeshgui = salome.ImportComponentGUI("SMESH")
-            smeshgui.Init()
-            smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
             if refresh: salome.sg.updateObjBrowser()
 
     def ClearSubMesh(self, geomId, refresh=False):
             if refresh: salome.sg.updateObjBrowser()
 
     def ClearSubMesh(self, geomId, refresh=False):
@@ -1982,9 +2087,6 @@ class Mesh(metaclass = MeshMeta):
 
         self.mesh.ClearSubMesh(geomId)
         if salome.sg.hasDesktop():
 
         self.mesh.ClearSubMesh(geomId)
         if salome.sg.hasDesktop():
-            smeshgui = salome.ImportComponentGUI("SMESH")
-            smeshgui.Init()
-            smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
             if refresh: salome.sg.updateObjBrowser()
 
     def AutomaticTetrahedralization(self, fineness=0):
             if refresh: salome.sg.updateObjBrowser()
 
     def AutomaticTetrahedralization(self, fineness=0):
@@ -2161,6 +2263,10 @@ 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.
                 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.
                 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
                 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
@@ -2172,38 +2278,53 @@ class Mesh(metaclass = MeshMeta):
                         If *autoDimension* is *False*, the space dimension is always 3.
                 fields: list of GEOM fields defined on the shape to mesh.
                 geomAssocFields: each character of this string means a need to export a 
                         If *autoDimension* is *False*, the space dimension is always 3.
                 fields: list of GEOM fields defined on the shape to mesh.
                 geomAssocFields: each character of this string means a need to export a 
-                        corresponding field; correspondence between fields and characters is following:
-                        - 'v' stands for "_vertices _" field;
-                        - 'e' stands for "_edges _" field;
-                        - 'f' stands for "_faces _" field;
-                        - 's' stands for "_solids _" field.
+                        corresponding field; correspondence between fields and characters 
+                        is following:
+
+                        - 'v' stands for "_vertices_" field;
+                        - 'e' stands for "_edges_" field;
+                        - 'f' stands for "_faces_" field;
+                        - 's' stands for "_solids_" field.
+
+                zTolerance (float): tolerance in Z direction. If Z coordinate of a node is 
+                             close to zero within a given tolerance, the coordinate is set to zero.
+                             If *ZTolerance* is negative (default), the node coordinates are kept as is.
         """
         # process positional arguments
         """
         # process positional arguments
-        args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
+        #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
         fileName        = args[0]
         auto_groups     = args[1] if len(args) > 1 else False
-        overwrite       = args[2] if len(args) > 2 else True
-        meshPart        = args[3] if len(args) > 3 else None
-        autoDimension   = args[4] if len(args) > 4 else True
-        fields          = args[5] if len(args) > 5 else []
-        geomAssocFields = args[6] if len(args) > 6 else ''
+        minor           = 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
+        fields          = args[6] if len(args) > 6 else []
+        geomAssocFields = args[7] if len(args) > 7 else ''
+        z_tolerance     = args[8] if len(args) > 8 else -1.
         # process keywords arguments
         auto_groups     = kwargs.get("auto_groups", auto_groups)
         # process keywords arguments
         auto_groups     = kwargs.get("auto_groups", auto_groups)
+        minor           = kwargs.get("minor", minor)
         overwrite       = kwargs.get("overwrite", overwrite)
         meshPart        = kwargs.get("meshPart", meshPart)
         autoDimension   = kwargs.get("autoDimension", autoDimension)
         fields          = kwargs.get("fields", fields)
         geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
         overwrite       = kwargs.get("overwrite", overwrite)
         meshPart        = kwargs.get("meshPart", meshPart)
         autoDimension   = kwargs.get("autoDimension", autoDimension)
         fields          = kwargs.get("fields", fields)
         geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
+        z_tolerance     = kwargs.get("zTolerance", z_tolerance)
+
         # invoke engine's function
         # invoke engine's function
-        if meshPart or fields or geomAssocFields:
+        if meshPart or fields or geomAssocFields or z_tolerance > 0:
             unRegister = genObjUnRegister()
             if isinstance( meshPart, list ):
                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
                 unRegister.set( meshPart )
             unRegister = genObjUnRegister()
             if isinstance( meshPart, list ):
                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
                 unRegister.set( meshPart )
-            self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, overwrite, autoDimension,
-                                       fields, geomAssocFields)
+
+            z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
+            self.mesh.SetParameters(Parameters)
+
+            self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
+                                       fields, geomAssocFields, z_tolerance)
         else:
         else:
-            self.mesh.ExportMED(fileName, auto_groups, overwrite, autoDimension)
+            self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
 
     def ExportSAUV(self, f, auto_groups=0):
         """
 
     def ExportSAUV(self, f, auto_groups=0):
         """
@@ -2340,7 +2461,7 @@ class Mesh(metaclass = MeshMeta):
     
         print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
         # process positional arguments
     
         print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
         # process positional arguments
-        args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
+        #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
         overwrite     = args[2] if len(args) > 2 else True
         fileName      = args[0]
         auto_groups   = args[1] if len(args) > 1 else False
         overwrite     = args[2] if len(args) > 2 else True
@@ -2350,8 +2471,9 @@ class Mesh(metaclass = MeshMeta):
         auto_groups   = kwargs.get("auto_groups", auto_groups) # new keyword name
         overwrite     = kwargs.get("overwrite", overwrite)
         autoDimension = kwargs.get("autoDimension", autoDimension)
         auto_groups   = kwargs.get("auto_groups", auto_groups) # new keyword name
         overwrite     = kwargs.get("overwrite", overwrite)
         autoDimension = kwargs.get("autoDimension", autoDimension)
+        minor = -1
         # invoke engine's function
         # invoke engine's function
-        self.mesh.ExportMED(fileName, auto_groups, overwrite, autoDimension)
+        self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
 
     def ExportToMEDX(self, *args, **kwargs):
         """
 
     def ExportToMEDX(self, *args, **kwargs):
         """
@@ -2374,7 +2496,7 @@ class Mesh(metaclass = MeshMeta):
 
         print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
         # process positional arguments
 
         print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
         # process positional arguments
-        args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
+        #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
         overwrite     = args[2] if len(args) > 2 else True
         fileName      = args[0]
         auto_groups   = args[1] if len(args) > 1 else False
         overwrite     = args[2] if len(args) > 2 else True
@@ -2383,14 +2505,34 @@ class Mesh(metaclass = MeshMeta):
         auto_groups   = kwargs.get("auto_groups", auto_groups)
         overwrite     = kwargs.get("overwrite", overwrite)
         autoDimension = kwargs.get("autoDimension", autoDimension)
         auto_groups   = kwargs.get("auto_groups", auto_groups)
         overwrite     = kwargs.get("overwrite", overwrite)
         autoDimension = kwargs.get("autoDimension", autoDimension)
+        minor = -1
         # invoke engine's function
         # invoke engine's function
-        self.mesh.ExportMED(fileName, auto_groups, overwrite, autoDimension)
+        self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
+        return
+
+
+    def Append(self, meshes, uniteIdenticalGroups = True,
+                     mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
+        """
+        Append given meshes into this mesh.
+        All groups of input meshes will be created in this mesh.
+
+        Parameters:
+                meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
+                uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
+                mergeNodesAndElements: if True, equal nodes and elements are merged
+                mergeTolerance: tolerance for merging nodes
+                allGroups: forces creation of groups corresponding to every input mesh
+        """
+        self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
+                                   mergeNodesAndElements, mergeTolerance, allGroups,
+                                   meshToAppendTo = self.GetMesh() )
 
     # Operations with groups:
     # ----------------------
     def CreateEmptyGroup(self, elementType, name):
         """
 
     # Operations with groups:
     # ----------------------
     def CreateEmptyGroup(self, elementType, name):
         """
-        Create an empty mesh group
+        Create an empty standalone mesh group
 
         Parameters:
                 elementType: the :class:`type <SMESH.ElementType>` of elements in the group; 
 
         Parameters:
                 elementType: the :class:`type <SMESH.ElementType>` of elements in the group; 
@@ -2425,7 +2567,7 @@ class Mesh(metaclass = MeshMeta):
     def GroupOnGeom(self, grp, name="", typ=None):
         """
         Create a mesh group based on the geometrical object *grp*
     def GroupOnGeom(self, grp, name="", typ=None):
         """
         Create a mesh group based on the geometrical object *grp*
-        and gives a *name*.
+        and give it a *name*.
         if *name* is not defined the name of the geometric group is used
 
         Parameters:
         if *name* is not defined the name of the geometric group is used
 
         Parameters:
@@ -2470,8 +2612,8 @@ class Mesh(metaclass = MeshMeta):
 
     def GroupOnFilter(self, typ, name, filter):
         """
 
     def GroupOnFilter(self, typ, name, filter):
         """
-        Create a mesh group with given *name* based on the *filter* which
-        is a special type of group dynamically updating it's contents during
+        Create a mesh group with given *name* based on the *filter*.
+        It is a special type of group dynamically updating it's contents during
         mesh modification
 
         Parameters:
         mesh modification
 
         Parameters:
@@ -2621,15 +2763,15 @@ class Mesh(metaclass = MeshMeta):
 
     def GetGroups(self, elemType = SMESH.ALL):
         """
 
     def GetGroups(self, elemType = SMESH.ALL):
         """
-        Get the list of groups existing in the mesh in the order
-        of creation (starting from the oldest one)
+        Get the list of groups existing in the mesh in the order of creation 
+        (starting from the oldest one)
 
         Parameters:
                 elemType (SMESH.ElementType): type of elements the groups contain;
                         by default groups of elements of all types are returned
 
         Returns:
 
         Parameters:
                 elemType (SMESH.ElementType): type of elements the groups contain;
                         by default groups of elements of all types are returned
 
         Returns:
-                a sequence of :class:`SMESH.SMESH_GroupBase`
+                a list of :class:`SMESH.SMESH_GroupBase`
         """
 
         groups = self.mesh.GetGroups()
         """
 
         groups = self.mesh.GetGroups()
@@ -2789,7 +2931,7 @@ class Mesh(metaclass = MeshMeta):
         Create a standalone group of entities basing on nodes of other groups.
 
         Parameters:
         Create a standalone group of entities basing on nodes of other groups.
 
         Parameters:
-                groups: list of reference :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
+                groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
                 elemType: a type of elements to include to the new group; either of
                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
                 name: a name of the new group.
                 elemType: a type of elements to include to the new group; either of
                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
                 name: a name of the new group.
@@ -2815,6 +2957,22 @@ class Mesh(metaclass = MeshMeta):
             groups = [groups]
         return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
 
             groups = [groups]
         return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
 
+    def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
+        """
+        Distribute all faces of the mesh among groups using sharp edges and optionally
+        existing 1D elements as group boundaries.
+
+        Parameters:
+                sharpAngle: edge is considered sharp if an angle between normals of
+                            adjacent faces is more than \a sharpAngle in degrees.
+                createEdges (boolean): to create 1D elements for detected sharp edges.
+                useExistingEdges (boolean): to use existing edges as group boundaries
+        Returns:
+                ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
+        """
+        sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
+        self.mesh.SetParameters(Parameters)
+        return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
 
     def ConvertToStandalone(self, group):
         """
 
     def ConvertToStandalone(self, group):
         """
@@ -3424,16 +3582,20 @@ class Mesh(metaclass = MeshMeta):
 
         return self.mesh.GetNodeXYZ(id)
 
 
         return self.mesh.GetNodeXYZ(id)
 
-    def GetNodeInverseElements(self, id):
+    def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
         """
         Return list of IDs of inverse elements for the given node.
         If there is no node for the given ID - return an empty list
 
         """
         Return list of IDs of inverse elements for the given node.
         If there is no node for the given ID - return an empty list
 
+        Parameters:
+                id: node ID
+                elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
+
         Returns:
             list of integer values
         """
 
         Returns:
             list of integer values
         """
 
-        return self.mesh.GetNodeInverseElements(id)
+        return self.mesh.GetNodeInverseElements(id,elemType)
 
     def GetNodePosition(self,NodeID):
         """
 
     def GetNodePosition(self,NodeID):
         """
@@ -3607,26 +3769,40 @@ class Mesh(metaclass = MeshMeta):
 
         Returns:
             a list of three double values
 
         Returns:
             a list of three double values
+
+        See also: 
+                :meth:`smeshBuilder.GetGravityCenter`
         """
 
         return self.mesh.BaryCenter(id)
 
         """
 
         return self.mesh.BaryCenter(id)
 
-    def GetIdsFromFilter(self, theFilter):
+    def GetIdsFromFilter(self, filter, meshParts=[] ):
         """
         Pass mesh elements through the given filter and return IDs of fitting elements
 
         Parameters:
         """
         Pass mesh elements through the given filter and return IDs of fitting elements
 
         Parameters:
-                theFilter: :class:`SMESH.Filter`
+                filter: :class:`SMESH.Filter`
+                meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
 
         Returns:
             a list of ids
 
         See Also:
             :meth:`SMESH.Filter.GetIDs`
 
         Returns:
             a list of ids
 
         See Also:
             :meth:`SMESH.Filter.GetIDs`
+            :meth:`SMESH.Filter.GetElementsIdFromParts`
         """
 
         """
 
-        theFilter.SetMesh( self.mesh )
-        return theFilter.GetIDs()
+        filter.SetMesh( self.mesh )
+
+        if meshParts:
+            if isinstance( meshParts, Mesh ):
+                filter.SetMesh( meshParts.GetMesh() )
+                return theFilter.GetIDs()
+            if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
+                meshParts = [ meshParts ]
+            return filter.GetElementsIdFromParts( meshParts )
+
+        return filter.GetIDs()
 
     # Get mesh measurements information:
     # ------------------------------------
 
     # Get mesh measurements information:
     # ------------------------------------
@@ -3658,7 +3834,9 @@ class Mesh(metaclass = MeshMeta):
                 isElem2: *True* if *id2* is element id, *False* if it is node id
 
         Returns:
                 isElem2: *True* if *id2* is element id, *False* if it is node id
 
         Returns:
-            minimum distance value **GetMinDistance()**
+            minimum distance value
+        See Also:
+            :meth:`GetMinDistance`
         """
 
         aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
         """
 
         aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
@@ -3983,7 +4161,7 @@ class Mesh(metaclass = MeshMeta):
 
     def SetNodeOnVertex(self, NodeID, Vertex):
         """
 
     def SetNodeOnVertex(self, NodeID, Vertex):
         """
-        Binds a node to a vertex
+        Bind a node to a vertex
 
         Parameters:
                 NodeID: a node ID
 
         Parameters:
                 NodeID: a node ID
@@ -4006,7 +4184,7 @@ class Mesh(metaclass = MeshMeta):
 
     def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
         """
 
     def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
         """
-        Stores the node position on an edge
+        Store the node position on an edge
 
         Parameters:
                 NodeID: a node ID
 
         Parameters:
                 NodeID: a node ID
@@ -4029,7 +4207,7 @@ class Mesh(metaclass = MeshMeta):
 
     def SetNodeOnFace(self, NodeID, Face, u, v):
         """
 
     def SetNodeOnFace(self, NodeID, Face, u, v):
         """
-        Stores node position on a face
+        Store node position on a face
 
         Parameters:
                 NodeID: a node ID
 
         Parameters:
                 NodeID: a node ID
@@ -4053,7 +4231,7 @@ class Mesh(metaclass = MeshMeta):
 
     def SetNodeInVolume(self, NodeID, Solid):
         """
 
     def SetNodeInVolume(self, NodeID, Solid):
         """
-        Binds a node to a solid
+        Bind a node to a solid
 
         Parameters:
                 NodeID: a node ID
 
         Parameters:
                 NodeID: a node ID
@@ -4146,8 +4324,6 @@ class Mesh(metaclass = MeshMeta):
             the ID of a node
         """
 
             the ID of a node
         """
 
-        #preview = self.mesh.GetMeshEditPreviewer()
-        #return preview.MoveClosestNodeToPoint(x, y, z, -1)
         return self.editor.FindNodeClosestTo(x, y, z)
 
     def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
         return self.editor.FindNodeClosestTo(x, y, z)
 
     def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
@@ -4168,10 +4344,23 @@ class Mesh(metaclass = MeshMeta):
         else:
             return self.editor.FindElementsByPoint(x, y, z, elementType)
 
         else:
             return self.editor.FindElementsByPoint(x, y, z, elementType)
 
+    def ProjectPoint(self, x,y,z, elementType, meshObject=None):
+        """
+        Project a point to a mesh object.
+        Return ID of an element of given type where the given point is projected
+        and coordinates of the projection point.
+        In the case if nothing found, return -1 and []
+        """
+        if isinstance( meshObject, Mesh ):
+            meshObject = meshObject.GetMesh()
+        if not meshObject:
+            meshObject = self.GetMesh()
+        return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
+
     def GetPointState(self, x, y, z):
         """
         Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
     def GetPointState(self, x, y, z):
         """
         Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
-        0-IN, 1-OUT, 2-ON, 3-UNKNOWN.
+        smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
         UNKNOWN state means that either mesh is wrong or the analysis fails.
         """
 
         UNKNOWN state means that either mesh is wrong or the analysis fails.
         """
 
@@ -4191,6 +4380,40 @@ class Mesh(metaclass = MeshMeta):
 
         return self.editor.IsCoherentOrientation2D()
 
 
         return self.editor.IsCoherentOrientation2D()
 
+    def Get1DBranches( self, edges, startNode = 0 ):
+        """
+        Partition given 1D elements into groups of contiguous edges.
+        A node where number of meeting edges != 2 is a group end.
+        An optional startNode is used to orient groups it belongs to.
+
+        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.
+             If a group is closed, the first and last nodes of the group are same.
+        """
+        if isinstance( edges, Mesh ):
+            edges = edges.GetMesh()
+        unRegister = genObjUnRegister()
+        if isinstance( edges, list ):
+            edges = self.GetIDSource( edges, SMESH.EDGE )
+            unRegister.set( edges )
+        return self.editor.Get1DBranches( edges, startNode )
+    
+    def FindSharpEdges( self, angle, addExisting=False ):
+        """
+        Return sharp edges of faces and non-manifold ones.
+        Optionally add existing edges.
+
+        Parameters:
+                angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
+                addExisting: to return existing edges (1D elements) as well
+
+        Returns:
+            list of FaceEdge structures
+        """
+        angle = ParseParameters( angle )[0]
+        return self.editor.FindSharpEdges( angle, addExisting )
+
     def MeshToPassThroughAPoint(self, x, y, z):
         """
         Find the node closest to a point and moves it to a point location
     def MeshToPassThroughAPoint(self, x, y, z):
         """
         Find the node closest to a point and moves it to a point location
@@ -4465,7 +4688,7 @@ class Mesh(metaclass = MeshMeta):
 
         Parameters:
                 IDsOfElements: the faces to be splitted
 
         Parameters:
                 IDsOfElements: the faces to be splitted
-                Diag13:        is used to choose a diagonal for splitting.
+                Diag13 (boolean):        is used to choose a diagonal for splitting.
 
         Returns:
             True in case of success, False otherwise.
 
         Returns:
             True in case of success, False otherwise.
@@ -4481,7 +4704,7 @@ class Mesh(metaclass = MeshMeta):
         Parameters:
                 theObject: the object from which the list of elements is taken,
                         this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
         Parameters:
                 theObject: the object from which the list of elements is taken,
                         this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
-                Diag13:    is used to choose a diagonal for splitting.
+                Diag13 (boolean):    is used to choose a diagonal for splitting.
 
         Returns:
             True in case of success, False otherwise.
 
         Returns:
             True in case of success, False otherwise.
@@ -4966,7 +5189,7 @@ class Mesh(metaclass = MeshMeta):
                 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
 
         Returns:
                 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
 
         Returns:
-                tuple( long, mesh, groups )
+                tuple( long, mesh, group )
                        - long - number of added boundary elements
                        - mesh - the :class:`Mesh` where elements were added to
                        - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
                        - long - number of added boundary elements
                        - mesh - the :class:`Mesh` where elements were added to
                        - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
@@ -5143,7 +5366,8 @@ class Mesh(metaclass = MeshMeta):
                                          NbOfSteps, Tolerance, MakeGroups, TotalAngle)
 
     def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
                                          NbOfSteps, Tolerance, MakeGroups, TotalAngle)
 
     def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
-                              scaleFactors=[], linearVariation=False, basePoint=[] ):
+                              scaleFactors=[], linearVariation=False, basePoint=[],
+                              angles=[], anglesVariation=False):
         """
         Generate new elements by extrusion of the given elements and nodes
 
         """
         Generate new elements by extrusion of the given elements and nodes
 
@@ -5157,15 +5381,19 @@ class Mesh(metaclass = MeshMeta):
             NbOfSteps: the number of steps
             MakeGroups: forces the generation of new groups from existing ones
             scaleFactors: optional scale factors to apply during extrusion
             NbOfSteps: the number of steps
             MakeGroups: forces the generation of new groups from existing ones
             scaleFactors: optional scale factors to apply during extrusion
-            linearVariation: if *True*, scaleFactors are spread over all *scaleFactors*,
-                else scaleFactors[i] is applied to nodes at the i-th extrusion step
-            basePoint: optional scaling center; if not provided, a gravity center of
+            linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
+                else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
+            basePoint: optional scaling and rotation center; if not provided, a gravity center of
                 nodes and elements being extruded is used as the scaling center.
                 It can be either
 
                         - a list of tree components of the point or
                         - a node ID or
                         - a GEOM point
                 nodes and elements being extruded is used as the scaling center.
                 It can be either
 
                         - a list of tree components of the point or
                         - a node ID or
                         - a GEOM point
+            angles: list of angles in radians. Nodes at each extrusion step are rotated 
+                around *basePoint*, additionally to previous steps.
+            anglesVariation: forces the computation of rotation angles as linear
+                variation of the given *angles* along path steps
         Returns:
             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
 
         Returns:
             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
 
@@ -5190,13 +5418,17 @@ class Mesh(metaclass = MeshMeta):
             basePoint = self.geompyD.PointCoordinates( basePoint )
 
         NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
             basePoint = self.geompyD.PointCoordinates( basePoint )
 
         NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
-        Parameters = StepVector.PS.parameters + var_separator + Parameters
+        scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
+        angles,angleParameters,hasVars = ParseAngles(angles)
+        Parameters = StepVector.PS.parameters + var_separator + \
+                     Parameters + var_separator + \
+                     scaleParameters + var_separator + angleParameters
         self.mesh.SetParameters(Parameters)
 
         return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
         self.mesh.SetParameters(Parameters)
 
         return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
-                                                  StepVector, NbOfSteps,
+                                                  StepVector, NbOfSteps, MakeGroups,
                                                   scaleFactors, linearVariation, basePoint,
                                                   scaleFactors, linearVariation, basePoint,
-                                                  MakeGroups)
+                                                  angles, anglesVariation )
 
 
     def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
 
 
     def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
@@ -5358,9 +5590,10 @@ class Mesh(metaclass = MeshMeta):
         return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
                                              ExtrFlags, SewTolerance, MakeGroups)
 
         return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
                                              ExtrFlags, SewTolerance, MakeGroups)
 
-    def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
+    def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
                                   NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
                                   NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
-                                  HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
+                                  HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
+                                  ScaleFactors=[], ScalesVariation=False):
         """
         Generate new elements by extrusion of the given elements and nodes along the path.
         The path of extrusion must be a meshed edge.
         """
         Generate new elements by extrusion of the given elements and nodes along the path.
         The path of extrusion must be a meshed edge.
@@ -5369,20 +5602,22 @@ class Mesh(metaclass = MeshMeta):
             Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
             Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
             Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
             Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
             Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
             Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
-            PathMesh: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
-            PathShape: shape (edge) defines the sub-mesh of PathMesh if PathMesh
-                contains not only path segments, else it can be None
+            PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
+            PathShape: optional shape (edge or wire) which defines the sub-mesh of the mesh defined by *PathObject* if the mesh contains not only path segments, else it can be None
             NodeStart: the first or the last node on the path. Defines the direction of extrusion
             NodeStart: the first or the last node on the path. Defines the direction of extrusion
-            HasAngles: allows the shape to be rotated around the path
-                to get the resulting mesh in a helical fashion
-            Angles: list of angles
+            HasAngles: not used obsolete
+            Angles: list of angles in radians. Nodes at each extrusion step are rotated 
+                around *basePoint*, additionally to previous steps.
             LinearVariation: forces the computation of rotation angles as linear
                 variation of the given Angles along path steps
             HasRefPoint: allows using the reference point
             LinearVariation: forces the computation of rotation angles as linear
                 variation of the given Angles along path steps
             HasRefPoint: allows using the reference point
-            RefPoint: the reference point around which the shape is rotated (the mass center of the
-                shape by default). The User can specify any point as the Reference Point. 
+            RefPoint: optional scaling and rotation center (mass center of the extruded
+                elements by default). The User can specify any point as the Reference Point. 
                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
             MakeGroups: forces the generation of new groups from existing ones
                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
             MakeGroups: forces the generation of new groups from existing ones
+            ScaleFactors: optional scale factors to apply during extrusion
+            ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
+                else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
 
         Returns:
             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
 
         Returns:
             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
@@ -5400,15 +5635,18 @@ class Mesh(metaclass = MeshMeta):
         if isinstance( RefPoint, list ):
             if not RefPoint: RefPoint = [0,0,0]
             RefPoint = SMESH.PointStruct( *RefPoint )
         if isinstance( RefPoint, list ):
             if not RefPoint: RefPoint = [0,0,0]
             RefPoint = SMESH.PointStruct( *RefPoint )
-        if isinstance( PathMesh, Mesh ):
-            PathMesh = PathMesh.GetMesh()
+        if isinstance( PathObject, Mesh ):
+            PathObject = PathObject.GetMesh()
         Angles,AnglesParameters,hasVars = ParseAngles(Angles)
         Angles,AnglesParameters,hasVars = ParseAngles(Angles)
-        Parameters = AnglesParameters + var_separator + RefPoint.parameters
+        ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
+        Parameters = AnglesParameters + var_separator + \
+                     RefPoint.parameters + var_separator + ScalesParameters 
         self.mesh.SetParameters(Parameters)
         return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
         self.mesh.SetParameters(Parameters)
         return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
-                                                     PathMesh, PathShape, NodeStart,
+                                                     PathObject, PathShape, NodeStart,
                                                      HasAngles, Angles, LinearVariation,
                                                      HasAngles, Angles, LinearVariation,
-                                                     HasRefPoint, RefPoint, MakeGroups)
+                                                     HasRefPoint, RefPoint, MakeGroups,
+                                                     ScaleFactors, ScalesVariation)
 
     def ExtrusionAlongPathX(self, Base, Path, NodeStart,
                             HasAngles=False, Angles=[], LinearVariation=False,
 
     def ExtrusionAlongPathX(self, Base, Path, NodeStart,
                             HasAngles=False, Angles=[], LinearVariation=False,
@@ -5422,9 +5660,9 @@ class Mesh(metaclass = MeshMeta):
             Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
             Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
             NodeStart: the start node from Path. Defines the direction of extrusion
             Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
             Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
             NodeStart: the start node from Path. Defines the direction of extrusion
-            HasAngles: allows the shape to be rotated around the path
-                to get the resulting mesh in a helical fashion
-            Angles: list of angles in radians
+            HasAngles: not used obsolete
+            Angles: list of angles in radians. Nodes at each extrusion step are rotated 
+                around *basePoint*, additionally to previous steps.
             LinearVariation: forces the computation of rotation angles as linear
                 variation of the given Angles along path steps
             HasRefPoint: allows using the reference point
             LinearVariation: forces the computation of rotation angles as linear
                 variation of the given Angles along path steps
             HasRefPoint: allows using the reference point
@@ -5465,9 +5703,9 @@ class Mesh(metaclass = MeshMeta):
             PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
             PathShape: shape (edge) defines the sub-mesh for the path
             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
             PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
             PathShape: shape (edge) defines the sub-mesh for the path
             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
-            HasAngles: allows the shape to be rotated around the path
-                to get the resulting mesh in a helical fashion
-            Angles: list of angles in radians
+            HasAngles: not used obsolete
+            Angles: list of angles in radians. Nodes at each extrusion step are rotated 
+                around *basePoint*, additionally to previous steps.
             HasRefPoint: allows using the reference point
             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
                 The User can specify any point as the Reference Point.
             HasRefPoint: allows using the reference point
             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
                 The User can specify any point as the Reference Point.
@@ -5483,6 +5721,8 @@ class Mesh(metaclass = MeshMeta):
         Example: :ref:`tui_extrusion_along_path`
         """
 
         Example: :ref:`tui_extrusion_along_path`
         """
 
+        if not IDsOfElements:
+            IDsOfElements = [ self.GetMesh() ]
         n,e,f = [],IDsOfElements,IDsOfElements
         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
                                                NodeStart, HasAngles, Angles,
         n,e,f = [],IDsOfElements,IDsOfElements
         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
                                                NodeStart, HasAngles, Angles,
@@ -5504,9 +5744,9 @@ class Mesh(metaclass = MeshMeta):
             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
             PathShape: shape (edge) defines the sub-mesh for the path
             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
             PathShape: shape (edge) defines the sub-mesh for the path
             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
-            HasAngles: allows the shape to be rotated around the path
-                to get the resulting mesh in a helical fashion
-            Angles: list of angles
+            HasAngles: not used obsolete
+            Angles: list of angles in radians. Nodes at each extrusion step are rotated 
+                around *basePoint*, additionally to previous steps.
             HasRefPoint: allows using the reference point
             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
                 The User can specify any point as the Reference Point.
             HasRefPoint: allows using the reference point
             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
                 The User can specify any point as the Reference Point.
@@ -5542,9 +5782,9 @@ class Mesh(metaclass = MeshMeta):
             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
             PathShape: shape (edge) defines the sub-mesh for the path
             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
             PathShape: shape (edge) defines the sub-mesh for the path
             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
-            HasAngles: allows the shape to be rotated around the path
-                to get the resulting mesh in a helical fashion
-            Angles: list of angles
+            HasAngles: not used obsolete
+            Angles: list of angles in radians. Nodes at each extrusion step are rotated 
+                around *basePoint*, additionally to previous steps.
             HasRefPoint: allows using the reference point
             RefPoint:  the reference point around which the shape is rotated (the mass center of the shape by default).
                 The User can specify any point as the Reference Point.
             HasRefPoint: allows using the reference point
             RefPoint:  the reference point around which the shape is rotated (the mass center of the shape by default).
                 The User can specify any point as the Reference Point.
@@ -5580,9 +5820,9 @@ class Mesh(metaclass = MeshMeta):
             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
             PathShape: shape (edge) defines the sub-mesh for the path
             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
             PathShape: shape (edge) defines the sub-mesh for the path
             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
-            HasAngles: allows the shape to be rotated around the path
-                to get the resulting mesh in a helical fashion
-            Angles: list of angles
+            HasAngles: not used obsolete
+            Angles: list of angles in radians. Nodes at each extrusion step are rotated 
+                around *basePoint*, additionally to previous steps.
             HasRefPoint: allows using the reference point
             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
                 The User can specify any point as the Reference Point.
             HasRefPoint: allows using the reference point
             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
                 The User can specify any point as the Reference Point.
@@ -5612,7 +5852,7 @@ class Mesh(metaclass = MeshMeta):
         Parameters:
             IDsOfElements: list of elements ids
             Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
         Parameters:
             IDsOfElements: list of elements ids
             Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
-            theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
+            theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
                 If the *Mirror* is a geom object this parameter is unnecessary
             Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
             MakeGroups: forces the generation of new groups from existing ones (if Copy)
                 If the *Mirror* is a geom object this parameter is unnecessary
             Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
             MakeGroups: forces the generation of new groups from existing ones (if Copy)
@@ -5640,7 +5880,7 @@ class Mesh(metaclass = MeshMeta):
         Parameters:
             IDsOfElements: the list of elements ids
             Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
         Parameters:
             IDsOfElements: the list of elements ids
             Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
-            theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
+            theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
                 If the *Mirror* is a geom object this parameter is unnecessary
             MakeGroups: to generate new groups from existing ones
             NewMeshName: a name of the new mesh to create
                 If the *Mirror* is a geom object this parameter is unnecessary
             MakeGroups: to generate new groups from existing ones
             NewMeshName: a name of the new mesh to create
@@ -5667,7 +5907,7 @@ class Mesh(metaclass = MeshMeta):
         Parameters:
             theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
             Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
         Parameters:
             theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
             Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
-            theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
+            theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
                 If the *Mirror* is a geom object this parameter is unnecessary
             Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
             MakeGroups: forces the generation of new groups from existing ones (if Copy)
                 If the *Mirror* is a geom object this parameter is unnecessary
             Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
             MakeGroups: forces the generation of new groups from existing ones (if Copy)
@@ -5695,7 +5935,7 @@ class Mesh(metaclass = MeshMeta):
         Parameters:
             theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
             Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
         Parameters:
             theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
             Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
-            theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
+            theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
                 If the *Mirror* is a geom object this parameter is unnecessary
             MakeGroups: forces the generation of new groups from existing ones
             NewMeshName: the name of the new mesh to create
                 If the *Mirror* is a geom object this parameter is unnecessary
             MakeGroups: forces the generation of new groups from existing ones
             NewMeshName: the name of the new mesh to create
@@ -6042,7 +6282,7 @@ class Mesh(metaclass = MeshMeta):
 
         Parameters:
             Tolerance: the value of tolerance
 
         Parameters:
             Tolerance: the value of tolerance
-            SubMeshOrGroup: :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`
+            SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
             exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
             SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
                 corner and medium nodes in separate groups thus preventing
             exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
             SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
                 corner and medium nodes in separate groups thus preventing
@@ -6053,13 +6293,23 @@ class Mesh(metaclass = MeshMeta):
         """
 
         unRegister = genObjUnRegister()
         """
 
         unRegister = genObjUnRegister()
-        if (isinstance( SubMeshOrGroup, Mesh )):
-            SubMeshOrGroup = SubMeshOrGroup.GetMesh()
+        if not isinstance( SubMeshOrGroup, list ):
+            SubMeshOrGroup = [ SubMeshOrGroup ]
+        for i,obj in enumerate( SubMeshOrGroup ):
+            if isinstance( obj, Mesh ):
+                SubMeshOrGroup = [ obj.GetMesh() ]
+                break
+            if isinstance( obj, int ):
+                SubMeshOrGroup = self.GetIDSource( SubMeshOrGroup, SMESH.NODE )
+                unRegister.set( SubMeshOrGroup )
+                break
+
         if not isinstance( exceptNodes, list ):
             exceptNodes = [ exceptNodes ]
         if exceptNodes and isinstance( exceptNodes[0], int ):
             exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
             unRegister.set( exceptNodes )
         if not isinstance( exceptNodes, list ):
             exceptNodes = [ exceptNodes ]
         if exceptNodes and isinstance( exceptNodes[0], int ):
             exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
             unRegister.set( exceptNodes )
+
         return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
                                                         exceptNodes, SeparateCornerAndMediumNodes)
 
         return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
                                                         exceptNodes, SeparateCornerAndMediumNodes)
 
@@ -6070,44 +6320,72 @@ class Mesh(metaclass = MeshMeta):
         Parameters:
             GroupsOfNodes: a list of groups of nodes IDs for merging.
                 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
         Parameters:
             GroupsOfNodes: a list of groups of nodes IDs for merging.
                 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
-                in all elements and groups by nodes 1 and 25 correspondingly
+                in all elements and mesh groups by nodes 1 and 25 correspondingly
             NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
                 If *NodesToKeep* does not include a node to keep for some group to merge,
                 then the first node in the group is kept.
             AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
                 invalid
         """
             NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
                 If *NodesToKeep* does not include a node to keep for some group to merge,
                 then the first node in the group is kept.
             AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
                 invalid
         """
-        # NodesToKeep are converted to SMESH.SMESH_IDSource in meshEditor.MergeNodes()
         self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
 
         self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
 
-    def FindEqualElements (self, MeshOrSubMeshOrGroup=None):
+    def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
         """
         Find the elements built on the same nodes.
 
         Parameters:
         """
         Find the elements built on the same nodes.
 
         Parameters:
-            MeshOrSubMeshOrGroup: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
+            MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
+            exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
+
 
         Returns:
             the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
         """
 
 
         Returns:
             the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
         """
 
-        if not MeshOrSubMeshOrGroup:
-            MeshOrSubMeshOrGroup=self.mesh
+        unRegister = genObjUnRegister()
+        if MeshOrSubMeshOrGroup is None:
+            MeshOrSubMeshOrGroup = [ self.mesh ]
         elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
         elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
-            MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh()
-        return self.editor.FindEqualElements( MeshOrSubMeshOrGroup )
-
-    def MergeElements(self, GroupsOfElementsID):
+            MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
+        elif not isinstance( MeshOrSubMeshOrGroup, list ):
+            MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
+        if isinstance( MeshOrSubMeshOrGroup[0], int ):
+            MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
+            unRegister.set( MeshOrSubMeshOrGroup )
+        for item in MeshOrSubMeshOrGroup:
+            if isinstance( item, Mesh ):
+                MeshOrSubMeshOrGroup = [ item.GetMesh() ]
+
+        if not isinstance( exceptElements, list ):
+            exceptElements = [ exceptElements ]
+        if exceptElements and isinstance( exceptElements[0], int ):
+            exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
+            unRegister.set( exceptElements )
+
+        return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
+
+    def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
         """
         Merge elements in each given group.
 
         Parameters:
             GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
                 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
         """
         Merge elements in each given group.
 
         Parameters:
             GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
                 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
-                replaced in all groups by elements 1 and 25)
+                replaced in all mesh groups by elements 1 and 25)
+            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.
         """
 
         """
 
-        self.editor.MergeElements(GroupsOfElementsID)
+        unRegister = genObjUnRegister()
+        if ElementsToKeep:
+            if not isinstance( ElementsToKeep, list ):
+                ElementsToKeep = [ ElementsToKeep ]
+            if isinstance( ElementsToKeep[0], int ):
+                ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
+                unRegister.set( ElementsToKeep )
+
+        self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
 
     def MergeEqualElements(self):
         """
 
     def MergeEqualElements(self):
         """
@@ -6126,14 +6404,17 @@ class Mesh(metaclass = MeshMeta):
 
         return self.editor.FindFreeBorders( ClosedOnly )
 
 
         return self.editor.FindFreeBorders( ClosedOnly )
 
-    def FillHole(self, holeNodes):
+    def FillHole(self, holeNodes, groupName=""):
         """
         Fill with 2D elements a hole defined by a SMESH.FreeBorder.
 
         Parameters:
         """
         Fill with 2D elements a hole defined by a SMESH.FreeBorder.
 
         Parameters:
-            FreeBorder: either a SMESH.FreeBorder or a list on node IDs. These nodes
+            holeNodes: 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 :meth:`FindFreeBorders` to get nodes of holes.
                 must describe all sequential nodes of the hole border. The first and the last
                 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
+            groupName (string): name of a group to add new faces
+        Returns:
+            a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
         """
 
 
         """
 
 
@@ -6141,7 +6422,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)
             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 )
+        self.editor.FillHole( holeNodes, groupName )
 
     def FindCoincidentFreeBorders (self, tolerance=0.):
         """
 
     def FindCoincidentFreeBorders (self, tolerance=0.):
         """
@@ -6591,7 +6872,7 @@ class Mesh(metaclass = MeshMeta):
     def MakePolyLine(self, segments, groupName='', isPreview=False ):
         """    
         Create a polyline consisting of 1D mesh elements each lying on a 2D element of
     def MakePolyLine(self, segments, groupName='', isPreview=False ):
         """    
         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
+        the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
         plane passing through pairs of points specified by each :class:`SMESH.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
         plane passing through pairs of points specified by each :class:`SMESH.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
@@ -6601,12 +6882,12 @@ class Mesh(metaclass = MeshMeta):
         The vector goes from the middle point to the projection point. In case of planar
         mesh, the vector is normal 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.
 
-        *segments* [i].vector returns the used vector which goes from the middle point to its projection.
+        In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
 
 
-        Parameters:        
+        Parameters:
             segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
             groupName: optional name of a group where created mesh segments will be added.
             segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
             groupName: optional name of a group where created mesh segments will be added.
-            
+
         """    
         editor = self.editor
         if isPreview:
         """    
         editor = self.editor
         if isPreview:
@@ -6616,7 +6897,18 @@ class Mesh(metaclass = MeshMeta):
             segments[i].vector = seg.vector
         if isPreview:
             return editor.GetPreviewData()
             segments[i].vector = seg.vector
         if isPreview:
             return editor.GetPreviewData()
-        return None        
+        return None
+
+    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
+        around each segment. Segments are expected to be created by MakePolyLine().
+
+        Returns:
+               FaceEdge's located at the slot boundary
+        """
+        return self.editor.MakeSlot( segmentGroup, width )
 
     def GetFunctor(self, funcType ):
         """
 
     def GetFunctor(self, funcType ):
         """
@@ -6709,6 +7001,24 @@ class Mesh(metaclass = MeshMeta):
             volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
         return volume
 
             volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
         return volume
 
+    def GetAngle(self, node1, node2, node3 ):
+        """
+        Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
+
+        Parameters:            
+                node1,node2,node3: IDs of the three nodes
+
+        Returns:        
+            Angle in radians [0,PI]. -1 if failure case.
+        """
+        p1 = self.GetNodeXYZ( node1 )
+        p2 = self.GetNodeXYZ( node2 )
+        p3 = self.GetNodeXYZ( node3 )
+        if p1 and p2 and p3:
+            return self.smeshpyD.GetAngle( p1,p2,p3 )
+        return -1.
+
+
     def GetMaxElementLength(self, elemId):
         """
         Get maximum element length.
     def GetMaxElementLength(self, elemId):
         """
         Get maximum element length.
@@ -6846,22 +7156,24 @@ class meshProxy(SMESH._objref_SMESH_Mesh):
         return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
     def ExportToMEDX(self, *args): # function removed
         print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
         return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
     def ExportToMEDX(self, *args): # function removed
         print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
-        args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
+        #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
         SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
     def ExportToMED(self, *args): # function removed
         print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
         SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
     def ExportToMED(self, *args): # function removed
         print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
-        args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
-        while len(args) < 4:  # !!!! nb of parameters for ExportToMED IDL's method
-            args.append(True)
-        SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
+        #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
+        args2 = list(args)
+        while len(args2) < 5:  # !!!! nb of parameters for ExportToMED IDL's method
+            args2.append(True)
+        SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
     def ExportPartToMED(self, *args): # 'version' parameter removed
     def ExportPartToMED(self, *args): # 'version' parameter removed
-        args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
+        #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
         SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
     def ExportMED(self, *args): # signature of method changed
         SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
     def ExportMED(self, *args): # signature of method changed
-        args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
-        while len(args) < 4:  # !!!! nb of parameters for ExportToMED IDL's method
-            args.append(True)
-        SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
+        #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
+        args2 = list(args)
+        while len(args2) < 5:  # !!!! nb of parameters for ExportToMED IDL's method
+            args2.append(True)
+        SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
     pass
 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
 
     pass
 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
 
@@ -6898,9 +7210,6 @@ class submeshProxy(SMESH._objref_SMESH_subMesh):
         ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
 
         if salome.sg.hasDesktop():
         ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
 
         if salome.sg.hasDesktop():
-            smeshgui = salome.ImportComponentGUI("SMESH")
-            smeshgui.Init()
-            smeshgui.SetMeshIcon( salome.ObjectToID( self ), ok, (self.GetNumberOfElements()==0) )
             if refresh: salome.sg.updateObjBrowser()
             pass
 
             if refresh: salome.sg.updateObjBrowser()
             pass