Salome HOME
NPAL18095: Pb. with dump python and mesh group by filter.
[modules/smesh.git] / src / SMESH_SWIG / smesh.py
index d7a687e935d9f5cf9254777509a576b888f4b24a..15f933c85096a00f0f91b946dad950cb891096f7 100644 (file)
 import salome
 import geompy
 
-import SMESH
+import SMESH # necessary for back compatibility
 from   SMESH import *
 
 import StdMeshers
 
+import SALOME
+
 # import NETGENPlugin module if possible
 noNETGENPlugin = 0
 try:
@@ -43,13 +45,18 @@ except ImportError:
     pass
     
 # Types of algo
-REGULAR = 1
-PYTHON  = 2
-
-MEFISTO = 3
-NETGEN  = 4
-GHS3D   = 5
-FULL_NETGEN = 6
+REGULAR    = 1
+PYTHON     = 2
+COMPOSITE  = 3
+
+MEFISTO       = 3
+NETGEN        = 4
+GHS3D         = 5
+FULL_NETGEN   = 6
+NETGEN_2D     = 7
+NETGEN_1D2D   = NETGEN
+NETGEN_1D2D3D = FULL_NETGEN
+NETGEN_FULL   = FULL_NETGEN
 
 # MirrorType enumeration
 POINT = SMESH_MeshEditor.POINT
@@ -121,6 +128,13 @@ def GetDirStruct(theVector):
     dir = DirStruct(pnt)
     return dir
 
+## Make DirStruct from a triplet
+#  @param x,y,z are vector components
+#  @return SMESH.DirStruct
+def MakeDirStruct(x,y,z):
+    pnt = PointStruct(x,y,z)
+    return DirStruct(pnt)
+
 ## Get AxisStruct from object
 #  @param theObj is GEOM object(line or plane)
 #  @return SMESH.AxisStruct
@@ -268,7 +282,7 @@ def GetCriterion(elementType,
             print "Error: Treshold should be a string."
             return None
     elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_BadOrientedVolume]:
-        # Here we don't need treshold
+        # Here we do not need treshold
         if aTreshold ==  FT_LogicalNOT:
             aCriterion.UnaryOp = EnumToLong(FT_LogicalNOT)
         elif aTreshold in [FT_LogicalAND, FT_LogicalOR]:
@@ -349,7 +363,7 @@ def GetFunctor(theCriterion):
         print "Error: given parameter is not numerucal functor type."
 
 
-## Private method. Print error message if a hypothesis was not assigned.
+## Print error message if a hypothesis was not assigned.
 def TreatHypoStatus(status, hypName, geomName, isAlgo):
     if isAlgo:
         hypType = "algorithm"
@@ -388,7 +402,7 @@ def TreatHypoStatus(status, hypName, geomName, isAlgo):
 
     
     
-## Mother class to define algorithm, recommended to don't use directly.
+## Mother class to define algorithm, recommended to do not use directly.
 #
 #  More details.
 class Mesh_Algorithm:
@@ -399,6 +413,13 @@ class Mesh_Algorithm:
     geom = 0
     subm = 0
     algo = 0
+    hypos = {}
+
+    def FindHypothesis(self,hypname, args):
+        key = "%s %s %s" % (self.__class__.__name__, hypname, args)
+        if Mesh_Algorithm.hypos.has_key( key ):
+            return Mesh_Algorithm.hypos[ key ]
+        return None
 
     ## If the algorithm is global, return 0; \n
     #  else return the submesh associated to this algorithm.
@@ -430,41 +451,57 @@ class Mesh_Algorithm:
     
     ## Private method.
     def Create(self, mesh, geom, hypo, so="libStdMeshersEngine.so"):
+        if geom is None:
+            raise RuntimeError, "Attemp to create " + hypo + " algoritm on None shape"
+        algo = smesh.CreateHypothesis(hypo, so)
+        self.Assign(algo, mesh, geom)
+        return self.algo
+
+    ## Private method
+    def Assign(self, algo, mesh, geom):
         if geom is None:
             raise RuntimeError, "Attemp to create " + hypo + " algoritm on None shape"
         self.mesh = mesh
         piece = mesh.geom
-        if geom==0:
+        if not geom:
             self.geom = piece
-            name = GetName(piece)
         else:
             self.geom = geom
             name = GetName(geom)
             if name==NO_NAME:
                 name = geompy.SubShapeName(geom, piece)
                 geompy.addToStudyInFather(piece, geom, name)
-            self.subm = mesh.mesh.GetSubMesh(geom, hypo)
+            self.subm = mesh.mesh.GetSubMesh(geom, algo.GetName())
 
-        self.algo = smesh.CreateHypothesis(hypo, so)
-        SetName(self.algo, name + "/" + hypo)
+        self.algo = algo
         status = mesh.mesh.AddHypothesis(self.geom, self.algo)
-        TreatHypoStatus( status, hypo, name, 1 )
-        
+        TreatHypoStatus( status, algo.GetName(), GetName(self.geom), True )
+
     ## Private method
-    def Hypothesis(self, hyp, args=[], so="libStdMeshersEngine.so"):
-        hypo = smesh.CreateHypothesis(hyp, so)
-        a = ""
-        s = "="
-        i = 0
-        n = len(args)
-        while i<n:
-            a = a + s + str(args[i])
-            s = ","
-            i = i + 1
-        name = GetName(self.geom)
-        SetName(hypo, name + "/" + hyp + a)
+    def Hypothesis(self, hyp, args=[], so="libStdMeshersEngine.so", UseExisting=0):
+        CreateNew = 1
+        if UseExisting:
+            hypo = self.FindHypothesis(hyp, args)
+            if hypo: CreateNew = 0
+            pass
+        if CreateNew:
+            hypo = smesh.CreateHypothesis(hyp, so)
+            key = "%s %s %s" % (self.__class__.__name__, hyp, args)
+            Mesh_Algorithm.hypos[key] = hypo
+            a = ""
+            s = "="
+            i = 0
+            n = len(args)
+            while i<n:
+                a = a + s + str(args[i])
+                s = ","
+                i = i + 1
+                name = GetName(self.geom)
+            #SetName(hypo, name + "/" + hyp + a) - NPAL16198
+            SetName(hypo, hyp + a)
+            pass
         status = self.mesh.mesh.AddHypothesis(self.geom, hypo)
-        TreatHypoStatus( status, hyp, name, 0 )
+        TreatHypoStatus( status, GetName(hypo), GetName(self.geom), 0 )
         return hypo
 
 
@@ -476,25 +513,35 @@ class Mesh_Algorithm:
 #  More details.
 class Mesh_Segment(Mesh_Algorithm):
 
+    algo = 0 # algorithm object common for all Mesh_Segments
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "Regular_1D")
-        
+        if not Mesh_Segment.algo:
+            Mesh_Segment.algo = self.Create(mesh, geom, "Regular_1D")
+        else:
+            self.Assign( Mesh_Segment.algo, mesh, geom)
+            pass
+
     ## Define "LocalLength" hypothesis to cut an edge in several segments with the same length
     #  @param l for the length of segments that cut an edge
-    def LocalLength(self, l):
-        hyp = self.Hypothesis("LocalLength", [l])
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def LocalLength(self, l, UseExisting=0):
+        hyp = self.Hypothesis("LocalLength", [l], UseExisting=UseExisting)
         hyp.SetLength(l)
         return hyp
         
     ## Define "NumberOfSegments" hypothesis to cut an edge in several fixed number of segments
     #  @param n for the number of segments that cut an edge
     #  @param s for the scale factor (optional)
-    def NumberOfSegments(self, n, s=[]):
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def NumberOfSegments(self, n, s=[], UseExisting=0):
         if s == []:
-            hyp = self.Hypothesis("NumberOfSegments", [n])
+            hyp = self.Hypothesis("NumberOfSegments", [n], UseExisting=UseExisting)
         else:
-            hyp = self.Hypothesis("NumberOfSegments", [n,s])
+            hyp = self.Hypothesis("NumberOfSegments", [n,s], UseExisting=UseExisting)
             hyp.SetDistrType( 1 )
             hyp.SetScaleFactor(s)
         hyp.SetNumberOfSegments(n)
@@ -503,8 +550,10 @@ class Mesh_Segment(Mesh_Algorithm):
     ## Define "Arithmetic1D" hypothesis to cut an edge in several segments with arithmetic length increasing
     #  @param start for the length of the first segment
     #  @param end   for the length of the last  segment
-    def Arithmetic1D(self, start, end):
-        hyp = self.Hypothesis("Arithmetic1D", [start, end])
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def Arithmetic1D(self, start, end, UseExisting=0):
+        hyp = self.Hypothesis("Arithmetic1D", [start, end], UseExisting=UseExisting)
         hyp.SetLength(start, 1)
         hyp.SetLength(end  , 0)
         return hyp
@@ -512,31 +561,57 @@ class Mesh_Segment(Mesh_Algorithm):
     ## Define "StartEndLength" hypothesis to cut an edge in several segments with geometric length increasing
     #  @param start for the length of the first segment
     #  @param end   for the length of the last  segment
-    def StartEndLength(self, start, end):
-        hyp = self.Hypothesis("StartEndLength", [start, end])
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def StartEndLength(self, start, end, UseExisting=0):
+        hyp = self.Hypothesis("StartEndLength", [start, end], UseExisting=UseExisting)
         hyp.SetLength(start, 1)
         hyp.SetLength(end  , 0)
         return hyp
         
     ## Define "Deflection1D" hypothesis
     #  @param d for the deflection
