Salome HOME
PAL16099 (Hypothesis modified and Mesh icon is still "Completed")
[modules/smesh.git] / src / SMESH_SWIG / smesh.py
index 5aad243efee16db6a90cdbcefea6b52525aedd7d..3e070a596eaced1408d3eebb48f93e6acd68f265 100644 (file)
@@ -1,3 +1,26 @@
+#  Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+#  File   : smesh.py
+#  Author : Francis KLOSS, OCC
+#  Module : SMESH
+
 """
  \namespace smesh
  \brief Module smesh
 
 import salome
 import geompy
-import StdMeshers
+
 import SMESH
 from   SMESH import *
 
-## Types of algo
-REGULAR = 1
-PYTHON  = 2
+import StdMeshers
+
+import SALOME
+
+# import NETGENPlugin module if possible
+noNETGENPlugin = 0
+try:
+    import NETGENPlugin
+except ImportError:
+    noNETGENPlugin = 1
+    pass
+    
+# Types of algo
+REGULAR    = 1
+PYTHON     = 2
+COMPOSITE  = 3
 
 MEFISTO = 3
 NETGEN  = 4
 GHS3D   = 5
 FULL_NETGEN = 6
 
-## MirrorType enumeration
+# MirrorType enumeration
 POINT = SMESH_MeshEditor.POINT
 AXIS =  SMESH_MeshEditor.AXIS 
 PLANE = SMESH_MeshEditor.PLANE
 
-## Smooth_Method enumeration
+# Smooth_Method enumeration
 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
 
-## Fineness enumeration(for NETGEN)
+# Fineness enumeration(for NETGEN)
 VeryCoarse = 0
 Coarse = 1
 Moderate = 2
@@ -42,7 +78,7 @@ NO_NAME = "NoName"
 smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
 smesh.SetCurrentStudy(salome.myStudy)
 
-## Global functions
+# Global functions
 
 ## Gets object name
 def GetName(obj):
@@ -63,7 +99,7 @@ def SetName(obj, name):
         attr.SetValue(name)
         
 ## Returns long value from enumeration
-#  Uses for FT_... enumeration
+#  Uses for SMESH.FunctorType enumeration
 def EnumToLong(theItem):
     return theItem._v
 
@@ -113,8 +149,8 @@ def GetAxisStruct(theObj):
         return axis
     return None
 
-## From SMESH_Gen interface:
-#  ------------------------
+# From SMESH_Gen interface:
+# ------------------------
 
 ## Set the current mode
 def SetEmbeddedMode( theMode ):
@@ -160,9 +196,14 @@ def CreateMeshesFromSTL( theFileName ):
 def GetSubShapesId( theMainObject, theListOfSubObjects ):
     return smesh.GetSubShapesId(theMainObject, theListOfSubObjects)
 
+## From SMESH_Gen interface. Creates pattern
+def GetPattern():
+    return smesh.GetPattern()
+
 
-## Filtering. Auxiliary functions:
-#  ------------------------------
+
+# Filtering. Auxiliary functions:
+# ------------------------------
 
 ## Creates an empty criterion
 #  @return SMESH.Filter.Criterion
@@ -203,11 +244,17 @@ def GetCriterion(elementType,
         
     if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
         aCriterion.Compare = EnumToLong(Compare)
+    elif Compare == "=" or Compare == "==":
+        aCriterion.Compare = EnumToLong(FT_EqualTo)
+    elif Compare == "<":
+        aCriterion.Compare = EnumToLong(FT_LessThan)
+    elif Compare == ">":
+        aCriterion.Compare = EnumToLong(FT_MoreThan)
     else:
         aCriterion.Compare = EnumToLong(FT_EqualTo)
         aTreshold = Compare
 
-    if CritType in [FT_BelongToGeom,     FT_BelongToPlane,
+    if CritType in [FT_BelongToGeom,     FT_BelongToPlane, FT_BelongToGenSurface, 
                     FT_BelongToCylinder, FT_LyingOnGeom]:
         # Check treshold
         if isinstance(aTreshold, geompy.GEOM._objref_GEOM_Object):
@@ -251,7 +298,98 @@ def GetCriterion(elementType,
         aCriterion.BinaryOp = EnumToLong(BinaryOp)
 
     return aCriterion
-  
+
+## Creates filter by given parameters of criterion
+#  @param elementType is the type of elements in the group
+#  @param CritType is type of criterion( FT_Taper, FT_Area, FT_RangeOfIds, FT_LyingOnGeom etc. )
+#  @param Compare belong to {FT_LessThan, FT_MoreThan, FT_EqualTo}
+#  @param Treshold is threshold value (range of id ids as string, shape, numeric)
+#  @param UnaryOp is FT_LogicalNOT or FT_Undefined
+#  @return SMESH_Filter
+def GetFilter(elementType,
+              CritType=FT_Undefined,
+              Compare=FT_EqualTo,
+              Treshold="",
+              UnaryOp=FT_Undefined):
+    aCriterion = GetCriterion(elementType, CritType, Compare, Treshold, UnaryOp, FT_Undefined)
+    aFilterMgr = smesh.CreateFilterManager()
+    aFilter = aFilterMgr.CreateFilter()
+    aCriteria = []
+    aCriteria.append(aCriterion)
+    aFilter.SetCriteria(aCriteria)
+    return aFilter
+
+## Creates numerical functor by its type
+#  @param theCrierion is FT_...; functor type
+#  @return SMESH_NumericalFunctor
+def GetFunctor(theCriterion):
+    aFilterMgr = smesh.CreateFilterManager()
+    if theCriterion == FT_AspectRatio:
+        return aFilterMgr.CreateAspectRatio()
+    elif theCriterion == FT_AspectRatio3D:
+        return aFilterMgr.CreateAspectRatio3D()
+    elif theCriterion == FT_Warping:
+        return aFilterMgr.CreateWarping()
+    elif theCriterion == FT_MinimumAngle:
+        return aFilterMgr.CreateMinimumAngle()
+    elif theCriterion == FT_Taper:
+        return aFilterMgr.CreateTaper()
+    elif theCriterion == FT_Skew:
+        return aFilterMgr.CreateSkew()
+    elif theCriterion == FT_Area:
+        return aFilterMgr.CreateArea()
+    elif theCriterion == FT_Volume3D:
+        return aFilterMgr.CreateVolume3D()
+    elif theCriterion == FT_MultiConnection:
+        return aFilterMgr.CreateMultiConnection()
+    elif theCriterion == FT_MultiConnection2D:
+        return aFilterMgr.CreateMultiConnection2D()
+    elif theCriterion == FT_Length:
+        return aFilterMgr.CreateLength()
+    elif theCriterion == FT_Length2D:
+        return aFilterMgr.CreateLength2D()
+    else:
+        print "Error: given parameter is not numerucal functor type."
+
+
+## Print error message if a hypothesis was not assigned.
+def TreatHypoStatus(status, hypName, geomName, isAlgo):
+    if isAlgo:
+        hypType = "algorithm"
+    else:
+        hypType = "hypothesis"
+        pass
+    if status == HYP_UNKNOWN_FATAL :
+        reason = "for unknown reason"
+    elif status == HYP_INCOMPATIBLE :
+        reason = "this hypothesis mismatches algorithm"
+    elif status == HYP_NOTCONFORM :
+        reason = "not conform mesh would be built"
+    elif status == HYP_ALREADY_EXIST :
+        reason = hypType + " of the same dimension already assigned to this shape"
+    elif status == HYP_BAD_DIM :
+        reason = hypType + " mismatches shape"
+    elif status == HYP_CONCURENT :
+        reason = "there are concurrent hypotheses on sub-shapes"
+    elif status == HYP_BAD_SUBSHAPE :
+        reason = "shape is neither the main one, nor its subshape, nor a valid group"
+    elif status == HYP_BAD_GEOMETRY:
+        reason = "geometry mismatches algorithm's expectation"
+    elif status == HYP_HIDDEN_ALGO:
+        reason = "it is hidden by an algorithm of upper dimension generating all-dimensions elements"
+    elif status == HYP_HIDING_ALGO:
+        reason = "it hides algorithm(s) of lower dimension by generating all-dimensions elements"
+    else:
+        return
+    hypName = '"' + hypName + '"'
+    geomName= '"' + geomName+ '"'
+    if status < HYP_UNKNOWN_FATAL:
+        print hypName, "was assigned to",    geomName,"but", reason
+    else:
+        print hypName, "was not assigned to",geomName,":", reason
+        pass
+
+    
     
 ## Mother class to define algorithm, recommended to don't use directly.
 #
@@ -265,10 +403,8 @@ class Mesh_Algorithm:
     subm = 0
     algo = 0
 
-    ## If the algorithm is global, return 0
-    #  \fn else return the submesh associated to this algorithm.
-    #
-    #  More details.
+    ## If the algorithm is global, return 0; \n
+    #  else return the submesh associated to this algorithm.
     def GetSubMesh(self):
         return self.subm
 
@@ -295,36 +431,6 @@ class Mesh_Algorithm:
     def GetId(self):
         return self.algo.GetId()
     
-    ## Private method. Print error message if a hypothesis was not assigned.
-    def TreatHypoStatus(self, status, hypName, geomName, isAlgo):
-        if isAlgo:
-            hypType = "algorithm"
-        else:
-            hypType = "hypothesis"
-        if status == HYP_UNKNOWN_FATAL :
-            reason = "for unknown reason"
-        elif status == HYP_INCOMPATIBLE :
-            reason = "this hypothesis mismatches algorithm"
-        elif status == HYP_NOTCONFORM :
-            reason = "not conform mesh would be built"
-        elif status == HYP_ALREADY_EXIST :
-            reason = hypType + " of the same dimension already assigned to this shape"
-        elif status == HYP_BAD_DIM :
-            reason = hypType + " mismatches shape"
-        elif status == HYP_CONCURENT :
-            reason = "there are concurrent hypotheses on sub-shapes"
-        elif status == HYP_BAD_SUBSHAPE :
-            reason = "shape is neither the main one, nor its subshape, nor a valid group"
-        else:
-            return
-        hypName = '"' + hypName + '"'
-        geomName= '"' + geomName+ '"'
-        if status < HYP_UNKNOWN_FATAL:
-            print hypName, "was assigned to",    geomName,"but", reason
-        else:
-            print hypName, "was not assigned to",geomName,":", reason
-        pass
-        
     ## Private method.
     def Create(self, mesh, geom, hypo, so="libStdMeshersEngine.so"):
         if geom is None:
@@ -345,7 +451,7 @@ class Mesh_Algorithm:
         self.algo = smesh.CreateHypothesis(hypo, so)
         SetName(self.algo, name + "/" + hypo)
         status = mesh.mesh.AddHypothesis(self.geom, self.algo)
-        self.TreatHypoStatus( status, hypo, name, 1 )
+        TreatHypoStatus( status, hypo, name, 1 )
         
     ## Private method
     def Hypothesis(self, hyp, args=[], so="libStdMeshersEngine.so"):
@@ -361,9 +467,10 @@ class Mesh_Algorithm:
         name = GetName(self.geom)
         SetName(hypo, name + "/" + hyp + a)
         status = self.mesh.mesh.AddHypothesis(self.geom, hypo)
-        self.TreatHypoStatus( status, hyp, name, 0 )
+        TreatHypoStatus( status, hyp, name, 0 )
         return hypo
-       
+
+
 # Public class: Mesh_Segment
 # --------------------------
 
@@ -433,6 +540,24 @@ class Mesh_Segment(Mesh_Algorithm):
         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
+    def LengthNearVertex(self, length, vertex=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")
+        hyp = self.Hypothesis("SegmentLengthAroundVertex")
+        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
@@ -443,6 +568,19 @@ class Mesh_Segment(Mesh_Algorithm):
         hyp = self.Hypothesis("QuadraticMesh")
         return hyp
 
+# Public class: Mesh_CompositeSegment
+# --------------------------
+
+## Class to define a segment 1D algorithm for discretization
+#
+#  More details.
+class Mesh_CompositeSegment(Mesh_Segment):
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        self.Create(mesh, geom, "CompositeSegment_1D")
+        
+
 # Public class: Mesh_Segment_Python
 # ---------------------------------
 
@@ -481,6 +619,8 @@ class Mesh_Triangle(Mesh_Algorithm):
         if algoType == MEFISTO:
             self.Create(mesh, geom, "MEFISTO_2D")
         elif algoType == NETGEN:
+            if noNETGENPlugin:
+                print "Warning: NETGENPlugin module has not been imported."
             self.Create(mesh, geom, "NETGEN_2D", "libNETGENEngine.so")
         self.algoType = algoType
 
@@ -602,6 +742,8 @@ class Mesh_Tetrahedron(Mesh_Algorithm):
             import GHS3DPlugin
             self.Create(mesh, geom, "GHS3D_3D" , "libGHS3DEngine.so")
         elif algoType == FULL_NETGEN:
+            if noNETGENPlugin:
+                print "Warning: NETGENPlugin module has not been imported."
             self.Create(mesh, geom, "NETGEN_2D3D", "libNETGENEngine.so")
         self.algoType = algoType
 
@@ -684,6 +826,8 @@ class Mesh_Hexahedron(Mesh_Algorithm):
 ## Class to define a NETGEN-based 2D or 3D algorithm
 #  that need no discrete boundary (i.e. independent)
 #
+#  This class is deprecated, only for compatibility!
+#
 #  More details.
 class Mesh_Netgen(Mesh_Algorithm):
 
@@ -691,6 +835,9 @@ class Mesh_Netgen(Mesh_Algorithm):
 
     ## Private constructor.
     def __init__(self, mesh, is3D, geom=0):
+        if noNETGENPlugin:
+            print "Warning: NETGENPlugin module has not been imported."
+            
         self.is3D = is3D
         if is3D:
             self.Create(mesh, geom, "NETGEN_2D3D", "libNETGENEngine.so")
@@ -704,7 +851,207 @@ class Mesh_Netgen(Mesh_Algorithm):
         else:
             hyp = self.Hypothesis("NETGEN_Parameters_2D", [], "libNETGENEngine.so")
         return hyp
+
+# Public class: Mesh_Projection1D
+# ------------------------------
+
+## Class to define a projection 1D algorithm
+#
+#  More details.
+class Mesh_Projection1D(Mesh_Algorithm):
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        self.Create(mesh, geom, "Projection_1D")
+
+    ## Define "Source Edge" hypothesis, specifying a meshed edge to
+    #  take a mesh pattern from, and optionally association of vertices
+    #  between the source edge and a target one (where a hipothesis is assigned to)
+    #  @param edge to take nodes distribution from
+    #  @param mesh to take nodes distribution from (optional)
+    #  @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")
+        hyp.SetSourceEdge( edge )
+        if not mesh is None and isinstance(mesh, Mesh):
+            mesh = mesh.GetMesh()
+        hyp.SetSourceMesh( mesh )
+        hyp.SetVertexAssociation( srcV, tgtV )
+        return hyp
+
+
+# Public class: Mesh_Projection2D
+# ------------------------------
+
+## Class to define a projection 2D algorithm
+#
+#  More details.
+class Mesh_Projection2D(Mesh_Algorithm):
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        self.Create(mesh, geom, "Projection_2D")
+
+    ## Define "Source Face" hypothesis, specifying a meshed face to
+    #  take a mesh pattern from, and optionally association of vertices
+    #  between the source face and a target one (where a hipothesis is assigned to)
+    #  @param face to take mesh pattern from
+    #  @param mesh to take mesh pattern from (optional)
+    #  @param srcV1 is vertex of \a face to associate with \a tgtV1 (optional)
+    #  @param tgtV1 is vertex of \a the face where the algorithm is assigned,
+    #  to associate with \a srcV1 (optional)
+    #  @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)
+    #
+    #  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")
+        hyp.SetSourceFace( face )
+        if not mesh is None and isinstance(mesh, Mesh):
+            mesh = mesh.GetMesh()
+        hyp.SetSourceMesh( mesh )
+        hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 )
+        return hyp
+
+# Public class: Mesh_Projection3D
+# ------------------------------
+
+## Class to define a projection 3D algorithm
+#
+#  More details.
+class Mesh_Projection3D(Mesh_Algorithm):
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        self.Create(mesh, geom, "Projection_3D")
+
+    ## Define "Source Shape 3D" hypothesis, specifying a meshed solid to
+    #  take a mesh pattern from, and optionally association of vertices
+    #  between the source solid and a target one (where a hipothesis is assigned to)
+    #  @param solid to take mesh pattern from
+    #  @param mesh to take mesh pattern from (optional)
+    #  @param srcV1 is vertex of \a solid to associate with \a tgtV1 (optional)
+    #  @param tgtV1 is vertex of \a the solid where the algorithm is assigned,
+    #  to associate with \a srcV1 (optional)
+    #  @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)
+    #
+    #  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")
+        hyp.SetSource3DShape( solid )
+        if not mesh is None and isinstance(mesh, Mesh):
+            mesh = mesh.GetMesh()
+        hyp.SetSourceMesh( mesh )
+        hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 )
+        return hyp
+
+
+# Public class: Mesh_Prism
+# ------------------------
+
+## Class to define a 3D extrusion algorithm
+#
+#  More details.
+class Mesh_Prism3D(Mesh_Algorithm):
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        self.Create(mesh, geom, "Prism_3D")
+
+# Public class: Mesh_RadialPrism
+# -------------------------------
+
+## Class to define a Radial Prism 3D algorithm
+#
+#  More details.
+class Mesh_RadialPrism3D(Mesh_Algorithm):
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        self.Create(mesh, geom, "RadialPrism_3D")
+        self.distribHyp = self.Hypothesis( "LayerDistribution" )
+        self.nbLayers = None
+
+    ## Return 3D hypothesis holding the 1D one
+    def Get3DHypothesis(self):
+        return self.distribHyp
+
+    ## Private method creating 1D hypothes and storing it in the LayerDistribution
+    #  hypothes. Returns the created hypothes
+    def OwnHypothesis(self, hypType, args=[], so="libStdMeshersEngine.so"):
+        if not self.nbLayers is None:
+            self.mesh.GetMesh().RemoveHypothesis( self.geom, self.nbLayers )
+            self.mesh.GetMesh().AddHypothesis( self.geom, self.distribHyp )
+        study = GetCurrentStudy() # prevent publishing of own 1D hypothesis
+        hyp = smesh.CreateHypothesis(hypType, so)
+        SetCurrentStudy( study ) # anable publishing
+        self.distribHyp.SetLayerDistribution( hyp )
+        return hyp
+
+    ## Define "NumberOfLayers" hypothesis, specifying a number of layers of
+    #  prisms to build between the inner and outer shells
+    def NumberOfLayers(self, n ):
+        self.mesh.GetMesh().RemoveHypothesis( self.geom, self.distribHyp )
+        self.nbLayers = self.Hypothesis("NumberOfLayers")
+        self.nbLayers.SetNumberOfLayers( n )
+        return self.nbLayers
+
+    ## Define "LocalLength" hypothesis, specifying segment length
+    #  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.SetLength(l)
+        return hyp
+        
+    ## Define "NumberOfSegments" hypothesis, specifying a number of layers of
+    #  prisms to build between the inner and outer shells
+    #  @param n for the number of segments
+    #  @param s for the scale factor (optional)
+    def NumberOfSegments(self, n, s=[]):
+        if s == []:
+            hyp = self.OwnHypothesis("NumberOfSegments", [n])
+        else:
+            hyp = self.OwnHypothesis("NumberOfSegments", [n,s])
+            hyp.SetDistrType( 1 )
+            hyp.SetScaleFactor(s)
+        hyp.SetNumberOfSegments(n)
+        return hyp
+        
+    ## Define "Arithmetic1D" hypothesis, specifying distribution of segments
+    #  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):
+        hyp = self.OwnHypothesis("Arithmetic1D", [start, end])
+        hyp.SetLength(start, 1)
+        hyp.SetLength(end  , 0)
+        return hyp
         
+    ## Define "StartEndLength" hypothesis, specifying distribution of segments
+    #  to build between the inner and outer shells as 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.OwnHypothesis("StartEndLength", [start, end])
+        hyp.SetLength(start, 1)
+        hyp.SetLength(end  , 0)
+        return hyp
+        
+    ## Define "AutomaticLength" hypothesis, specifying number of segments
+    #  to build between the inner and outer shells
+    #  @param fineness for the fineness [0-1]
+    def AutomaticLength(self, fineness=0):
+        hyp = self.OwnHypothesis("AutomaticLength")
+        hyp.SetFineness( fineness )
+        return hyp
+
+
 # Public class: Mesh
 # ==================
 
@@ -725,6 +1072,8 @@ class Mesh:
     #  @param obj Shape to be meshed or SMESH_Mesh object
     #  @param name Study name of the mesh
     def __init__(self, obj=0, name=0):
+        if obj is None:
+            obj = 0
         if obj != 0:
             if isinstance(obj, geompy.GEOM._objref_GEOM_Object):
                 self.geom = obj
@@ -762,7 +1111,7 @@ class Mesh:
     
     ## Get the subMesh object associated to a subShape. The subMesh object
     #  gives access to nodes and elements IDs.
-    #  SubMesh will be used instead of SubShape in a next idl version to
+    #  \n SubMesh will be used instead of SubShape in a next idl version to
     #  adress a specific subMesh...
     def GetSubMesh(self, theSubObject, name):
         submesh = self.mesh.GetSubMesh(theSubObject, name)
@@ -818,7 +1167,7 @@ class Mesh:
     ## Creates a segment discretization 1D algorithm.
     #  If the optional \a algo parameter is not sets, this algorithm is REGULAR.
     #  If the optional \a geom parameter is not sets, this algorithm is global.
-    #  Otherwise, this algorithm define a submesh based on \a geom subshape.
+    #  \n Otherwise, this algorithm define a submesh based on \a geom subshape.
     #  @param algo values are smesh.REGULAR or smesh.PYTHON for discretization via python function
     #  @param geom If defined, subshape to be meshed
     def Segment(self, algo=REGULAR, geom=0):
@@ -830,12 +1179,14 @@ class Mesh:
             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)
         
     ## Creates a triangle 2D algorithm for faces.
     #  If the optional \a geom parameter is not sets, this algorithm is global.
-    #  Otherwise, this algorithm define a submesh based on \a geom subshape.
+    #  \n Otherwise, this algorithm define a submesh based on \a geom subshape.
     #  @param algo values are: smesh.MEFISTO or smesh.NETGEN
     #  @param geom If defined, subshape to be meshed
     def Triangle(self, algo=MEFISTO, geom=0):
@@ -848,7 +1199,7 @@ class Mesh:
         
     ## Creates a quadrangle 2D algorithm for faces.
     #  If the optional \a geom parameter is not sets, this algorithm is global.
-    #  Otherwise, this algorithm define a submesh based on \a geom subshape.
+    #  \n Otherwise, this algorithm define a submesh based on \a geom subshape.
     #  @param geom If defined, subshape to be meshed
     def Quadrangle(self, geom=0):
         return Mesh_Quadrangle(self, geom)
@@ -856,7 +1207,7 @@ class Mesh:
     ## Creates a tetrahedron 3D algorithm for solids.
     #  The parameter \a algo permits to choice the algorithm: NETGEN or GHS3D
     #  If the optional \a geom parameter is not sets, this algorithm is global.
-    #  Otherwise, this algorithm define a submesh based on \a geom subshape.
+    #  \n Otherwise, this algorithm define a submesh based on \a geom subshape.
     #  @param algo values are: smesh.NETGEN, smesh.GHS3D, smesh.FULL_NETGEN
     #  @param geom If defined, subshape to be meshed
     def Tetrahedron(self, algo=NETGEN, geom=0):
@@ -868,21 +1219,50 @@ class Mesh:
         
     ## Creates a hexahedron 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.
+    #  \n Otherwise, this algorithm define a submesh based on \a geom subshape.
     #  @param geom If defined, subshape to be meshed
     def Hexahedron(self, geom=0):
         return Mesh_Hexahedron(self, geom)
 
     ## Deprecated, only for compatibility!
-    #  Creates a NETGEN-based 2D or 3D independent algorithm (i.e. needs no
-    #  discrete boundary).
-    #  If the optional \a geom parameter is not sets, this algorithm is global.
-    #  Otherwise, this algorithm defines a submesh based on \a geom subshape.
-    #  @param is3D If 0 then algorithm is 2D, otherwise 3D
-    #  @param geom If defined, subshape to be meshed
     def Netgen(self, is3D, geom=0):
         return Mesh_Netgen(self, is3D, geom)
-      
+
+    ## Creates a projection 1D algorithm for edges.
+    #  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
+    def Projection1D(self, geom=0):
+        return Mesh_Projection1D(self, geom)
+
+    ## Creates a projection 2D algorithm for faces.
+    #  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
+    def Projection2D(self, geom=0):
+        return Mesh_Projection2D(self, geom)
+
+    ## Creates a projection 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
+    def Projection3D(self, geom=0):
+        return Mesh_Projection3D(self, geom)
+
+    ## 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
+    def Prism(self, geom=0):
+        shape = geom
+        if shape==0:
+            shape = self.geom
+        nbSolids = len( geompy.SubShapeAll( shape, geompy.ShapeType["SOLID"] ))
+        nbShells = len( geompy.SubShapeAll( shape, geompy.ShapeType["SHELL"] ))
+        if nbSolids == 0 or nbSolids == nbShells:
+            return Mesh_Prism3D(self, geom)
+        return Mesh_RadialPrism3D(self, geom)
+
     ## Compute the mesh and return the status of the computation
     def Compute(self, geom=0):
         if geom == 0 or not isinstance(geom, geompy.GEOM._objref_GEOM_Object):
@@ -891,7 +1271,16 @@ 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 cought:"
+            print "    ", ex.details.text
+        except:
+            import traceback
+            print "Mesh computation failed, exception cought:"
+            traceback.print_exc()
         if not ok:
             errors = smesh.GetAlgoState( self.mesh, geom )
             allReasons = ""
@@ -907,8 +1296,15 @@ class Mesh:
                 elif err.name == MISSING_HYPO:
                     name = '"' + err.algoName + '"'
                     reason = glob + dim + "D algorithm " + name + " misses " + dim + "D hypothesis"
-                else:
+                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"
+                else:
+                    reason = "For unknown reason."+\
+                             " Revise Mesh.Compute() implementation in smesh.py!"
                     pass
                 if allReasons != "":
                     allReasons += "\n"
@@ -916,20 +1312,22 @@ 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
 
     ## Compute tetrahedral mesh using AutomaticLength + MEFISTO + NETGEN
-    #  The parameter \a fineness [0.-1.] defines mesh fineness
+    #  The parameter \a fineness [0,-1] defines mesh fineness
     def AutomaticTetrahedralization(self, fineness=0):
         dim = self.MeshDimension()
         # assign hypotheses
@@ -944,7 +1342,7 @@ class Mesh:
         return self.Compute()
         
     ## Compute hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
-    #  The parameter \a fineness [0.-1.] defines mesh fineness
+    #  The parameter \a fineness [0,-1] defines mesh fineness
     def AutomaticHexahedralization(self, fineness=0):
         dim = self.MeshDimension()
         # assign hypotheses
@@ -957,6 +1355,21 @@ 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.SMESH_Algo ) is not None )
+        TreatHypoStatus( status, GetName( hyp ), GetName( geom ), isAlgo )
+        return status
     
     ## Get the list of hypothesis added on a geom
     #  @param geom is subhape of mesh geometry
@@ -972,9 +1385,9 @@ class Mesh:
         pass
         
     ## Create a mesh group based on geometric object \a grp
-    #  and give a \a name, if this parameter is not defined
-    #  the name is the same as the geometric group name
-    #  Note: this function is obsolete. Works like GroupOnGeom(). 
+    #  and give a \a name, \n if this parameter is not defined
+    #  the name is the same as the geometric group name \n
+    #  Note: Works like GroupOnGeom(). 
     #  @param grp  is a geometric group, a vertex, an edge, a face or a solid
     #  @param name is the name of the mesh group
     #  @return SMESH_GroupOnGeom
@@ -1012,11 +1425,10 @@ class Mesh:
     #  @param ascii defined the kind of file contents
     def ExportSTL(self, f, ascii=1):
         self.mesh.ExportSTL(f, ascii)
-    
-    ###################################################################################
+   
         
-    ## Operations with groups
-    #  ----------------------
+    # Operations with groups:
+    # ----------------------
 
     ## Creates an empty mesh group
     #  @param elementType is the type of elements in the group
@@ -1026,7 +1438,7 @@ class Mesh:
         return self.mesh.CreateGroup(elementType, name)
     
     ## Creates a mesh group based on geometric object \a grp
-    #  and give a \a name, if this parameter is not defined
+    #  and give a \a name, \n if this parameter is not defined
     #  the name is the same as the geometric group name
     #  @param grp  is a geometric group, a vertex, an edge, a face or a solid
     #  @param name is the name of the mesh group
@@ -1130,27 +1542,22 @@ class Mesh:
         group = self.MakeGroupByIds(groupName, anElemType, anIds)
         return group
 
-    ## Creates filter by given parameters of criterion
-    #  @param elementType is the type of elements in the group
-    #  @param CritType is type of criterion( FT_Taper, FT_Area, FT_RangeOfIds, FT_LyingOnGeom etc. )
-    #  @param Compare belong to {FT_LessThan, FT_MoreThan, FT_EqualTo}
-    #  @param Treshold is threshold value (range of id ids as string, shape, numeric)
-    #  @param UnaryOp is FT_LogicalNOT or FT_Undefined
-    #  @return SMESH_Filter
-    def GetFilter(self,
-                  elementType,
-                  CritType=FT_Undefined,
-                  Compare=FT_EqualTo,
-                  Treshold="",
-                  UnaryOp=FT_Undefined):
-        aCriterion = GetCriterion(elementType, CritType, Compare, Treshold, UnaryOp, FT_Undefined)
+    ## Pass mesh elements through the given filter and return ids
+    #  @param theFilter is SMESH_Filter
+    #  @return list of ids
+    def GetIdsFromFilter(self, theFilter):
+        return theFilter.GetElementsId(self.mesh)
+
+    ## Verify whether 2D mesh element has free edges(edges connected to one face only)\n
+    #  Returns list of special structures(borders).
+    #  @return list of SMESH.FreeEdges.Border structure: edge id and two its nodes ids.
+    def GetFreeBorders(self):
         aFilterMgr = smesh.CreateFilterManager()
-        aFilter = aFilterMgr.CreateFilter()
-        aCriteria = []
-        aCriteria.append(aCriterion)
-        aFilter.SetCriteria(aCriteria)
-        return aFilter
-        
+        aPredicate = aFilterMgr.CreateFreeEdges()
+        aPredicate.SetMesh(self.mesh)
+        aBorders = aPredicate.GetBorders()
+        return aBorders
+                
     ## Remove a group
     def RemoveGroup(self, group):
         self.mesh.RemoveGroup(group)
@@ -1190,8 +1597,8 @@ class Mesh:
         return self.mesh.CutGroups(mainGroup, toolGroup, name)
          
     
-    ## Get some info about mesh:
-    #  ------------------------
+    # Get some info about mesh:
+    # ------------------------
 
     ## Get the log of nodes and elements added or removed since previous
     #  clear of the log.
@@ -1231,8 +1638,8 @@ class Mesh:
         return self.mesh.GetMEDMesh()
     
     
-    ## Get informations about mesh contents:
-    #  ------------------------------------
+    # Get informations about mesh contents:
+    # ------------------------------------
 
     ## Returns number of nodes in mesh
     def NbNodes(self):
@@ -1357,8 +1764,8 @@ class Mesh:
     def GetNodesId(self):
         return self.mesh.GetNodesId()
     
-    ## Get informations about mesh elements:
-    #  ------------------------------------
+    # Get informations about mesh elements:
+    # ------------------------------------
     
     ## Returns type of mesh element
     def GetElementType(self, id, iselem):
@@ -1384,33 +1791,38 @@ class Mesh:
         return self.mesh.Dump()
 
     
-    ## Get information about nodes and elements of mesh by its ids:
-    #  -----------------------------------------------------------
+    # Get information about nodes and elements of mesh by its ids:
+    # -----------------------------------------------------------
 
     ## Get XYZ coordinates of node as list of double
-    #  If there is not node for given ID - returns empty list
+    #  \n If there is not node for given ID - returns empty list
     def GetNodeXYZ(self, id):
         return self.mesh.GetNodeXYZ(id)
 
     ## For given node returns list of IDs of inverse elements
-    #  If there is not node for given ID - returns empty list
+    #  \n If there is not node for given ID - returns empty list
     def GetNodeInverseElements(self, id):
         return self.mesh.GetNodeInverseElements(id)
-    
+
     ## If given element is node returns IDs of shape from position
-    # else - return ID of result shape after Mesh.FindShape()
-    # If there is not element for given ID - returns -1
+    #  \n If there is not node for given ID - returns -1
     def GetShapeID(self, id):
         return self.mesh.GetShapeID(id)
 
+    ## 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):
+        return self.mesh.GetShapeIDForElem(id)
+    
     ## Returns number of nodes for given element
-    #  If there is not element for given ID - returns -1
+    #  \n If there is not element for given ID - returns -1
     def GetElemNbNodes(self, id):
         return self.mesh.GetElemNbNodes(id)
 
     ## Returns ID of node by given index for given element
-    #  If there is not element for given ID - returns -1
-    #  If there is not node for given index - returns -2
+    #  \n If there is not element for given ID - returns -1
+    #  \n If there is not node for given index - returns -2
     def GetElemNode(self, id, index):
         return self.mesh.GetElemNode(id, index)
 
@@ -1442,13 +1854,13 @@ class Mesh:
 
     ## Returns XYZ coordinates of bary center for given element
     #  as list of double
-    #  If there is not element for given ID - returns empty list
+    #  \n If there is not element for given ID - returns empty list
     def BaryCenter(self, id):
         return self.mesh.BaryCenter(id)
     
     
-    ## Mesh edition (SMESH_MeshEditor functionality):
-    #  ---------------------------------------------
+    # Mesh edition (SMESH_MeshEditor functionality):
+    # ---------------------------------------------
 
     ## Removes elements from mesh by ids
     #  @param IDsOfElements is list of ids of elements to remove
@@ -1469,7 +1881,7 @@ class Mesh:
     #  by number of given nodes).
     #  @param IdsOfNodes List of node IDs for creation of element.
     #  Needed order of nodes in this list corresponds to description
-    #  of MED. This description is located by the following link:
+    #  of MED. \n This description is located by the following link:
     #  http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
     def AddEdge(self, IDsOfNodes):
         return self.editor.AddEdge(IDsOfNodes)
@@ -1478,7 +1890,7 @@ class Mesh:
     #  by number of given nodes).
     #  @param IdsOfNodes List of node IDs for creation of element.
     #  Needed order of nodes in this list corresponds to description
-    #  of MED. This description is located by the following link:
+    #  of MED. \n This description is located by the following link:
     #  http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
     def AddFace(self, IDsOfNodes):
         return self.editor.AddFace(IDsOfNodes)
@@ -1491,7 +1903,7 @@ class Mesh:
     #  by number of given nodes).
     #  @param IdsOfNodes List of node IDs for creation of element.
     #  Needed order of nodes in this list corresponds to description
-    #  of MED. This description is located by the following link:
+    #  of MED. \n This description is located by the following link:
     #  http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
     def AddVolume(self, IDsOfNodes):
         return self.editor.AddVolume(IDsOfNodes)
@@ -1513,12 +1925,29 @@ class Mesh:
     
     ## 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
@@ -1549,37 +1978,38 @@ class Mesh:
 
     ## Fuse neighbour triangles into quadrangles.
     #  @param IDsOfElements The triangles to be fused,
-    #  @param Criterion     is used to choose a neighbour to fuse with.
+    #  @param theCriterion     is FT_...; used to choose a neighbour to fuse with.
     #  @param MaxAngle      is a max angle between element normals at which fusion
     #                       is still performed; theMaxAngle is mesured in radians.
     #  @return TRUE in case of success, FALSE otherwise.
-    def TriToQuad(self, IDsOfElements, Criterion, MaxAngle):
+    def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
-        return self.editor.TriToQuad(IDsOfElements, Criterion, MaxAngle)
+        return self.editor.TriToQuad(IDsOfElements, GetFunctor(theCriterion), MaxAngle)
 
     ## Fuse neighbour triangles of the object into quadrangles
     #  @param theObject is mesh, submesh or group
-    #  @param Criterion is used to choose a neighbour to fuse with.
+    #  @param theCriterion is FT_...; used to choose a neighbour to fuse with.
     #  @param MaxAngle  is a max angle between element normals at which fusion
     #                   is still performed; theMaxAngle is mesured in radians.
     #  @return TRUE in case of success, FALSE otherwise.
-    def TriToQuadObject (self, theObject, Criterion, MaxAngle):
-        return self.editor.TriToQuadObject(theObject, Criterion, MaxAngle)
+    def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
+        return self.editor.TriToQuadObject(theObject, GetFunctor(theCriterion), MaxAngle)
 
     ## Split quadrangles into triangles.
     #  @param IDsOfElements the faces to be splitted.
-    #  @param theCriterion  is used to choose a diagonal for splitting.
+    #  @param theCriterion  is FT_...; used to choose a diagonal for splitting.
     #  @param @return TRUE in case of success, FALSE otherwise.
-    def QuadToTri (self, IDsOfElements, Criterion):
+    def QuadToTri (self, IDsOfElements, theCriterion):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
-        return self.editor.QuadToTri(IDsOfElements, Criterion)
+        return self.editor.QuadToTri(IDsOfElements, GetFunctor(theCriterion))
 
     ## Split quadrangles into triangles.
     #  @param theObject object to taking list of elements from, is mesh, submesh or group
-    def QuadToTriObject (self, theObject, Criterion):
-        return self.editor.QuadToTriObject(theObject, Criterion)
+    #  @param theCriterion  is FT_...; used to choose a diagonal for splitting.
+    def QuadToTriObject (self, theObject, theCriterion):
+        return self.editor.QuadToTriObject(theObject, GetFunctor(theCriterion))
 
     ## Split quadrangles into triangles.
     #  @param theElems  The faces to be splitted
@@ -1597,11 +2027,150 @@ class Mesh:
 
     ## Find better splitting of the given quadrangle.
     #  @param IDOfQuad  ID of the quadrangle to be splitted.
-    #  @param Criterion is a criterion to choose a diagonal for splitting.
+    #  @param theCriterion is FT_...; a criterion to choose a diagonal for splitting.
     #  @return 1 if 1-3 diagonal is better, 2 if 2-4
     #          diagonal is better, 0 if error occurs.
-    def BestSplit (self, IDOfQuad, Criterion):
-        return self.editor.BestSplit(IDOfQuad, Criterion)
+    def BestSplit (self, IDOfQuad, theCriterion):
+        return self.editor.BestSplit(IDOfQuad, GetFunctor(theCriterion))
+
+    ## Split quafrangle faces near triangular facets of volumes
+    #
+    def SplitQuadsNearTriangularFacets(self):
+        faces_array = self.GetElementsByType(SMESH.FACE)
+        for face_id in faces_array:
+            if self.GetElemNbNodes(face_id) == 4: # quadrangle
+                quad_nodes = self.mesh.GetElemNodes(face_id)
+                node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
+                isVolumeFound = False
+                for node1_elem in node1_elems:
+                    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
+                                volume_elem = node1_elem
+                                volume_nodes = self.mesh.GetElemNodes(volume_elem)
+                                if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
+                                    if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
+                                        isVolumeFound = True
+                                        if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
+                                            self.SplitQuad([face_id], False) # diagonal 2-4
+                                    elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
+                                        isVolumeFound = True
+                                        self.SplitQuad([face_id], True) # diagonal 1-3
+                                elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
+                                    if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
+                                        isVolumeFound = True
+                                        self.SplitQuad([face_id], True) # diagonal 1-3
+
+    ## @brief Split hexahedrons into tetrahedrons.
+    #
+    #  Use pattern mapping functionality for splitting.
+    #  @param theObject object to take list of hexahedrons from; is mesh, submesh or group.
+    #  @param theNode000,theNode001 is in range [0,7]; give an orientation of the
+    #         pattern relatively each hexahedron: the (0,0,0) key-point of pattern
+    #         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.
+    #  @return TRUE in case of success, FALSE otherwise.
+    def SplitHexaToTetras (self, theObject, theNode000, theNode001):
+        # Pattern:     5.---------.6
+        #              /|#*      /|
+        #             / | #*    / |
+        #            /  |  # * /  |
+        #           /   |   # /*  |
+        # (0,0,1) 4.---------.7 * |
+        #          |#*  |1   | # *|
+        #          | # *.----|---#.2
+        #          |  #/ *   |   /
+        #          |  /#  *  |  /
+        #          | /   # * | /
+        #          |/      #*|/
+        # (0,0,0) 0.---------.3
+        pattern_tetra = "!!! Nb of points: \n 8 \n\
+        !!! Points: \n\
+        0 0 0  !- 0 \n\
+        0 1 0  !- 1 \n\
+        1 1 0  !- 2 \n\
+        1 0 0  !- 3 \n\
+        0 0 1  !- 4 \n\
+        0 1 1  !- 5 \n\
+        1 1 1  !- 6 \n\
+        1 0 1  !- 7 \n\
+        !!! Indices of points of 6 tetras: \n\
+        0 3 4 1 \n\
+        7 4 3 1 \n\
+        4 7 5 1 \n\
+        6 2 5 7 \n\
+        1 5 2 7 \n\
+        2 3 1 7 \n"
+
+        pattern = GetPattern()
+        isDone  = pattern.LoadFromFile(pattern_tetra)
+        if not isDone:
+            print 'Pattern.LoadFromFile :', pattern.GetErrorCode()
+            return isDone
+
+        pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
+        isDone = pattern.MakeMesh(self.mesh, False, False)
+        if not isDone: print 'Pattern.MakeMesh :', pattern.GetErrorCode()
+
+        # split quafrangle faces near triangular facets of volumes
+        self.SplitQuadsNearTriangularFacets()
+
+        return isDone
+
+    ## @brief Split hexahedrons into prisms.
+    #
+    #  Use pattern mapping functionality for splitting.
+    #  @param theObject object to take list of hexahedrons from; is mesh, submesh or group.
+    #  @param theNode000,theNode001 is in range [0,7]; give an orientation of the
+    #         pattern relatively each hexahedron: the (0,0,0) key-point of pattern
+    #         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 edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
+    #  @param @return TRUE in case of success, FALSE otherwise.
+    def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
+        # Pattern:     5.---------.6
+        #              /|#       /|
+        #             / | #     / |
+        #            /  |  #   /  |
+        #           /   |   # /   |
+        # (0,0,1) 4.---------.7   |
+        #          |    |    |    |
+        #          |   1.----|----.2
+        #          |   / *   |   /
+        #          |  /   *  |  /
+        #          | /     * | /
+        #          |/       *|/
+        # (0,0,0) 0.---------.3
+        pattern_prism = "!!! Nb of points: \n 8 \n\
+        !!! Points: \n\
+        0 0 0  !- 0 \n\
+        0 1 0  !- 1 \n\
+        1 1 0  !- 2 \n\
+        1 0 0  !- 3 \n\
+        0 0 1  !- 4 \n\
+        0 1 1  !- 5 \n\
+        1 1 1  !- 6 \n\
+        1 0 1  !- 7 \n\
+        !!! Indices of points of 2 prisms: \n\
+        0 1 3 4 5 7 \n\
+        2 3 1 6 7 5 \n"
+
+        pattern = GetPattern()
+        isDone  = pattern.LoadFromFile(pattern_prism)
+        if not isDone:
+            print 'Pattern.LoadFromFile :', pattern.GetErrorCode()
+            return isDone
+
+        pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
+        isDone = pattern.MakeMesh(self.mesh, False, False)
+        if not isDone: print 'Pattern.MakeMesh :', pattern.GetErrorCode()
+
+        # split quafrangle faces near triangular facets of volumes
+        self.SplitQuadsNearTriangularFacets()
+
+        return isDone
     
     ## Smooth elements
     #  @param IDsOfElements list if ids of elements to smooth
@@ -1661,7 +2230,7 @@ class Mesh:
         self.editor.ConvertToQuadratic(theForce3d)
 
     ## Converts all mesh from quadratic to ordinary ones,
-    #  deletes old quadratic elements, replacing 
+    #  deletes old quadratic elements, \n replacing 
     #  them with ordinary mesh elements with the same id.
     def ConvertFromQuadratic(self):
         return self.editor.ConvertFromQuadratic()
@@ -1759,13 +2328,15 @@ 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 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, LinearVariation=False):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( RefPoint, geompy.GEOM._objref_GEOM_Object)):
-            RefPoint = GetPointStruct(RefPoint) 
-        return self.editor.ExtrusionAlongPath(IDsOfElements, PathMesh, PathShape, NodeStart,
+            RefPoint = GetPointStruct(RefPoint)
+            pass
+        return self.editor.ExtrusionAlongPath(IDsOfElements, PathMesh.GetMesh(), PathShape, NodeStart,
                                               HasAngles, Angles, HasRefPoint, RefPoint)
 
     ## Generate new elements by extrusion of the elements belong to object
@@ -1779,12 +2350,13 @@ 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 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, LinearVariation=False):
         if ( isinstance( RefPoint, geompy.GEOM._objref_GEOM_Object)):
             RefPoint = GetPointStruct(RefPoint) 
-        return self.editor.ExtrusionAlongPathObject(theObject, PathMesh, PathShape, NodeStart,
-                                                    HasAngles, Angles, HasRefPoint, RefPoint)
+        return self.editor.ExtrusionAlongPathObject(theObject, PathMesh.GetMesh(), PathShape, NodeStart,
+                                                    HasAngles, Angles, HasRefPoint, RefPoint, LinearVariation)
     
     ## Symmetrical copy of mesh elements
     #  @param IDsOfElements list of elements ids
@@ -1856,11 +2428,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()
@@ -1906,13 +2496,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, if new nodes
-    #  not created - returns empty list
+    #  created this method returns list of it's 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, if new elements
-    #  not creared - returns empty list
+    #  created this method returns list of it's IDs, \n
+    #  if new elements not creared - returns empty list
     def GetLastCreatedElems(self):
         return self.editor.GetLastCreatedElems()