-    def Deflection1D(self, d):
-        hyp = self.Hypothesis("Deflection1D", [d])
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def Deflection1D(self, d, UseExisting=0):
+        hyp = self.Hypothesis("Deflection1D", [d], UseExisting=UseExisting)
         hyp.SetDeflection(d)
         return hyp
         
     ## Define "Propagation" hypothesis that propagate all other hypothesis on all others edges that are in
     #  the opposite side in the case of quadrangular faces
     def Propagation(self):
-        return self.Hypothesis("Propagation")
+        return self.Hypothesis("Propagation", UseExisting=1)
 
     ## Define "AutomaticLength" hypothesis
     #  @param fineness for the fineness [0-1]
-    def AutomaticLength(self, fineness=0):
-        hyp = self.Hypothesis("AutomaticLength")
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def AutomaticLength(self, fineness=0, UseExisting=0):
+        hyp = self.Hypothesis("AutomaticLength",[fineness],UseExisting=UseExisting)
         hyp.SetFineness( fineness )
         return hyp
 
+    ## Define "SegmentLengthAroundVertex" hypothesis
+    #  @param length for the segment length
+    #  @param vertex for the length localization: vertex index [0,1] | verext object
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def LengthNearVertex(self, length, vertex=0, UseExisting=0):
+        import types
+        store_geom = self.geom
+        if vertex:
+            if type(vertex) is types.IntType:
+                vertex = geompy.SubShapeAllSorted(self.geom,geompy.ShapeType["VERTEX"])[vertex]
+                pass
+            self.geom = vertex
+            pass
+        hyp = self.Hypothesis("SegmentAroundVertex_0D",[length],UseExisting=UseExisting)
+        hyp = self.Hypothesis("SegmentLengthAroundVertex",[length],UseExisting=UseExisting)
+        self.geom = store_geom
+        hyp.SetLength( length )
+        return hyp
+
     ## Define "QuadraticMesh" hypothesis, forcing construction of quadratic edges.
     #  If the 2D mesher sees that all boundary edges are quadratic ones,
     #  it generates quadratic faces, else it generates linear faces using
@@ -544,9 +619,28 @@ class Mesh_Segment(Mesh_Algorithm):
     #  The 3D mesher generates quadratic volumes only if all boundary faces
     #  are quadratic ones, else it fails.
     def QuadraticMesh(self):
-        hyp = self.Hypothesis("QuadraticMesh")
+        hyp = self.Hypothesis("QuadraticMesh", UseExisting=1)
         return hyp
 
+# Public class: Mesh_CompositeSegment
+# --------------------------
+
+## Class to define a segment 1D algorithm for discretization
+#
+#  More details.
+class Mesh_CompositeSegment(Mesh_Segment):
+
+    algo = 0 # algorithm object common for all Mesh_CompositeSegments
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        if not Mesh_CompositeSegment.algo:
+            Mesh_CompositeSegment.algo = self.Create(mesh, geom, "CompositeSegment_1D")
+        else:
+            self.Assign( Mesh_CompositeSegment.algo, mesh, geom)
+            pass
+        
+
 # Public class: Mesh_Segment_Python
 # ---------------------------------
 
@@ -555,16 +649,24 @@ class Mesh_Segment(Mesh_Algorithm):
 #  More details.
 class Mesh_Segment_Python(Mesh_Segment):
 
+    algo = 0 # algorithm object common for all Mesh_Segment_Pythons
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
         import Python1dPlugin
-        self.Create(mesh, geom, "Python_1D", "libPython1dEngine.so")
+        if not Mesh_Segment_Python.algo:
+            Mesh_Segment_Python.algo = self.Create(mesh, geom, "Python_1D", "libPython1dEngine.so")
+        else:
+            self.Assign( Mesh_Segment_Python.algo, mesh, geom)
+            pass
     
     ## Define "PythonSplit1D" hypothesis based on the Erwan Adam patch, awaiting equivalent SALOME functionality
     #  @param n for the number of segments that cut an edge
     #  @param func for the python function that calculate the length of all segments
-    def PythonSplit1D(self, n, func):
-        hyp = self.Hypothesis("PythonSplit1D", [n], "libPython1dEngine.so")
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def PythonSplit1D(self, n, func, UseExisting=0):
+        hyp = self.Hypothesis("PythonSplit1D", [n], "libPython1dEngine.so", UseExisting=UseExisting)
         hyp.SetNumberOfSegments(n)
         hyp.SetPythonLog10RatioFunction(func)
         return hyp
@@ -577,24 +679,58 @@ class Mesh_Segment_Python(Mesh_Segment):
 #  More details.
 class Mesh_Triangle(Mesh_Algorithm):
 
+    # default values
     algoType = 0
     params = 0
-   
+
+    # algorithm objects common for all instances of Mesh_Triangle
+    algoMEF = 0    
+    algoNET = 0
+    algoNET_2D = 0
+
     ## Private constructor.
     def __init__(self, mesh, algoType, geom=0):
         if algoType == MEFISTO:
-            self.Create(mesh, geom, "MEFISTO_2D")
+            if not Mesh_Triangle.algoMEF:
+                Mesh_Triangle.algoMEF = self.Create(mesh, geom, "MEFISTO_2D")
+            else:
+                self.Assign( Mesh_Triangle.algoMEF, mesh, geom)
+                pass
+            pass
+        
         elif algoType == NETGEN:
             if noNETGENPlugin:
-                print "Warning: NETGENPlugin module has not been imported."
-            self.Create(mesh, geom, "NETGEN_2D", "libNETGENEngine.so")
+                print "Warning: NETGENPlugin module unavailable"
+                pass
+            if not Mesh_Triangle.algoNET:
+                Mesh_Triangle.algoNET = self.Create(mesh, geom, "NETGEN_2D", "libNETGENEngine.so")
+            else:
+                self.Assign( Mesh_Triangle.algoNET, mesh, geom)
+                pass
+            pass
+        elif algoType == NETGEN_2D:
+            if noNETGENPlugin:
+                print "Warning: NETGENPlugin module unavailable"
+                pass
+            if not Mesh_Triangle.algoNET_2D:
+                Mesh_Triangle.algoNET_2D = self.Create(mesh, geom,
+                                                      "NETGEN_2D_ONLY", "libNETGENEngine.so")
+            else:
+                self.Assign( Mesh_Triangle.algoNET_2D, mesh, geom)
+                pass
+            pass
+
         self.algoType = algoType
 
     ## Define "MaxElementArea" hypothesis to give the maximun area of each triangles
     #  @param area for the maximum area of each triangles
-    def MaxElementArea(self, area):
-        if self.algoType == MEFISTO:
-            hyp = self.Hypothesis("MaxElementArea", [area])
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    #
+    #  Only for algoType == MEFISTO || NETGEN_2D
+    def MaxElementArea(self, area, UseExisting=0):
+        if self.algoType == MEFISTO or self.algoType == NETGEN_2D:
+            hyp = self.Hypothesis("MaxElementArea", [area], UseExisting=UseExisting)
             hyp.SetMaxElementArea(area)
             return hyp
         elif self.algoType == NETGEN:
@@ -602,74 +738,120 @@ class Mesh_Triangle(Mesh_Algorithm):
             return None
             
     ## Define "LengthFromEdges" hypothesis to build triangles based on the length of the edges taken from the wire
+    #
+    #  Only for algoType == MEFISTO || NETGEN_2D
     def LengthFromEdges(self):
-        if self.algoType == MEFISTO:
-            hyp = self.Hypothesis("LengthFromEdges")
+        if self.algoType == MEFISTO or self.algoType == NETGEN_2D:
+            hyp = self.Hypothesis("LengthFromEdges", UseExisting=1)
             return hyp
         elif self.algoType == NETGEN:
             print "Netgen 1D-2D algo doesn't support this hypothesis"
             return None
         
+    ## Set QuadAllowed flag
+    #
+    #  Only for algoType == NETGEN || NETGEN_2D
+    def SetQuadAllowed(self, toAllow=True):
+        if self.algoType == NETGEN_2D:
+            if toAllow: # add QuadranglePreference
+                self.Hypothesis("QuadranglePreference", UseExisting=1)
+            else:       # remove QuadranglePreference
+                for hyp in self.mesh.GetHypothesisList( self.geom ):
+                    if hyp.GetName() == "QuadranglePreference":
+                        self.mesh.RemoveHypothesis( self.geom, hyp )
+                        pass
+                    pass
+                pass
+            return
+        if self.params == 0 and self.Parameters():
+            self.params.SetQuadAllowed(toAllow)
+            return
+        
     ## Define "Netgen 2D Parameters" hypothesis
+    #
+    #  Only for algoType == NETGEN
     def Parameters(self):
         if self.algoType == NETGEN:
-            self.params = self.Hypothesis("NETGEN_Parameters_2D", [], "libNETGENEngine.so")
+            self.params = self.Hypothesis("NETGEN_Parameters_2D", [],
+                                          "libNETGENEngine.so", UseExisting=0)
             return self.params
         elif self.algoType == MEFISTO:
-            print "Mefisto algo doesn't support this hypothesis"
+            print "Mefisto algo doesn't support NETGEN_Parameters_2D hypothesis"
+            return None
+        elif self.algoType == NETGEN_2D:
+            print "NETGEN_2D_ONLY algo doesn't support 'NETGEN_Parameters_2D' hypothesis"
+            print "NETGEN_2D_ONLY uses 'MaxElementArea' and 'LengthFromEdges' ones"
             return None
+        return None
 
     ## Set MaxSize
+    #
+    #  Only for algoType == NETGEN
     def SetMaxSize(self, theSize):
         if self.params == 0:
             self.Parameters()
-        self.params.SetMaxSize(theSize)
-        
+        if self.params is not None:
+            self.params.SetMaxSize(theSize)
+
     ## Set SecondOrder flag
-    def SetSecondOrder(seld, theVal):
+    #
+    #  Only for algoType == NETGEN
+    def SetSecondOrder(self, theVal):
         if self.params == 0:
             self.Parameters()
-        self.params.SetSecondOrder(theVal)
+        if self.params is not None:
+            self.params.SetSecondOrder(theVal)
 
     ## Set Optimize flag
+    #
+    #  Only for algoType == NETGEN
     def SetOptimize(self, theVal):
         if self.params == 0:
             self.Parameters()
-        self.params.SetOptimize(theVal)
+        if self.params is not None:
+            self.params.SetOptimize(theVal)
 
     ## Set Fineness
     #  @param theFineness is:
     #  VeryCoarse, Coarse, Moderate, Fine, VeryFine or Custom
+    #
+    #  Only for algoType == NETGEN
     def SetFineness(self, theFineness):
         if self.params == 0:
             self.Parameters()
-        self.params.SetFineness(theFineness)
-        
+        if self.params is not None:
+            self.params.SetFineness(theFineness)
+
     ## Set GrowthRate  
+    #
+    #  Only for algoType == NETGEN
     def SetGrowthRate(self, theRate):
         if self.params == 0:
             self.Parameters()
-        self.params.SetGrowthRate(theRate)
+        if self.params is not None:
+            self.params.SetGrowthRate(theRate)
 
     ## Set NbSegPerEdge
+    #
+    #  Only for algoType == NETGEN
     def SetNbSegPerEdge(self, theVal):
         if self.params == 0:
             self.Parameters()
-        self.params.SetNbSegPerEdge(theVal)
+        if self.params is not None:
+            self.params.SetNbSegPerEdge(theVal)
 
     ## Set NbSegPerRadius
+    #
+    #  Only for algoType == NETGEN
     def SetNbSegPerRadius(self, theVal):
         if self.params == 0:
             self.Parameters()
-        self.params.SetNbSegPerRadius(theVal)
+        if self.params is not None:
+            self.params.SetNbSegPerRadius(theVal)
+
+    pass
+
 
-    ## Set QuadAllowed flag
-    def SetQuadAllowed(self, toAllow):
-        if self.params == 0:
-            self.Parameters()
-        self.params.SetQuadAllowed(toAllow)
-        
-    
 # Public class: Mesh_Quadrangle
 # -----------------------------
 
@@ -678,15 +860,21 @@ class Mesh_Triangle(Mesh_Algorithm):
 #  More details.
 class Mesh_Quadrangle(Mesh_Algorithm):
 
+    algo = 0 # algorithm object common for all Mesh_Quadrangles
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "Quadrangle_2D")
+        if not Mesh_Quadrangle.algo:
+            Mesh_Quadrangle.algo = self.Create(mesh, geom, "Quadrangle_2D")
+        else:
+            self.Assign( Mesh_Quadrangle.algo, mesh, geom)
+            pass
     
     ## Define "QuadranglePreference" hypothesis, forcing construction
     #  of quadrangles if the number of nodes on opposite edges is not the same
     #  in the case where the global number of nodes on edges is even
     def QuadranglePreference(self):
-        hyp = self.Hypothesis("QuadranglePreference")
+        hyp = self.Hypothesis("QuadranglePreference", UseExisting=1)
         return hyp
     
 # Public class: Mesh_Tetrahedron
@@ -700,30 +888,55 @@ class Mesh_Tetrahedron(Mesh_Algorithm):
     params = 0
     algoType = 0
 
+    algoNET = 0 # algorithm object common for all Mesh_Tetrahedrons
+    algoGHS = 0 # algorithm object common for all Mesh_Tetrahedrons
+    algoFNET = 0 # algorithm object common for all Mesh_Tetrahedrons
+
     ## Private constructor.
     def __init__(self, mesh, algoType, geom=0):
         if algoType == NETGEN:
-            self.Create(mesh, geom, "NETGEN_3D", "libNETGENEngine.so")
+            if not Mesh_Tetrahedron.algoNET:
+                Mesh_Tetrahedron.algoNET = self.Create(mesh, geom, "NETGEN_3D", "libNETGENEngine.so")
+            else:
+                self.Assign( Mesh_Tetrahedron.algoNET, mesh, geom)
+                pass
+            pass
+
         elif algoType == GHS3D:
-            import GHS3DPlugin
-            self.Create(mesh, geom, "GHS3D_3D" , "libGHS3DEngine.so")
+            if not Mesh_Tetrahedron.algoGHS:
+                import GHS3DPlugin
+                Mesh_Tetrahedron.algoGHS = self.Create(mesh, geom, "GHS3D_3D" , "libGHS3DEngine.so")
+            else:
+                self.Assign( Mesh_Tetrahedron.algoGHS, mesh, geom)
+                pass
+            pass
+
         elif algoType == FULL_NETGEN:
             if noNETGENPlugin:
                 print "Warning: NETGENPlugin module has not been imported."
-            self.Create(mesh, geom, "NETGEN_2D3D", "libNETGENEngine.so")
+            if not Mesh_Tetrahedron.algoFNET:
+                Mesh_Tetrahedron.algoFNET = self.Create(mesh, geom, "NETGEN_2D3D", "libNETGENEngine.so")
+            else:
+                self.Assign( Mesh_Tetrahedron.algoFNET, mesh, geom)
+                pass
+            pass
+
         self.algoType = algoType
 
     ## Define "MaxElementVolume" hypothesis to give the maximun volume of each tetrahedral
     #  @param vol for the maximum volume of each tetrahedral
-    def MaxElementVolume(self, vol):
-        hyp = self.Hypothesis("MaxElementVolume", [vol])
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def MaxElementVolume(self, vol, UseExisting=0):
+        hyp = self.Hypothesis("MaxElementVolume", [vol], UseExisting=UseExisting)
         hyp.SetMaxElementVolume(vol)
         return hyp
 
     ## Define "Netgen 3D Parameters" hypothesis
     def Parameters(self):
         if (self.algoType == FULL_NETGEN):
-            self.params = self.Hypothesis("NETGEN_Parameters", [], "libNETGENEngine.so")
+            self.params = self.Hypothesis("NETGEN_Parameters", [],
+                                          "libNETGENEngine.so", UseExisting=0)
             return self.params
         else:
             print "Algo doesn't support this hypothesis"
@@ -781,9 +994,15 @@ class Mesh_Tetrahedron(Mesh_Algorithm):
 #  More details.
 class Mesh_Hexahedron(Mesh_Algorithm):
 
+    algo = 0 # algorithm object common for all Mesh_Hexahedrons
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "Hexa_3D")
+        if not Mesh_Hexahedron.algo:
+            Mesh_Hexahedron.algo = self.Create(mesh, geom, "Hexa_3D")
+        else:
+            self.Assign( Mesh_Hexahedron.algo, mesh, geom)
+            pass
 
 # Deprecated, only for compatibility!
 # Public class: Mesh_Netgen
@@ -799,6 +1018,9 @@ class Mesh_Netgen(Mesh_Algorithm):
 
     is3D = 0
 
+    algoNET23 = 0 # algorithm object common for all Mesh_Netgens
+    algoNET2 = 0 # algorithm object common for all Mesh_Netgens
+
     ## Private constructor.
     def __init__(self, mesh, is3D, geom=0):
         if noNETGENPlugin:
@@ -806,16 +1028,29 @@ class Mesh_Netgen(Mesh_Algorithm):
             
         self.is3D = is3D
         if is3D:
-            self.Create(mesh, geom, "NETGEN_2D3D", "libNETGENEngine.so")
+            if not Mesh_Netgen.algoNET23:
+                Mesh_Netgen.algoNET23 = self.Create(mesh, geom, "NETGEN_2D3D", "libNETGENEngine.so")
+            else:
+                self.Assign( Mesh_Netgen.algoNET23, mesh, geom)
+                pass
+            pass
+
         else:
-            self.Create(mesh, geom, "NETGEN_2D", "libNETGENEngine.so")
+            if not Mesh_Netgen.algoNET2:
+                Mesh_Netgen.algoNET2 = self.Create(mesh, geom, "NETGEN_2D", "libNETGENEngine.so")
+            else:
+                self.Assign( Mesh_Netgen.algoNET2, mesh, geom)
+                pass
+            pass
 
     ## Define hypothesis containing parameters of the algorithm
     def Parameters(self):
         if self.is3D:
-            hyp = self.Hypothesis("NETGEN_Parameters", [], "libNETGENEngine.so")
+            hyp = self.Hypothesis("NETGEN_Parameters", [],
+                                  "libNETGENEngine.so", UseExisting=0)
         else:
-            hyp = self.Hypothesis("NETGEN_Parameters_2D", [], "libNETGENEngine.so")
+            hyp = self.Hypothesis("NETGEN_Parameters_2D", [],
+                                  "libNETGENEngine.so", UseExisting=0)
         return hyp
 
 # Public class: Mesh_Projection1D
@@ -826,9 +1061,15 @@ class Mesh_Netgen(Mesh_Algorithm):
 #  More details.
 class Mesh_Projection1D(Mesh_Algorithm):
 
+    algo = 0 # algorithm object common for all Mesh_Projection1Ds
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "Projection_1D")
+        if not Mesh_Projection1D.algo:
+            Mesh_Projection1D.algo = self.Create(mesh, geom, "Projection_1D")
+        else:
+            self.Assign( Mesh_Projection1D.algo, mesh, geom)
+            pass
 
     ## Define "Source Edge" hypothesis, specifying a meshed edge to
     #  take a mesh pattern from, and optionally association of vertices
@@ -838,8 +1079,10 @@ class Mesh_Projection1D(Mesh_Algorithm):
     #  @param srcV is vertex of \a edge to associate with \a tgtV (optional)
     #  @param tgtV is vertex of \a the edge where the algorithm is assigned,
     #  to associate with \a srcV (optional)
-    def SourceEdge(self, edge, mesh=None, srcV=None, tgtV=None):
-        hyp = self.Hypothesis("ProjectionSource1D")
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def SourceEdge(self, edge, mesh=None, srcV=None, tgtV=None, UseExisting=0):
+        hyp = self.Hypothesis("ProjectionSource1D", [edge,mesh,srcV,tgtV], UseExisting=UseExisting)
         hyp.SetSourceEdge( edge )
         if not mesh is None and isinstance(mesh, Mesh):
             mesh = mesh.GetMesh()
@@ -856,9 +1099,15 @@ class Mesh_Projection1D(Mesh_Algorithm):
 #  More details.
 class Mesh_Projection2D(Mesh_Algorithm):
 
+    algo = 0 # algorithm object common for all Mesh_Projection2Ds
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "Projection_2D")
+        if not Mesh_Projection2D.algo:
+            Mesh_Projection2D.algo = self.Create(mesh, geom, "Projection_2D")
+        else:
+            self.Assign( Mesh_Projection2D.algo, mesh, geom)
+            pass
 
     ## Define "Source Face" hypothesis, specifying a meshed face to
     #  take a mesh pattern from, and optionally association of vertices
@@ -871,10 +1120,14 @@ class Mesh_Projection2D(Mesh_Algorithm):
     #  @param srcV2 is vertex of \a face to associate with \a tgtV1 (optional)
     #  @param tgtV2 is vertex of \a the face where the algorithm is assigned,
     #  to associate with \a srcV2 (optional)
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
     #
     #  Note: association vertices must belong to one edge of a face
-    def SourceFace(self, face, mesh=None, srcV1=None, tgtV1=None, srcV2=None, tgtV2=None):
-        hyp = self.Hypothesis("ProjectionSource2D")
+    def SourceFace(self, face, mesh=None, srcV1=None, tgtV1=None,
+                   srcV2=None, tgtV2=None, UseExisting=0):
+        hyp = self.Hypothesis("ProjectionSource2D", [face,mesh,srcV1,tgtV1,srcV2,tgtV2],
+                              UseExisting=UseExisting)
         hyp.SetSourceFace( face )
         if not mesh is None and isinstance(mesh, Mesh):
             mesh = mesh.GetMesh()
@@ -890,9 +1143,15 @@ class Mesh_Projection2D(Mesh_Algorithm):
 #  More details.
 class Mesh_Projection3D(Mesh_Algorithm):
 
+    algo = 0 # algorithm object common for all Mesh_Projection3Ds
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "Projection_3D")
+        if not Mesh_Projection3D.algo:
+            Mesh_Projection3D.algo = self.Create(mesh, geom, "Projection_3D")
+        else:
+            self.Assign( Mesh_Projection3D.algo, mesh, geom)
+            pass
 
     ## Define "Source Shape 3D" hypothesis, specifying a meshed solid to
     #  take a mesh pattern from, and optionally association of vertices
@@ -905,10 +1164,15 @@ class Mesh_Projection3D(Mesh_Algorithm):
     #  @param srcV2 is vertex of \a solid to associate with \a tgtV1 (optional)
     #  @param tgtV2 is vertex of \a the solid where the algorithm is assigned,
     #  to associate with \a srcV2 (optional)
+    #  @param UseExisting - if ==true - search existing hypothesis created with
+    #                       same parameters, else (default) - create new
     #
     #  Note: association vertices must belong to one edge of a solid
-    def SourceShape3D(self, solid, mesh=0, srcV1=0, tgtV1=0, srcV2=0, tgtV2=0):
-        hyp = self.Hypothesis("ProjectionSource3D")
+    def SourceShape3D(self, solid, mesh=0, srcV1=0, tgtV1=0,
+                      srcV2=0, tgtV2=0, UseExisting=0):
+        hyp = self.Hypothesis("ProjectionSource3D",
+                              [solid,mesh,srcV1,tgtV1,srcV2,tgtV2],
+                              UseExisting=UseExisting)
         hyp.SetSource3DShape( solid )
         if not mesh is None and isinstance(mesh, Mesh):
             mesh = mesh.GetMesh()
@@ -920,14 +1184,20 @@ class Mesh_Projection3D(Mesh_Algorithm):
 # Public class: Mesh_Prism
 # ------------------------
 
-## Class to define a Prism 3D algorithm
+## Class to define a 3D extrusion algorithm
 #
 #  More details.
 class Mesh_Prism3D(Mesh_Algorithm):
 
+    algo = 0 # algorithm object common for all Mesh_Prism3Ds
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "Prism_3D")
+        if not Mesh_Prism3D.algo:
+            Mesh_Prism3D.algo = self.Create(mesh, geom, "Prism_3D")
+        else:
+            self.Assign( Mesh_Prism3D.algo, mesh, geom)
+            pass
 
 # Public class: Mesh_RadialPrism
 # -------------------------------
@@ -937,10 +1207,16 @@ class Mesh_Prism3D(Mesh_Algorithm):
 #  More details.
 class Mesh_RadialPrism3D(Mesh_Algorithm):
 
+    algo = 0 # algorithm object common for all Mesh_RadialPrism3Ds
+
     ## Private constructor.
     def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "RadialPrism_3D")
-        self.distribHyp = self.Hypothesis( "LayerDistribution" )
+        if not Mesh_RadialPrism3D.algo:
+            Mesh_RadialPrism3D.algo = self.Create(mesh, geom, "RadialPrism_3D")
+        else:
+            self.Assign( Mesh_RadialPrism3D.algo, mesh, geom)
+            pass
+        self.distribHyp = self.Hypothesis( "LayerDistribution", UseExisting=0)
         self.nbLayers = None
 
     ## Return 3D hypothesis holding the 1D one
@@ -961,9 +1237,11 @@ class Mesh_RadialPrism3D(Mesh_Algorithm):
 
     ## Define "NumberOfLayers" hypothesis, specifying a number of layers of
     #  prisms to build between the inner and outer shells
-    def NumberOfLayers(self, n ):
+    #  @param UseExisting if ==true - search existing hypothesis created with
+    #                     same parameters, else (default) - create new
+    def NumberOfLayers(self, n, UseExisting=0):
         self.mesh.GetMesh().RemoveHypothesis( self.geom, self.distribHyp )
-        self.nbLayers = self.Hypothesis("NumberOfLayers")
+        self.nbLayers = self.Hypothesis("NumberOfLayers", [n], UseExisting=UseExisting)
         self.nbLayers.SetNumberOfLayers( n )
         return self.nbLayers
 
@@ -971,7 +1249,7 @@ class Mesh_RadialPrism3D(Mesh_Algorithm):
     #  to build between the inner and outer shells
     #  @param l for the length of segments
     def LocalLength(self, l):
-        hyp = self.OwnHypothesis("LocalLength", [l])
+        hyp = self.OwnHypothesis("LocalLength", [l] )
         hyp.SetLength(l)
         return hyp
         
@@ -981,7 +1259,7 @@ class Mesh_RadialPrism3D(Mesh_Algorithm):
     #  @param s for the scale factor (optional)
     def NumberOfSegments(self, n, s=[]):
         if s == []:
-            hyp = self.OwnHypothesis("NumberOfSegments", [n])
+            hyp = self.OwnHypothesis("NumberOfSegments", [n] )
         else:
             hyp = self.OwnHypothesis("NumberOfSegments", [n,s])
             hyp.SetDistrType( 1 )
@@ -993,7 +1271,7 @@ class Mesh_RadialPrism3D(Mesh_Algorithm):
     #  to build between the inner and outer shells as arithmetic length increasing
     #  @param start for the length of the first segment
     #  @param end   for the length of the last  segment
-    def Arithmetic1D(self, start, end):
+    def Arithmetic1D(self, start, end ):
         hyp = self.OwnHypothesis("Arithmetic1D", [start, end])
         hyp.SetLength(start, 1)
         hyp.SetLength(end  , 0)
@@ -1017,6 +1295,26 @@ class Mesh_RadialPrism3D(Mesh_Algorithm):
         hyp.SetFineness( fineness )
         return hyp
 
+# Private class: Mesh_UseExisting
+# -------------------------------
+class Mesh_UseExisting(Mesh_Algorithm):
+
+    algo1D = 0 # StdMeshers_UseExisting_1D object common for all Mesh_UseExisting
+    algo2D = 0 # StdMeshers_UseExisting_2D object common for all Mesh_UseExisting
+
+    def __init__(self, dim, mesh, geom=0):
+        if dim == 1:
+            if not Mesh_UseExisting.algo1D:
+                Mesh_UseExisting.algo1D= self.Create(mesh, geom, "UseExisting_1D")
+            else:
+                self.Assign( Mesh_UseExisting.algo1D, mesh, geom)
+                pass
+        else:
+            if not Mesh_UseExisting.algo2D:
+                Mesh_UseExisting.algo2D= self.Create(mesh, geom, "UseExisting_2D")
+            else:
+                self.Assign( Mesh_UseExisting.algo2D, mesh, geom)
+                pass
 
 # Public class: Mesh
 # ==================
@@ -1138,20 +1436,45 @@ class Mesh:
     #  @param geom If defined, subshape to be meshed
     def Segment(self, algo=REGULAR, geom=0):
         ## if Segment(geom) is called by mistake
-        if ( isinstance( algo, geompy.GEOM._objref_GEOM_Object)):
+        if isinstance( algo, geompy.GEOM._objref_GEOM_Object):
             algo, geom = geom, algo
+            if not algo: algo = REGULAR
             pass
         if algo == REGULAR:
             return Mesh_Segment(self, geom)
         elif algo == PYTHON:
             return Mesh_Segment_Python(self, geom)
+        elif algo == COMPOSITE:
+            return Mesh_CompositeSegment(self, geom)
         else:
             return Mesh_Segment(self, geom)
-        
+
+    ## Enable creation of nodes and segments usable by 2D algoritms.
+    #  Added nodes and segments must be bound to edges and vertices by
+    #  SetNodeOnVertex(), SetNodeOnEdge() and SetMeshElementOnShape()
+    #  If the optional \a geom parameter is not sets, this algorithm is global.
+    #  \n Otherwise, this algorithm define a submesh based on \a geom subshape.
+    #  @param geom subshape to be manually meshed
+    #  @return StdMeshers_UseExisting_1D algorithm that generates nothing
+    def UseExistingSegments(self, geom=0):
+        algo = Mesh_UseExisting(1,self,geom)
+        return algo.GetAlgorithm()
+
+    ## Enable creation of nodes and faces usable by 3D algoritms.
+    #  Added nodes and faces must be bound to geom faces by SetNodeOnFace()
+    #  and SetMeshElementOnShape()
+    #  If the optional \a geom parameter is not sets, this algorithm is global.
+    #  \n Otherwise, this algorithm define a submesh based on \a geom subshape.
+    #  @param geom subshape to be manually meshed
+    #  @return StdMeshers_UseExisting_2D algorithm that generates nothing
+    def UseExistingFaces(self, geom=0):
+        algo = Mesh_UseExisting(2,self,geom)
+        return algo.GetAlgorithm()
+
     ## Creates a triangle 2D algorithm for faces.
     #  If the optional \a geom parameter is not sets, this algorithm is global.
     #  \n Otherwise, this algorithm define a submesh based on \a geom subshape.
-    #  @param algo values are: smesh.MEFISTO or smesh.NETGEN
+    #  @param algo values are: smesh.MEFISTO || smesh.NETGEN_1D2D || smesh.NETGEN_2D
     #  @param geom If defined, subshape to be meshed
     def Triangle(self, algo=MEFISTO, geom=0):
         ## if Triangle(geom) is called by mistake
@@ -1178,6 +1501,7 @@ class Mesh:
         ## if Tetrahedron(geom) is called by mistake
         if ( isinstance( algo, geompy.GEOM._objref_GEOM_Object)):
             algo, geom = geom, algo
+            if not algo: algo = NETGEN
             pass
         return Mesh_Tetrahedron(self, algo, geom)
         
@@ -1213,7 +1537,7 @@ class Mesh:
     def Projection3D(self, geom=0):
         return Mesh_Projection3D(self, geom)
 
-    ## Creates a Prism 3D or RadialPrism 3D algorithm for solids.
+    ## Creates a 3D extrusion (Prism 3D) or RadialPrism 3D algorithm for solids.
     #  If the optional \a geom parameter is not sets, this algorithm is global.
     #  Otherwise, this algorithm define a submesh based on \a geom subshape.
     #  @param geom If defined, subshape to be meshed
@@ -1235,28 +1559,40 @@ class Mesh:
                 return 0
             else:
                 geom = self.geom
-        ok = smesh.Compute(self.mesh, geom)
+        ok = False
+        try:
+            ok = smesh.Compute(self.mesh, geom)
+        except SALOME.SALOME_Exception, ex:
+            print "Mesh computation failed, exception caught:"
+            print "    ", ex.details.text
+        except:
+            import traceback
+            print "Mesh computation failed, exception caught:"
+            traceback.print_exc()
         if not ok:
             errors = smesh.GetAlgoState( self.mesh, geom )
             allReasons = ""
             for err in errors:
                 if err.isGlobalAlgo:
-                    glob = " global "
+                    glob = "global"
                 else:
-                    glob = " local "
+                    glob = "local"
                     pass
-                dim = str(err.algoDim)
-                if err.name == MISSING_ALGO:
-                    reason = glob + dim + "D algorithm is missing"
-                elif err.name == MISSING_HYPO:
-                    name = '"' + err.algoName + '"'
-                    reason = glob + dim + "D algorithm " + name + " misses " + dim + "D hypothesis"
-                elif err.name == NOT_CONFORM_MESH:
-                    reason = "Global \"Not Conform mesh allowed\" hypothesis is missing"
-                elif err.name == BAD_PARAM_VALUE:
-                    name = '"' + err.algoName + '"'
-                    reason = "Hypothesis of" + glob + dim + "D algorithm " + name +\
-                             " has a bad parameter value"
+                dim = err.algoDim
+                name = err.algoName
+                if len(name) == 0:
+                    reason = '%s %sD algorithm is missing' % (glob, dim)
+                elif err.state == HYP_MISSING:
+                    reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
+                              % (glob, dim, name, dim))
+                elif err.state == HYP_NOTCONFORM:
+                    reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
+                elif err.state == HYP_BAD_PARAMETER:
+                    reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
+                              % ( glob, dim, name ))
+                elif err.state == HYP_BAD_GEOMETRY:
+                    reason = ('%s %sD algorithm "%s" is assigned to geometry mismatching'
+                              'its expectation' % ( glob, dim, name ))
                 else:
                     reason = "For unknown reason."+\
                              " Revise Mesh.Compute() implementation in smesh.py!"
@@ -1267,14 +1603,16 @@ class Mesh:
                 allReasons += reason
                 pass
             if allReasons != "":
-                print '"' + GetName(self.mesh) + '"',"not computed:"
+                print '"' + GetName(self.mesh) + '"',"has not been computed:"
                 print allReasons
+            else:
+                print '"' + GetName(self.mesh) + '"',"has not been computed."
                 pass
             pass
         if salome.sg.hasDesktop():
             smeshgui = salome.ImportComponentGUI("SMESH")
             smeshgui.Init(salome.myStudyId)
-            smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok )
+            smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok, (self.NbNodes()==0) )
             salome.sg.updateObjBrowser(1)
             pass
         return ok
@@ -1308,7 +1646,35 @@ class Mesh:
             self.Hexahedron()            
             pass
         return self.Compute()
+
+    ## Assign hypothesis
+    #  @param hyp is a hypothesis to assign
+    #  @param geom is subhape of mesh geometry
+    def AddHypothesis(self, hyp, geom=0 ):
+        if isinstance( hyp, Mesh_Algorithm ):
+            hyp = hyp.GetAlgorithm()
+            pass
+        if not geom:
+            geom = self.geom
+            pass
+        status = self.mesh.AddHypothesis(geom, hyp)
+        isAlgo = hyp._narrow( SMESH_Algo )
+        TreatHypoStatus( status, GetName( hyp ), GetName( geom ), isAlgo )
+        return status
     
+    ## Unassign hypothesis
+    #  @param hyp is a hypothesis to unassign
+    #  @param geom is subhape of mesh geometry
+    def RemoveHypothesis(self, hyp, geom=0 ):
+        if isinstance( hyp, Mesh_Algorithm ):
+            hyp = hyp.GetAlgorithm()
+            pass
+        if not geom:
+            geom = self.geom
+            pass
+        status = self.mesh.RemoveHypothesis(geom, hyp)
+        return status
+
     ## Get the list of hypothesis added on a geom
     #  @param geom is subhape of mesh geometry
     def GetHypothesisList(self, geom):
@@ -1508,6 +1874,10 @@ class Mesh:
     def GetGroups(self):
         return self.mesh.GetGroups()
 
+    ## Get number of groups existing in the mesh
+    def NbGroups(self):
+        return self.mesh.NbGroups()
+
     ## Get the list of names of groups existing in the mesh
     def GetGroupNames(self):
         groups = self.GetGroups()
@@ -1565,7 +1935,7 @@ class Mesh:
     ## Check group names for duplications.
     #  Consider maximum group name length stored in MED file.
     def HasDuplicatedGroupNamesMED(self):
-        return self.mesh.GetStudyId()
+        return self.mesh.HasDuplicatedGroupNamesMED()
         
     ## Obtain instance of SMESH_MeshEditor
     def GetMeshEditor(self):
@@ -1710,19 +2080,34 @@ class Mesh:
         return self.mesh.GetElementType(id, iselem)
 
     ## Returns list of submesh elements ids
-    #  @param shapeID is geom object(subshape) IOR
-    def GetSubMeshElementsId(self, shapeID):
-        return self.mesh.GetSubMeshElementsId(shapeID)
+    #  @param Shape is geom object(subshape) IOR
+    #  Shape must be subshape of a ShapeToMesh()
+    def GetSubMeshElementsId(self, Shape):
+        if ( isinstance( Shape, geompy.GEOM._objref_GEOM_Object)):
+            ShapeID = Shape.GetSubShapeIndices()[0]
+        else:
+            ShapeID = Shape
+        return self.mesh.GetSubMeshElementsId(ShapeID)
 
     ## Returns list of submesh nodes ids
-    #  @param shapeID is geom object(subshape) IOR
-    def GetSubMeshNodesId(self, shapeID, all):
-        return self.mesh.GetSubMeshNodesId(shapeID, all)
+    #  @param Shape is geom object(subshape) IOR
+    #  Shape must be subshape of a ShapeToMesh()
+    def GetSubMeshNodesId(self, Shape, all):
+        if ( isinstance( Shape, geompy.GEOM._objref_GEOM_Object)):
+            ShapeID = Shape.GetSubShapeIndices()[0]
+        else:
+            ShapeID = Shape
+        return self.mesh.GetSubMeshNodesId(ShapeID, all)
     
     ## Returns list of ids of submesh elements with given type
-    #  @param shapeID is geom object(subshape) IOR
-    def GetSubMeshElementType(self, shapeID):
-        return self.mesh.GetSubMeshElementType(shapeID)
+    #  @param Shape is geom object(subshape) IOR
+    #  Shape must be subshape of a ShapeToMesh()
+    def GetSubMeshElementType(self, Shape):
+        if ( isinstance( Shape, geompy.GEOM._objref_GEOM_Object)):
+            ShapeID = Shape.GetSubShapeIndices()[0]
+        else:
+            ShapeID = Shape
+        return self.mesh.GetSubMeshElementType(ShapeID)
       
     ## Get mesh description
     def Dump(self):
@@ -1742,6 +2127,11 @@ class Mesh:
     def GetNodeInverseElements(self, id):
         return self.mesh.GetNodeInverseElements(id)
 
+    ## @brief Return position of a node on shape
+    #  @return SMESH::NodePosition
+    def GetNodePosition(self,NodeID):
+        return self.mesh.GetNodePosition(NodeID)
+
     ## If given element is node returns IDs of shape from position
     #  \n If there is not node for given ID - returns -1
     def GetShapeID(self, id):
@@ -1750,7 +2140,7 @@ class Mesh:
     ## For given element returns ID of result shape after 
     #  FindShape() from SMESH_MeshEditor
     #  \n If there is not element for given ID - returns -1
-    def GetShapeIDForElem(id):
+    def GetShapeIDForElem(self,id):
         return self.mesh.GetShapeIDForElem(id)
     
     ## Returns number of nodes for given element
@@ -1764,6 +2154,10 @@ class Mesh:
     def GetElemNode(self, id, index):
         return self.mesh.GetElemNode(id, index)
 
+    ## Returns IDs of nodes of given element
+    def GetElemNodes(self, id):
+        return self.mesh.GetElemNodes(id)
+
     ## Returns true if given node is medium node
     #  in given quadratic element
     def IsMediumNode(self, elementID, nodeID):
@@ -1861,14 +2255,112 @@ class Mesh:
     def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
         return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
     
+
+    ## @brief Bind a node to a vertex
+    # @param NodeID - node ID
+    # @param Vertex - vertex or vertex ID
+    # @return True if succeed else raise an exception
+    def SetNodeOnVertex(self, NodeID, Vertex):
+        if ( isinstance( Vertex, geompy.GEOM._objref_GEOM_Object)):
+            VertexID = Vertex.GetSubShapeIndices()[0]
+        else:
+            VertexID = Vertex
+        try:
+            self.editor.SetNodeOnVertex(NodeID, VertexID)
+        except SALOME.SALOME_Exception, inst:
+            raise ValueError, inst.details.text
+        return True
+        
+
+    ## @brief Store node position on an edge
+    # @param NodeID - node ID
+    # @param Edge - edge or edge ID
+    # @param paramOnEdge - parameter on edge where the node is located
+    # @return True if succeed else raise an exception
+    def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
+        if ( isinstance( Edge, geompy.GEOM._objref_GEOM_Object)):
+            EdgeID = Edge.GetSubShapeIndices()[0]
+        else:
+            EdgeID = Edge
+        try:
+            self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
+        except SALOME.SALOME_Exception, inst:
+            raise ValueError, inst.details.text
+        return True
+
+    ## @brief Store node position on a face
+    # @param NodeID - node ID
+    # @param Face - face or face ID
+    # @param u - U parameter on face where the node is located
+    # @param v - V parameter on face where the node is located
+    # @return True if succeed else raise an exception
+    def SetNodeOnFace(self, NodeID, Face, u, v):
+        if ( isinstance( Face, geompy.GEOM._objref_GEOM_Object)):
+            FaceID = Face.GetSubShapeIndices()[0]
+        else:
+            FaceID = Face
+        try:
+            self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
+        except SALOME.SALOME_Exception, inst:
+            raise ValueError, inst.details.text
+        return True
+
+    ## @brief Bind a node to a solid
+    # @param NodeID - node ID
+    # @param Solid - solid or solid ID
+    # @return True if succeed else raise an exception
+    def SetNodeInVolume(self, NodeID, Solid):
+        if ( isinstance( Solid, geompy.GEOM._objref_GEOM_Object)):
+            SolidID = Solid.GetSubShapeIndices()[0]
+        else:
+            SolidID = Solid
+        try:
+            self.editor.SetNodeInVolume(NodeID, SolidID)
+        except SALOME.SALOME_Exception, inst:
+            raise ValueError, inst.details.text
+        return True
+
+    ## @brief Bind an element to a shape
+    # @param ElementID - element ID
+    # @param Shape - shape or shape ID
+    # @return True if succeed else raise an exception
+    def SetMeshElementOnShape(self, ElementID, Shape):
+        if ( isinstance( Shape, geompy.GEOM._objref_GEOM_Object)):
+            ShapeID = Shape.GetSubShapeIndices()[0]
+        else:
+            ShapeID = Shape
+        try:
+            self.editor.SetMeshElementOnShape(ElementID, ShapeID)
+        except SALOME.SALOME_Exception, inst:
+            raise ValueError, inst.details.text
+        return True
+
+
     ## Move node with given id
     #  @param NodeID id of the node
-    #  @param x displacing along the X axis
-    #  @param y displacing along the Y axis
-    #  @param z displacing along the Z axis
+    #  @param x new X coordinate
+    #  @param y new Y coordinate
+    #  @param z new Z coordinate
     def MoveNode(self, NodeID, x, y, z):
         return self.editor.MoveNode(NodeID, x, y, z)
 
+    ## Find a node closest to a point
+    #  @param x X coordinate of a point
+    #  @param y Y coordinate of a point
+    #  @param z Z coordinate of a point
+    #  @return id of a node
+    def FindNodeClosestTo(self, x, y, z):
+        preview = self.mesh.GetMeshEditPreviewer()
+        return preview.MoveClosestNodeToPoint(x, y, z, -1)
+
+    ## Find a node closest to a point and move it to a point location
+    #  @param x X coordinate of a point
+    #  @param y Y coordinate of a point
+    #  @param z Z coordinate of a point
+    #  @return id of a moved node
+    def MeshToPassThroughAPoint(self, x, y, z):
+        return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
+
     ## Replace two neighbour triangles sharing Node1-Node2 link
     #  with ones built on the same 4 nodes but having other common link.
     #  @param NodeID1 first node id
@@ -1895,6 +2387,8 @@ class Mesh:
     ## Reorient all elements of the object
     #  @param theObject is mesh, submesh or group
     def ReorientObject(self, theObject):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
         return self.editor.ReorientObject(theObject)
 
     ## Fuse neighbour triangles into quadrangles.
@@ -1915,6 +2409,8 @@ class Mesh:
     #                   is still performed; theMaxAngle is mesured in radians.
     #  @return TRUE in case of success, FALSE otherwise.
     def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
         return self.editor.TriToQuadObject(theObject, GetFunctor(theCriterion), MaxAngle)
 
     ## Split quadrangles into triangles.
@@ -1930,6 +2426,8 @@ class Mesh:
     #  @param theObject object to taking list of elements from, is mesh, submesh or group
     #  @param theCriterion  is FT_...; used to choose a diagonal for splitting.
     def QuadToTriObject (self, theObject, theCriterion):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
         return self.editor.QuadToTriObject(theObject, GetFunctor(theCriterion))
 
     ## Split quadrangles into triangles.
@@ -1944,6 +2442,8 @@ class Mesh:
     ## Split quadrangles into triangles.
     #  @param theObject is object to taking list of elements from, is mesh, submesh or group
     def SplitQuadObject (self, theObject, Diag13):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
         return self.editor.SplitQuadObject(theObject, Diag13)
 
     ## Find better splitting of the given quadrangle.
@@ -1962,9 +2462,9 @@ class Mesh:
             if self.GetElemNbNodes(face_id) == 4: # quadrangle
                 quad_nodes = self.mesh.GetElemNodes(face_id)
                 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
-                isPrismFound = False
+                isVolumeFound = False
                 for node1_elem in node1_elems:
-                    if not isPrismFound:
+                    if not isVolumeFound:
                         if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
                             nb_nodes = self.GetElemNbNodes(node1_elem)
                             if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
@@ -1992,7 +2492,7 @@ class Mesh:
     #         will be mapped into <theNode000>-th node of each volume, the (0,0,1)
     #         key-point will be mapped into <theNode001>-th node of each volume.
     #         The (0,0,0) key-point of used pattern corresponds to not split corner.
-    #  @param @return TRUE in case of success, FALSE otherwise.
+    #  @return TRUE in case of success, FALSE otherwise.
     def SplitHexaToTetras (self, theObject, theNode000, theNode001):
         # Pattern:     5.---------.6
         #              /|#*      /|
@@ -2116,6 +2616,8 @@ class Mesh:
     #  @param Method is Laplacian(LAPLACIAN_SMOOTH) or Centroidal(CENTROIDAL_SMOOTH)
     def SmoothObject(self, theObject, IDsOfFixedNodes, 
                      MaxNbOfIterations, MaxxAspectRatio, Method):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
         return self.editor.SmoothObject(theObject, IDsOfFixedNodes, 
                                         MaxNbOfIterations, MaxxAspectRatio, Method)
 
@@ -2126,7 +2628,7 @@ class Mesh:
     #  @param MaxNbOfIterations maximum number of iterations
     #  @param MaxAspectRatio varies in range [1.0, inf]
     #  @param Method is Laplacian(LAPLACIAN_SMOOTH) or Centroidal(CENTROIDAL_SMOOTH)
-    def SmoothParametric(IDsOfElements, IDsOfFixedNodes,
+    def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
                          MaxNbOfIterations, MaxAspectRatio, Method):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
@@ -2142,6 +2644,8 @@ class Mesh:
     #  @param Method is Laplacian(LAPLACIAN_SMOOTH) or Centroidal(CENTROIDAL_SMOOTH)
     def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
                                MaxNbOfIterations, MaxAspectRatio, Method):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
         return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
                                                   MaxNbOfIterations, MaxAspectRatio, Method)
 
@@ -2170,12 +2674,17 @@ class Mesh:
     #  @param AngleInRadians angle of Rotation
     #  @param NbOfSteps number of steps
     #  @param Tolerance tolerance
-    def RotationSweep(self, IDsOfElements, Axix, AngleInRadians, NbOfSteps, Tolerance):
+    #  @param MakeGroups to generate new groups from existing ones
+    def RotationSweep(self, IDsOfElements, Axix, AngleInRadians, NbOfSteps, Tolerance, MakeGroups=False):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( Axix, geompy.GEOM._objref_GEOM_Object)):
             Axix = GetAxisStruct(Axix)
+        if MakeGroups:
+            return self.editor.RotationSweepMakeGroups(IDsOfElements, Axix,
+                                                       AngleInRadians, NbOfSteps, Tolerance)
         self.editor.RotationSweep(IDsOfElements, Axix, AngleInRadians, NbOfSteps, Tolerance)
+        return []
 
     ## Generate new elements by rotation of the elements of object around the axis
     #  @param theObject object wich elements should be sweeped
@@ -2183,21 +2692,32 @@ class Mesh:
     #  @param AngleInRadians angle of Rotation
     #  @param NbOfSteps number of steps
     #  @param Tolerance tolerance
-    def RotationSweepObject(self, theObject, Axix, AngleInRadians, NbOfSteps, Tolerance):
+    #  @param MakeGroups to generate new groups from existing ones
+    def RotationSweepObject(self, theObject, Axix, AngleInRadians, NbOfSteps, Tolerance, MakeGroups=False):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
         if ( isinstance( Axix, geompy.GEOM._objref_GEOM_Object)):
             Axix = GetAxisStruct(Axix)
+        if MakeGroups:
+            return self.editor.RotationSweepObjectMakeGroups(theObject, Axix, AngleInRadians,
+                                                             NbOfSteps, Tolerance)
         self.editor.RotationSweepObject(theObject, Axix, AngleInRadians, NbOfSteps, Tolerance)
+        return []
 
     ## Generate new elements by extrusion of the elements with given ids
     #  @param IDsOfElements list of elements ids for extrusion
     #  @param StepVector vector, defining the direction and value of extrusion 
     #  @param NbOfSteps the number of steps
-    def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps):
+    #  @param MakeGroups to generate new groups from existing ones
+    def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( StepVector, geompy.GEOM._objref_GEOM_Object)):
             StepVector = GetDirStruct(StepVector)
+        if MakeGroups:
+            return self.editor.ExtrusionSweepMakeGroups(IDsOfElements, StepVector, NbOfSteps)
         self.editor.ExtrusionSweep(IDsOfElements, StepVector, NbOfSteps)
+        return []
 
     ## Generate new elements by extrusion of the elements with given ids
     #  @param IDsOfElements is ids of elements
@@ -2206,37 +2726,61 @@ class Mesh:
     #  @param ExtrFlags set flags for performing extrusion
     #  @param SewTolerance uses for comparing locations of nodes if flag
     #         EXTRUSION_FLAG_SEW is set
-    def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps, ExtrFlags, SewTolerance):
+    #  @param MakeGroups to generate new groups from existing ones
+    def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps, ExtrFlags, SewTolerance, MakeGroups=False):
         if ( isinstance( StepVector, geompy.GEOM._objref_GEOM_Object)):
             StepVector = GetDirStruct(StepVector)
-        self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps, ExtrFlags, SewTolerance)
+        if MakeGroups:
+            return self.editor.AdvancedExtrusionMakeGroups(IDsOfElements, StepVector, NbOfSteps,
+                                                           ExtrFlags, SewTolerance)
+        self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
+                                      ExtrFlags, SewTolerance)
+        return []
 
     ## Generate new elements by extrusion of the elements belong to object
     #  @param theObject object wich elements should be processed
     #  @param StepVector vector, defining the direction and value of extrusion 
     #  @param NbOfSteps the number of steps
-    def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps):
+    #  @param MakeGroups to generate new groups from existing ones
+    def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
         if ( isinstance( StepVector, geompy.GEOM._objref_GEOM_Object)):
             StepVector = GetDirStruct(StepVector)
+        if MakeGroups:
+            return self.editor.ExtrusionSweepObjectMakeGroups(theObject, StepVector, NbOfSteps)
         self.editor.ExtrusionSweepObject(theObject, StepVector, NbOfSteps)
+        return []
 
     ## Generate new elements by extrusion of the elements belong to object
     #  @param theObject object wich elements should be processed
     #  @param StepVector vector, defining the direction and value of extrusion 
     #  @param NbOfSteps the number of steps
-    def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps):
+    #  @param MakeGroups to generate new groups from existing ones
+    def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
         if ( isinstance( StepVector, geompy.GEOM._objref_GEOM_Object)):
             StepVector = GetDirStruct(StepVector)
+        if MakeGroups:
+            return self.editor.ExtrusionSweepObject1DMakeGroups(theObject, StepVector, NbOfSteps)
         self.editor.ExtrusionSweepObject1D(theObject, StepVector, NbOfSteps)
+        return []
     
     ## Generate new elements by extrusion of the elements belong to object
     #  @param theObject object wich elements should be processed
     #  @param StepVector vector, defining the direction and value of extrusion 
     #  @param NbOfSteps the number of steps    
-    def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps):
+    #  @param MakeGroups to generate new groups from existing ones
+    def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
         if ( isinstance( StepVector, geompy.GEOM._objref_GEOM_Object)):
             StepVector = GetDirStruct(StepVector)
+        if MakeGroups:
+            return self.editor.ExtrusionSweepObject2DMakeGroups(theObject, StepVector, NbOfSteps)
         self.editor.ExtrusionSweepObject2D(theObject, StepVector, NbOfSteps)
+        return []
 
     ## Generate new elements by extrusion of the given elements
     #  A path of extrusion must be a meshed edge.
@@ -2249,14 +2793,22 @@ class Mesh:
     #  @param HasRefPoint allows to use base point 
     #  @param RefPoint point around which the shape is rotated(the mass center of the shape by default).
     #         User can specify any point as the Base Point and the shape will be rotated with respect to this point.
+    #  @param MakeGroups to generate new groups from existing ones
+    #  @param LinearVariation makes compute rotation angles as linear variation of given Angles along path steps
     def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
-                           HasAngles, Angles, HasRefPoint, RefPoint):
+                           HasAngles, Angles, HasRefPoint, RefPoint,
+                           MakeGroups=False, LinearVariation=False):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( RefPoint, geompy.GEOM._objref_GEOM_Object)):
-            RefPoint = GetPointStruct(RefPoint) 
-        return self.editor.ExtrusionAlongPath(IDsOfElements, PathMesh.GetMesh(), PathShape, NodeStart,
-                                              HasAngles, Angles, HasRefPoint, RefPoint)
+            RefPoint = GetPointStruct(RefPoint)
+            pass
+        if MakeGroups:
+            return self.editor.ExtrusionAlongPathMakeGroups(IDsOfElements, PathMesh.GetMesh(),
+                                                            PathShape, NodeStart, HasAngles,
+                                                            Angles, HasRefPoint, RefPoint)
+        return self.editor.ExtrusionAlongPath(IDsOfElements, PathMesh.GetMesh(), PathShape,
+                                              NodeStart, HasAngles, Angles, HasRefPoint, RefPoint)
 
     ## Generate new elements by extrusion of the elements belong to object
     #  A path of extrusion must be a meshed edge.
@@ -2269,12 +2821,22 @@ class Mesh:
     #  @param HasRefPoint allows to use base point 
     #  @param RefPoint point around which the shape is rotated(the mass center of the shape by default).
     #         User can specify any point as the Base Point and the shape will be rotated with respect to this point.
+    #  @param MakeGroups to generate new groups from existing ones
+    #  @param LinearVariation makes compute rotation angles as linear variation of given Angles along path steps
     def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
-                                 HasAngles, Angles, HasRefPoint, RefPoint):
+                                 HasAngles, Angles, HasRefPoint, RefPoint,
+                                 MakeGroups=False, LinearVariation=False):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
         if ( isinstance( RefPoint, geompy.GEOM._objref_GEOM_Object)):
             RefPoint = GetPointStruct(RefPoint) 
-        return self.editor.ExtrusionAlongPathObject(theObject, PathMesh.GetMesh(), PathShape, NodeStart,
-                                                    HasAngles, Angles, HasRefPoint, RefPoint)
+        if MakeGroups:
+            return self.editor.ExtrusionAlongPathObjectMakeGroups(theObject, PathMesh.GetMesh(),
+                                                                  PathShape, NodeStart, HasAngles,
+                                                                  Angles, HasRefPoint, RefPoint)
+        return self.editor.ExtrusionAlongPathObject(theObject, PathMesh.GetMesh(), PathShape,
+                                                    NodeStart, HasAngles, Angles, HasRefPoint,
+                                                    RefPoint)
     
     ## Symmetrical copy of mesh elements
     #  @param IDsOfElements list of elements ids
@@ -2282,12 +2844,32 @@ class Mesh:
     #  @param theMirrorType is  POINT, AXIS or PLANE
     #  If the Mirror is geom object this parameter is unnecessary
     #  @param Copy allows to copy element(Copy is 1) or to replace with its mirroring(Copy is 0)
-    def Mirror(self, IDsOfElements, Mirror, theMirrorType, Copy=0):
+    #  @param MakeGroups to generate new groups from existing ones (if Copy)
+    def Mirror(self, IDsOfElements, Mirror, theMirrorType, Copy=0, MakeGroups=False):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( Mirror, geompy.GEOM._objref_GEOM_Object)):
             Mirror = GetAxisStruct(Mirror)
+        if Copy and MakeGroups:
+            return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
         self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
+        return []
+
+    ## Create a new mesh by symmetrical copy of mesh elements
+    #  @param IDsOfElements list of elements ids
+    #  @param Mirror is AxisStruct or geom object(point, line, plane)
+    #  @param theMirrorType is  POINT, AXIS or PLANE
+    #  If the Mirror is geom object this parameter is unnecessary
+    #  @param MakeGroups to generate new groups from existing ones
+    #  @param NewMeshName is a name of new mesh to create
+    def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType, MakeGroups=0, NewMeshName=""):
+        if IDsOfElements == []:
+            IDsOfElements = self.GetElementsId()
+        if ( isinstance( Mirror, geompy.GEOM._objref_GEOM_Object)):
+            Mirror = GetAxisStruct(Mirror)
+        mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
+                                          MakeGroups, NewMeshName)
+        return Mesh(mesh)
 
     ## Symmetrical copy of object
     #  @param theObject mesh, submesh or group
@@ -2295,50 +2877,150 @@ class Mesh:
     #  @param theMirrorType is  POINT, AXIS or PLANE
     #  If the Mirror is geom object this parameter is unnecessary
     #  @param Copy allows to copy element(Copy is 1) or to replace with its mirroring(Copy is 0)
-    def MirrorObject (self, theObject, Mirror, theMirrorType, Copy=0):
+    #  @param MakeGroups to generate new groups from existing ones (if Copy)
+    def MirrorObject (self, theObject, Mirror, theMirrorType, Copy=0, MakeGroups=False):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
         if ( isinstance( Mirror, geompy.GEOM._objref_GEOM_Object)):
             Mirror = GetAxisStruct(Mirror)
+        if Copy and MakeGroups:
+            return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
         self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
+        return []
+
+    ## Create a new mesh by symmetrical copy of object
+    #  @param theObject mesh, submesh or group
+    #  @param Mirror is AxisStruct or geom object(point, line, plane)
+    #  @param theMirrorType is  POINT, AXIS or PLANE
+    #  If the Mirror is geom object this parameter is unnecessary
+    #  @param MakeGroups to generate new groups from existing ones
+    #  @param NewMeshName is a name of new mesh to create
+    def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType,MakeGroups=0, NewMeshName=""):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
+        if ( isinstance( Mirror, geompy.GEOM._objref_GEOM_Object)):
+            Mirror = GetAxisStruct(Mirror)
+        mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
+                                                MakeGroups, NewMeshName)
+        return Mesh( mesh )
 
     ## Translates the elements
     #  @param IDsOfElements list of elements ids
     #  @param Vector direction of translation(DirStruct or vector)
     #  @param Copy allows to copy the translated elements
-    def Translate(self, IDsOfElements, Vector, Copy):
+    #  @param MakeGroups to generate new groups from existing ones (if Copy)
+    def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( Vector, geompy.GEOM._objref_GEOM_Object)):
             Vector = GetDirStruct(Vector)
+        if Copy and MakeGroups:
+            return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
         self.editor.Translate(IDsOfElements, Vector, Copy)
+        return []
+
+    ## Create a new mesh of translated elements
+    #  @param IDsOfElements list of elements ids
+    #  @param Vector direction of translation(DirStruct or vector)
+    #  @param MakeGroups to generate new groups from existing ones
+    #  @param NewMeshName is a name of new mesh to create
+    def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
+        if IDsOfElements == []:
+            IDsOfElements = self.GetElementsId()
+        if ( isinstance( Vector, geompy.GEOM._objref_GEOM_Object)):
+            Vector = GetDirStruct(Vector)
+        mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
+        return Mesh ( mesh )
 
     ## Translates the object
     #  @param theObject object to translate(mesh, submesh, or group)
     #  @param Vector direction of translation(DirStruct or geom vector)
     #  @param Copy allows to copy the translated elements
-    def TranslateObject(self, theObject, Vector, Copy):
+    #  @param MakeGroups to generate new groups from existing ones (if Copy)
+    def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
         if ( isinstance( Vector, geompy.GEOM._objref_GEOM_Object)):
             Vector = GetDirStruct(Vector)
+        if Copy and MakeGroups:
+            return self.editor.TranslateObjectMakeGroups(theObject, Vector)
         self.editor.TranslateObject(theObject, Vector, Copy)
+        return []
+
+    ## Create a new mesh from translated object
+    #  @param theObject object to translate(mesh, submesh, or group)
+    #  @param Vector direction of translation(DirStruct or geom vector)
+    #  @param MakeGroups to generate new groups from existing ones
+    #  @param NewMeshName is a name of new mesh to create
+    def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
+        if ( isinstance( Vector, geompy.GEOM._objref_GEOM_Object)):
+            Vector = GetDirStruct(Vector)
+        mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
+        return Mesh( mesh )
 
     ## Rotates the elements
     #  @param IDsOfElements list of elements ids
     #  @param Axis axis of rotation(AxisStruct or geom line)
     #  @param AngleInRadians angle of rotation(in radians)
     #  @param Copy allows to copy the rotated elements   
-    def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy):
+    #  @param MakeGroups to generate new groups from existing ones (if Copy)
+    def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( Axis, geompy.GEOM._objref_GEOM_Object)):
             Axis = GetAxisStruct(Axis)
+        if Copy and MakeGroups:
+            return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
         self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
+        return []
+
+    ## Create a new mesh of rotated elements
+    #  @param IDsOfElements list of element ids
+    #  @param Axis axis of rotation(AxisStruct or geom line)
+    #  @param AngleInRadians angle of rotation(in radians)
+    #  @param MakeGroups to generate new groups from existing ones
+    #  @param NewMeshName is a name of new mesh to create
+    def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
+        if IDsOfElements == []:
+            IDsOfElements = self.GetElementsId()
+        if ( isinstance( Axis, geompy.GEOM._objref_GEOM_Object)):
+            Axis = GetAxisStruct(Axis)
+        mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
+                                          MakeGroups, NewMeshName)
+        return Mesh( mesh )
 
     ## Rotates the object
     #  @param theObject object to rotate(mesh, submesh, or group)
     #  @param Axis axis of rotation(AxisStruct or geom line)
     #  @param AngleInRadians angle of rotation(in radians)
     #  @param Copy allows to copy the rotated elements
-    def RotateObject (self, theObject, Axis, AngleInRadians, Copy):
+    #  @param MakeGroups to generate new groups from existing ones (if Copy)
+    def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
+        if ( isinstance( Axis, geompy.GEOM._objref_GEOM_Object)):
+            Axis = GetAxisStruct(Axis)
+        if Copy and MakeGroups:
+            return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
         self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
+        return []
+
+    ## Create a new mesh from a rotated object
+    #  @param theObject object to rotate (mesh, submesh, or group)
+    #  @param Axis axis of rotation(AxisStruct or geom line)
+    #  @param AngleInRadians angle of rotation(in radians)
+    #  @param MakeGroups to generate new groups from existing ones
+    #  @param NewMeshName is a name of new mesh to create
+    def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
+        if ( isinstance( Axis, geompy.GEOM._objref_GEOM_Object)):
+            Axis = GetAxisStruct(Axis)
+        mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
+                                                       MakeGroups, NewMeshName)
+        return Mesh( mesh )
 
     ## Find group of nodes close to each other within Tolerance.
     #  @param Tolerance tolerance value
@@ -2346,11 +3028,29 @@ class Mesh:
     def FindCoincidentNodes (self, Tolerance):
         return self.editor.FindCoincidentNodes(Tolerance)
 
+    ## Find group of nodes close to each other within Tolerance.
+    #  @param Tolerance tolerance value
+    #  @param SubMeshOrGroup SubMesh or Group
+    #  @param list of group of nodes
+    def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance):
+        return self.editor.FindCoincidentNodesOnPart(SubMeshOrGroup, Tolerance)
+
     ## Merge nodes
     #  @param list of group of nodes
     def MergeNodes (self, GroupsOfNodes):
         self.editor.MergeNodes(GroupsOfNodes)
 
+    ## Find elements built on the same nodes.
+    #  @param MeshOrSubMeshOrGroup Mesh or SubMesh, or Group of elements for searching
+    #  @return a list of groups of equal elements
+    def FindEqualElements (self, MeshOrSubMeshOrGroup):
+        return self.editor.FindEqualElements(MeshOrSubMeshOrGroup)
+
+    ## Merge elements in each given group.
+    #  @param GroupsOfElementsID groups of elements for merging
+    def MergeElements(self, GroupsOfElementsID):
+        self.editor.MergeElements(GroupsOfElementsID)
+
     ## Remove all but one of elements built on the same nodes.
     def MergeEqualElements(self):
         self.editor.MergeEqualElements()
@@ -2396,13 +3096,13 @@ class Mesh:
         return self.editor.ChangeElemNodes(ide, newIDs)
     
     ## If during last operation of MeshEditor some nodes were
-    #  created this method returns list of it's IDs, \n
+    #  created this method returns list of its IDs, \n
     #  if new nodes not created - returns empty list
     def GetLastCreatedNodes(self):
         return self.editor.GetLastCreatedNodes()
 
     ## If during last operation of MeshEditor some elements were
-    #  created this method returns list of it's IDs, \n
+    #  created this method returns list of its IDs, \n
     #  if new elements not creared - returns empty list
     def GetLastCreatedElems(self):
         return self.editor.GetLastCreatedElems()