Salome HOME
PR: synchro V7_main tag mergefrom_V6_main_06Mar13
[modules/smesh.git] / src / SMESH_SWIG / smeshDC.py
index 578e0970d1c33a92e240427949fa4714a426b239..70f259314e26ea8065719b1c2cdd1b8ac32b081f 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 #
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
-#  File   : smesh.py
+#  File   : smeshDC.py
 #  Author : Francis KLOSS, OCC
 #  Module : SMESH
 
-"""
- \namespace smesh
- \brief Module smesh
-"""
+## @package smeshDC
+#  Python API for SALOME %Mesh module
 
 ## @defgroup l1_auxiliary Auxiliary methods and structures
 ## @defgroup l1_creating  Creating meshes
 ##     @defgroup l3_hypos_1dhyps 1D Meshing Hypotheses
 ##     @defgroup l3_hypos_2dhyps 2D Meshing Hypotheses
 ##     @defgroup l3_hypos_maxvol Max Element Volume hypothesis
-##     @defgroup l3_hypos_netgen Netgen 2D and 3D hypotheses
-##     @defgroup l3_hypos_ghs3dh GHS3D Parameters hypothesis
-##     @defgroup l3_hypos_blsurf BLSURF Parameters hypothesis
-##     @defgroup l3_hypos_hexotic Hexotic Parameters hypothesis
 ##     @defgroup l3_hypos_quad Quadrangle Parameters hypothesis
 ##     @defgroup l3_hypos_additi Additional Hypotheses
 
@@ -93,9 +87,11 @@ import geompyDC
 
 import SMESH # This is necessary for back compatibility
 from   SMESH import *
+from   smesh_algorithm import Mesh_Algorithm
 
 import SALOME
 import SALOMEDS
+import os
 
 ## @addtogroup l1_auxiliary
 ## @{
@@ -132,6 +128,7 @@ var_separator = ":"
 def ParseParameters(*args):
     Result = []
     Parameters = ""
+    hasVariables = False
     varModifFun=None
     if args and callable( args[-1] ):
         args, varModifFun = args[:-1], args[-1]
@@ -144,6 +141,7 @@ def ParseParameters(*args):
             if not notebook.isVariable(parameter):
                 raise ValueError, "Variable with name '" + parameter + "' doesn't exist!!!"
             parameter = notebook.get(parameter)
+            hasVariables = True
             if varModifFun:
                 parameter = varModifFun(parameter)
                 pass
@@ -153,6 +151,7 @@ def ParseParameters(*args):
         pass
     Parameters = Parameters[:-1]
     Result.append( Parameters )
+    Result.append( hasVariables )
     return Result
 
 # Parse parameters converting variables to radians
@@ -162,14 +161,14 @@ def ParseAngles(*args):
 # Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
 # Parameters are stored in PointStruct.parameters attribute
 def __initPointStruct(point,*args):
-    point.x, point.y, point.z, point.parameters = ParseParameters(*args)
+    point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
     pass
 SMESH.PointStruct.__init__ = __initPointStruct
 
 # Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
 # Parameters are stored in AxisStruct.parameters attribute
 def __initAxisStruct(ax,*args):
-    ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters = ParseParameters(*args)
+    ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
     pass
 SMESH.AxisStruct.__init__ = __initAxisStruct
 
@@ -188,7 +187,10 @@ def GetName(obj):
         if isinstance(obj, SALOMEDS._objref_SObject):
             # study object
             return obj.GetName()
-        ior  = salome.orb.object_to_string(obj)
+        try:
+            ior  = salome.orb.object_to_string(obj)
+        except:
+            ior = None
         if ior:
             # CORBA object
             studies = salome.myStudyManager.GetOpenStudies()
@@ -257,7 +259,8 @@ def TreatHypoStatus(status, hypName, geomName, isAlgo):
 def AssureGeomPublished(mesh, geom, name=''):
     if not isinstance( geom, geompyDC.GEOM._objref_GEOM_Object ):
         return
-    if not geom.IsSame( mesh.geom ) and not geom.GetStudyEntry():
+    if not geom.GetStudyEntry() and \
+           mesh.smeshpyD.GetCurrentStudy():
         ## set the study
         studyID = mesh.smeshpyD.GetCurrentStudy()._get_StudyId()
         if studyID != mesh.geompyD.myStudyId:
@@ -272,17 +275,16 @@ def AssureGeomPublished(mesh, geom, name=''):
         mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
     return
 
-## Return the first vertex of a geomertical edge by ignoring orienation
+## Return the first vertex of a geometrical edge by ignoring orientation
 def FirstVertexOnCurve(edge):
-    from geompy import SubShapeAll, ShapeType, KindOfShape, PointCoordinates
-    vv = SubShapeAll( edge, ShapeType["VERTEX"])
+    vv = geompyDC.SubShapeAll( edge, geompyDC.ShapeType["VERTEX"])
     if not vv:
         raise TypeError, "Given object has no vertices"
     if len( vv ) == 1: return vv[0]
-    info = KindOfShape(edge)
+    info = geompyDC.KindOfShape(edge)
     xyz = info[1:4] # coords of the first vertex
-    xyz1  = PointCoordinates( vv[0] )
-    xyz2  = PointCoordinates( vv[1] )
+    xyz1  = geompyDC.PointCoordinates( vv[0] )
+    xyz2  = geompyDC.PointCoordinates( vv[1] )
     dist1, dist2 = 0,0
     for i in range(3):
         dist1 += abs( xyz[i] - xyz1[i] )
@@ -295,8 +297,53 @@ def FirstVertexOnCurve(edge):
 # end of l1_auxiliary
 ## @}
 
-# All methods of this class are accessible directly from the smesh.py package.
-class smeshDC(SMESH._objref_SMESH_Gen):
+
+# Warning: smeshInst is a singleton
+smeshInst = None
+engine = None
+doLcc = False
+
+class smeshDC(object, SMESH._objref_SMESH_Gen):
+
+    def __new__(cls):
+        global engine
+        global smeshInst
+        global doLcc
+        print "__new__", engine, smeshInst, doLcc
+
+        if smeshInst is None:
+            # smesh engine is either retrieved from engine, or created
+            smeshInst = engine
+            # Following test avoids a recursive loop
+            if doLcc:
+                if smeshInst is not None:
+                    # smesh engine not created: existing engine found
+                    doLcc = False
+                if doLcc:
+                    doLcc = False
+                    # FindOrLoadComponent called:
+                    # 1. CORBA resolution of server
+                    # 2. the __new__ method is called again
+                    print "smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc
+                    smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
+            else:
+                # FindOrLoadComponent not called
+                if smeshInst is None:
+                    # smeshDC instance is created from lcc.FindOrLoadComponent
+                    print "smeshInst = super(smeshDC,cls).__new__(cls) ", engine, smeshInst, doLcc
+                    smeshInst = super(smeshDC,cls).__new__(cls)
+                else:
+                    # smesh engine not created: existing engine found
+                    print "existing ", engine, smeshInst, doLcc
+                    pass
+
+            return smeshInst
+
+        return smeshInst
+
+    def __init__(self):
+        print "__init__"
+        SMESH._objref_SMESH_Gen.__init__(self)
 
     ## Dump component to the Python script
     #  This method overrides IDL function to allow default values for the parameters.
@@ -315,7 +362,8 @@ class smeshDC(SMESH._objref_SMESH_Gen):
 
     ## Sets the current study and Geometry component
     #  @ingroup l1_auxiliary
-    def init_smesh(self,theStudy,geompyD):
+    def init_smesh(self,theStudy,geompyD = None):
+        print "init_smesh"
         self.SetCurrentStudy(theStudy,geompyD)
 
     ## Creates an empty Mesh. This mesh can have an underlying geometry.
@@ -330,7 +378,6 @@ class smeshDC(SMESH._objref_SMESH_Gen):
         return Mesh(self,self.geompyD,obj,name)
 
     ## Returns a long value from enumeration
-    #  Should be used for SMESH.FunctorType enumeration
     #  @ingroup l1_controls
     def EnumToLong(self,theItem):
         return theItem._v
@@ -438,12 +485,17 @@ class smeshDC(SMESH._objref_SMESH_Gen):
     def SetCurrentStudy( self, theStudy, geompyD = None ):
         #self.SetCurrentStudy(theStudy)
         if not geompyD:
-            import geompy
-            geompyD = geompy.geom
+            import geompyDC
+            geompyD = geompyDC.geom
             pass
         self.geompyD=geompyD
         self.SetGeomEngine(geompyD)
         SMESH._objref_SMESH_Gen.SetCurrentStudy(self,theStudy)
+        global notebook
+        if theStudy:
+            notebook = salome_notebook.NoteBook( theStudy )
+        else:
+            notebook = salome_notebook.NoteBook( salome_notebook.PseudoStudyForNoteBook() )
 
     ## Gets the current study
     #  @ingroup l1_auxiliary
@@ -500,6 +552,16 @@ class smeshDC(SMESH._objref_SMESH_Gen):
             aMeshes.append(aMesh)
         return aMeshes, aStatus
 
+    ## Creates a Mesh object importing data from the given GMF file
+    #  @return [ an instance of Mesh class, SMESH::ComputeError ]
+    #  @ingroup l2_impexp
+    def CreateMeshesFromGMF( self, theFileName ):
+        aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
+                                                                        theFileName,
+                                                                        True)
+        if error.comment: print "*** CreateMeshesFromGMF() errors:\n", error.comment
+        return Mesh(self, self.geompyD, aSmeshMesh), error
+
     ## Concatenate the given meshes into one mesh.
     #  @return an instance of Mesh class
     #  @param meshes the meshes to combine into one mesh
@@ -507,13 +569,15 @@ class smeshDC(SMESH._objref_SMESH_Gen):
     #  @param mergeNodesAndElements if true, equal nodes and elements aremerged
     #  @param mergeTolerance tolerance for merging nodes
     #  @param allGroups forces creation of groups of all elements
+    #  @param name name of a new mesh
     def Concatenate( self, meshes, uniteIdenticalGroups,
-                     mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
+                     mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
+                     name = ""):
         if not meshes: return None
         for i,m in enumerate(meshes):
             if isinstance(m, Mesh):
                 meshes[i] = m.GetMesh()
-        mergeTolerance,Parameters = ParseParameters(mergeTolerance)
+        mergeTolerance,Parameters,hasVars = ParseParameters(mergeTolerance)
         meshes[0].SetParameters(Parameters)
         if allGroups:
             aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
@@ -521,7 +585,7 @@ class smeshDC(SMESH._objref_SMESH_Gen):
         else:
             aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
                 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
-        aMesh = Mesh(self, self.geompyD, aSmeshMesh)
+        aMesh = Mesh(self, self.geompyD, aSmeshMesh, name=name)
         return aMesh
 
     ## Create a mesh by copying a part of another mesh.
@@ -624,10 +688,16 @@ class smeshDC(SMESH._objref_SMESH_Gen):
 
         if CritType in [FT_BelongToGeom,     FT_BelongToPlane, FT_BelongToGenSurface,
                         FT_BelongToCylinder, FT_LyingOnGeom]:
-            # Checks the Threshold
+            # Checks that Threshold is GEOM object
             if isinstance(aThreshold, geompyDC.GEOM._objref_GEOM_Object):
                 aCriterion.ThresholdStr = GetName(aThreshold)
-                aCriterion.ThresholdID = salome.ObjectToID(aThreshold)
+                aCriterion.ThresholdID  = aThreshold.GetStudyEntry()
+                if not aCriterion.ThresholdID:
+                    name = aCriterion.ThresholdStr
+                    if not name:
+                        name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
+                    aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
+                    #raise RuntimeError, "Threshold shape must be published"
             else:
                 print "Error: The Threshold should be a shape."
                 return None
@@ -636,7 +706,7 @@ class smeshDC(SMESH._objref_SMESH_Gen):
                 UnaryOp = FT_Undefined
                 pass
         elif CritType == FT_RangeOfIds:
-            # Checks the Threshold
+            # Checks that Threshold is string
             if isinstance(aThreshold, str):
                 aCriterion.ThresholdStr = aThreshold
             else:
@@ -645,7 +715,7 @@ class smeshDC(SMESH._objref_SMESH_Gen):
         elif CritType == FT_CoplanarFaces:
             # Checks the Threshold
             if isinstance(aThreshold, int):
-                aCriterion.ThresholdID = "%s"%aThreshold
+                aCriterion.ThresholdID = str(aThreshold)
             elif isinstance(aThreshold, str):
                 ID = int(aThreshold)
                 if ID < 1:
@@ -667,6 +737,20 @@ class smeshDC(SMESH._objref_SMESH_Gen):
                     return None
                 pass
             pass
+        elif CritType == FT_EntityType:
+            # Checks the Threshold
+            try:
+                aCriterion.Threshold = self.EnumToLong(aThreshold)
+                assert( aThreshold in SMESH.EntityType._items )
+            except:
+                if isinstance(aThreshold, int):
+                    aCriterion.Threshold = aThreshold
+                else:
+                    print "Error: The Threshold should be an integer or SMESH.EntityType."
+                    return None
+                pass
+            pass
+        
         elif CritType == FT_GroupColor:
             # Checks the Threshold
             try:
@@ -753,37 +837,42 @@ class smeshDC(SMESH._objref_SMESH_Gen):
     #  @return SMESH_NumericalFunctor
     #  @ingroup l1_controls
     def GetFunctor(self,theCriterion):
+        if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
+            return theCriterion
         aFilterMgr = self.CreateFilterManager()
+        functor = None
         if theCriterion == FT_AspectRatio:
-            return aFilterMgr.CreateAspectRatio()
+            functor = aFilterMgr.CreateAspectRatio()
         elif theCriterion == FT_AspectRatio3D:
-            return aFilterMgr.CreateAspectRatio3D()
+            functor = aFilterMgr.CreateAspectRatio3D()
         elif theCriterion == FT_Warping:
-            return aFilterMgr.CreateWarping()
+            functor = aFilterMgr.CreateWarping()
         elif theCriterion == FT_MinimumAngle:
-            return aFilterMgr.CreateMinimumAngle()
+            functor = aFilterMgr.CreateMinimumAngle()
         elif theCriterion == FT_Taper:
-            return aFilterMgr.CreateTaper()
+            functor = aFilterMgr.CreateTaper()
         elif theCriterion == FT_Skew:
-            return aFilterMgr.CreateSkew()
+            functor = aFilterMgr.CreateSkew()
         elif theCriterion == FT_Area:
-            return aFilterMgr.CreateArea()
+            functor = aFilterMgr.CreateArea()
         elif theCriterion == FT_Volume3D:
-            return aFilterMgr.CreateVolume3D()
+            functor = aFilterMgr.CreateVolume3D()
         elif theCriterion == FT_MaxElementLength2D:
-            return aFilterMgr.CreateMaxElementLength2D()
+            functor = aFilterMgr.CreateMaxElementLength2D()
         elif theCriterion == FT_MaxElementLength3D:
-            return aFilterMgr.CreateMaxElementLength3D()
+            functor = aFilterMgr.CreateMaxElementLength3D()
         elif theCriterion == FT_MultiConnection:
-            return aFilterMgr.CreateMultiConnection()
+            functor = aFilterMgr.CreateMultiConnection()
         elif theCriterion == FT_MultiConnection2D:
-            return aFilterMgr.CreateMultiConnection2D()
+            functor = aFilterMgr.CreateMultiConnection2D()
         elif theCriterion == FT_Length:
-            return aFilterMgr.CreateLength()
+            functor = aFilterMgr.CreateLength()
         elif theCriterion == FT_Length2D:
-            return aFilterMgr.CreateLength2D()
+            functor = aFilterMgr.CreateLength2D()
         else:
             print "Error: given parameter is not numerical functor type."
+        aFilterMgr.UnRegister()
+        return functor
 
     ## Creates hypothesis
     #  @param theHType mesh hypothesis type (string)
@@ -929,6 +1018,19 @@ import omniORB
 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshDC)
 
 
+def smeshInstance( study, instance=None):
+    global engine
+    global smeshInst
+    global doLcc
+    engine = instance
+    if engine is None:
+      doLcc = True
+    smeshInst = smeshDC()
+    assert isinstance(smeshInst,smeshDC), "Smesh engine class is %s but should be smeshDC.smeshDC. Import smeshmapi before creating the instance."%smeshInst.__class__
+    smeshInst.init_smesh(study)
+    return smeshInst
+
+
 # Public class: Mesh
 # ==================
 
@@ -957,16 +1059,22 @@ class Mesh:
         self.geompyD=geompyD
         if obj is None:
             obj = 0
+        objHasName = False
         if obj != 0:
             if isinstance(obj, geompyDC.GEOM._objref_GEOM_Object):
                 self.geom = obj
+                objHasName = True
                 # publish geom of mesh (issue 0021122)
-                if not self.geom.GetStudyEntry():
+                if not self.geom.GetStudyEntry() and smeshpyD.GetCurrentStudy():
+                    objHasName = False
                     studyID = smeshpyD.GetCurrentStudy()._get_StudyId()
                     if studyID != geompyD.myStudyId:
                         geompyD.init_geom( smeshpyD.GetCurrentStudy())
                         pass
-                    geo_name = "%s_%s"%(self.geom.GetShapeType(), id(self.geom)%100)
+                    if name:
+                        geo_name = name + " shape"
+                    else:
+                        geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
                     geompyD.addToStudy( self.geom, geo_name )
                 self.mesh = self.smeshpyD.CreateMesh(self.geom)
 
@@ -974,28 +1082,33 @@ class Mesh:
                 self.SetMesh(obj)
         else:
             self.mesh = self.smeshpyD.CreateEmptyMesh()
-        if name != 0:
+        if name:
             self.smeshpyD.SetName(self.mesh, name)
-        elif obj != 0:
-            self.smeshpyD.SetName(self.mesh, GetName(obj))
+        elif objHasName:
+            self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
 
         if not self.geom:
             self.geom = self.mesh.GetShapeToMesh()
 
-        self.editor = self.mesh.GetMeshEditor()
+        self.editor   = self.mesh.GetMeshEditor()
+        self.functors = [None] * SMESH.FT_Undefined._v
 
         # set self to algoCreator's
         for attrName in dir(self):
             attr = getattr( self, attrName )
             if isinstance( attr, algoCreator ):
+                print "algoCreator ", attrName
                 setattr( self, attrName, attr.copy( self ))
 
     ## Initializes the Mesh object from an instance of SMESH_Mesh interface
     #  @param theMesh a SMESH_Mesh object
     #  @ingroup l2_construct
     def SetMesh(self, theMesh):
+        if self.mesh: self.mesh.UnRegister()
         self.mesh = theMesh
-        self.geom = self.mesh.GetShapeToMesh()
+        if self.mesh:
+            self.mesh.Register()
+            self.geom = self.mesh.GetShapeToMesh()
 
     ## Returns the mesh, that is an instance of SMESH_Mesh interface
     #  @return a SMESH_Mesh object
@@ -1069,19 +1182,25 @@ class Mesh:
         return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
 
     ## Returns the mesh dimension depending on the dimension of the underlying shape
+    #  or, if the mesh is not based on any shape, basing on deimension of elements
     #  @return mesh dimension as an integer value [0,3]
     #  @ingroup l1_auxiliary
     def MeshDimension(self):
-        shells = self.geompyD.SubShapeAllIDs( self.geom, geompyDC.ShapeType["SHELL"] )
-        if len( shells ) > 0 :
-            return 3
-        elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
-            return 2
-        elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
-            return 1
+        if self.mesh.HasShapeToMesh():
+            shells = self.geompyD.SubShapeAllIDs( self.geom, geompyDC.ShapeType["SOLID"] )
+            if len( shells ) > 0 :
+                return 3
+            elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
+                return 2
+            elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
+                return 1
+            else:
+                return 0;
         else:
-            return 0;
-        pass
+            if self.NbVolumes() > 0: return 3
+            if self.NbFaces()   > 0: return 2
+            if self.NbEdges()   > 0: return 1
+        return 0
 
     ## Evaluates size of prospective mesh on a shape
     #  @return a list where i-th element is a number of elements of i-th SMESH.EntityType
@@ -1159,15 +1278,18 @@ class Mesh:
                     except:
                         shapeText = " on subshape #%s" % (err.subShapeID)
                 errText = ""
-                stdErrors = ["OK",                 #COMPERR_OK
-                             "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
-                             "std::exception",     #COMPERR_STD_EXCEPTION
-                             "OCC exception",      #COMPERR_OCC_EXCEPTION
-                             "SALOME exception",   #COMPERR_SLM_EXCEPTION
-                             "Unknown exception",  #COMPERR_EXCEPTION
+                stdErrors = ["OK",                   #COMPERR_OK
+                             "Invalid input mesh",   #COMPERR_BAD_INPUT_MESH
+                             "std::exception",       #COMPERR_STD_EXCEPTION
+                             "OCC exception",        #COMPERR_OCC_EXCEPTION
+                             "..",                   #COMPERR_SLM_EXCEPTION
+                             "Unknown exception",    #COMPERR_EXCEPTION
                              "Memory allocation problem", #COMPERR_MEMORY_PB
-                             "Algorithm failed",   #COMPERR_ALGO_FAILED
-                             "Unexpected geometry"]#COMPERR_BAD_SHAPE
+                             "Algorithm failed",     #COMPERR_ALGO_FAILED
+                             "Unexpected geometry",  #COMPERR_BAD_SHAPE
+                             "Warning",              #COMPERR_WARNING
+                             "Computation cancelled",#COMPERR_CANCELED
+                             "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
                 if err.code > 0:
                     if err.code < len(stdErrors): errText = stdErrors[err.code]
                 else:
@@ -1175,7 +1297,7 @@ class Mesh:
                 if errText: errText += ". "
                 errText += err.comment
                 if allReasons != "":allReasons += "\n"
-                allReasons += '"%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
+                allReasons += '-  "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
                 pass
 
             # Treat hyp errors
@@ -1201,22 +1323,27 @@ class Mesh:
                 elif err.state == HYP_BAD_GEOMETRY:
                     reason = ('%s %sD algorithm "%s" is assigned to mismatching'
                               'geometry' % ( glob, dim, name ))
+                elif err.state == HYP_HIDDEN_ALGO:
+                    reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
+                              'algorithm of upper dimension generating %sD mesh'
+                              % ( glob, dim, name, glob, dim ))
                 else:
-                    reason = "For unknown reason."+\
-                             " Revise Mesh.Compute() implementation in smeshDC.py!"
+                    reason = ("For unknown reason. "
+                              "Developer, revise Mesh.Compute() implementation in smeshDC.py!")
                     pass
                 if allReasons != "":allReasons += "\n"
-                allReasons += reason
+                allReasons += "-  " + reason
                 pass
-            if allReasons != "":
-                print '"' + GetName(self.mesh) + '"',"has not been computed:"
+            if not ok or allReasons != "":
+                msg = '"' + GetName(self.mesh) + '"'
+                if ok: msg += " has been computed with warnings"
+                else:  msg += " has not been computed"
+                if allReasons != "": msg += ":"
+                else:                msg += "."
+                print msg
                 print allReasons
-                ok = False
-            elif not ok:
-                print '"' + GetName(self.mesh) + '"',"has not been computed."
-                pass
             pass
-        if salome.sg.hasDesktop():
+        if salome.sg.hasDesktop() and self.mesh.GetStudyId() >= 0:
             smeshgui = salome.ImportComponentGUI("SMESH")
             smeshgui.Init(self.mesh.GetStudyId())
             smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok, (self.NbNodes()==0) )
@@ -1240,7 +1367,8 @@ class Mesh:
     #  @ingroup l2_construct
     def Clear(self):
         self.mesh.Clear()
-        if salome.sg.hasDesktop():
+        if ( salome.sg.hasDesktop() and 
+             salome.myStudyManager.GetStudyByID( self.mesh.GetStudyId() )):
             smeshgui = salome.ImportComponentGUI("SMESH")
             smeshgui.Init(self.mesh.GetStudyId())
             smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
@@ -1305,6 +1433,7 @@ class Mesh:
             if not geom:
                 geom = self.mesh.GetShapeToMesh()
             pass
+        AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
         status = self.mesh.AddHypothesis(geom, hyp)
         isAlgo = hyp._narrow( SMESH_Algo )
         hyp_name = GetName( hyp )
@@ -1320,7 +1449,7 @@ class Mesh:
     #  @return True of False
     #  @ingroup l2_hypotheses
     def IsUsedHypothesis(self, hyp, geom):
-        if not hyp or not geom:
+        if not hyp: # or not geom
             return False
         if isinstance( hyp, Mesh_Algorithm ):
             hyp = hyp.GetAlgorithm()
@@ -1340,11 +1469,16 @@ class Mesh:
         if isinstance( hyp, Mesh_Algorithm ):
             hyp = hyp.GetAlgorithm()
             pass
-        if not geom:
-            geom = self.geom
+        shape = geom
+        if not shape:
+            shape = self.geom
             pass
-        status = self.mesh.RemoveHypothesis(geom, hyp)
-        return status
+        if self.IsUsedHypothesis( hyp, shape ):
+            return self.mesh.RemoveHypothesis( shape, hyp )
+        hypName = GetName( hyp )
+        geoName = GetName( shape )
+        print "WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName )
+        return None
 
     ## Gets the list of hypotheses added on a geometry
     #  @param geom a sub-shape of mesh geometry
@@ -1362,19 +1496,7 @@ class Mesh:
             pass
         pass
 
-    ## Deprecated, used only for compatibility! Please, use ExportToMEDX() method instead.
-    #  Exports the mesh in a file in MED format and chooses the \a version of MED format
-    ## allowing to overwrite the file if it exists or add the exported data to its contents
-    #  @param f the file name
-    #  @param version values are SMESH.MED_V2_1, SMESH.MED_V2_2
-    #  @param opt boolean parameter for creating/not creating
-    #         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
-    #  @param overwrite boolean parameter for overwriting/not overwriting the file
-    #  @ingroup l2_impexp
-    def ExportToMED(self, f, version, opt=0, overwrite=1):
-        self.mesh.ExportToMEDX(f, opt, version, overwrite)
-
-    ## Exports the mesh in a file in MED format and chooses the \a version of MED format
+   ## Exports the mesh in a file in MED format and chooses the \a version of MED format
     ## allowing to overwrite the file if it exists or add the exported data to its contents
     #  @param f is the file name
     #  @param auto_groups boolean parameter for creating/not creating
@@ -1452,6 +1574,31 @@ class Mesh:
             meshPart = self.mesh
         self.mesh.ExportCGNS(meshPart, f, overwrite)
 
+    ## Exports the mesh in a file in GMF format
+    #  @param f is the file name
+    #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
+    #  @ingroup l2_impexp
+    def ExportGMF(self, f, meshPart=None):
+        if isinstance( meshPart, list ):
+            meshPart = self.GetIDSource( meshPart, SMESH.ALL )
+        if isinstance( meshPart, Mesh ):
+            meshPart = meshPart.mesh
+        elif not meshPart:
+            meshPart = self.mesh
+        self.mesh.ExportGMF(meshPart, f, True)
+
+    ## Deprecated, used only for compatibility! Please, use ExportToMEDX() method instead.
+    #  Exports the mesh in a file in MED format and chooses the \a version of MED format
+    ## allowing to overwrite the file if it exists or add the exported data to its contents
+    #  @param f the file name
+    #  @param version values are SMESH.MED_V2_1, SMESH.MED_V2_2
+    #  @param opt boolean parameter for creating/not creating
+    #         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
+    #  @param overwrite boolean parameter for overwriting/not overwriting the file
+    #  @ingroup l2_impexp
+    def ExportToMED(self, f, version, opt=0, overwrite=1):
+        self.mesh.ExportToMEDX(f, opt, version, overwrite)
+
     # Operations with groups:
     # ----------------------
 
@@ -1596,26 +1743,6 @@ class Mesh:
         group.AddFrom( theFilter )
         return group
 
-    ## Passes mesh elements through the given filter and return IDs of fitting elements
-    #  @param theFilter SMESH_Filter
-    #  @return a list of ids
-    #  @ingroup l1_controls
-    def GetIdsFromFilter(self, theFilter):
-        theFilter.SetMesh( self.mesh )
-        return theFilter.GetIDs()
-
-    ## Verifies whether a 2D mesh element has free edges (edges connected to one face only)\n
-    #  Returns a list of special structures (borders).
-    #  @return a list of SMESH.FreeEdges.Border structure: edge id and ids of two its nodes.
-    #  @ingroup l1_controls
-    def GetFreeBorders(self):
-        aFilterMgr = self.smeshpyD.CreateFilterManager()
-        aPredicate = aFilterMgr.CreateFreeEdges()
-        aPredicate.SetMesh(self.mesh)
-        aBorders = aPredicate.GetBorders()
-        aFilterMgr.UnRegister()
-        return aBorders
-
     ## Removes a group
     #  @ingroup l2_grps_delete
     def RemoveGroup(self, group):
@@ -1767,14 +1894,14 @@ class Mesh:
     #  @return an instance of SMESH_MeshEditor
     #  @ingroup l1_modifying
     def GetMeshEditor(self):
-        return self.mesh.GetMeshEditor()
+        return self.editor
 
     ## Wrap a list of IDs of elements or nodes into SMESH_IDSource which
-    #  can be passed as argument to accepting mesh, group or sub-mesh
+    #  can be passed as argument to a method accepting mesh, group or sub-mesh
     #  @return an instance of SMESH_IDSource
     #  @ingroup l1_auxiliary
     def GetIDSource(self, ids, elemType):
-        return self.GetMeshEditor().MakeIDSource(ids, elemType)
+        return self.editor.MakeIDSource(ids, elemType)
 
     ## Gets MED Mesh
     #  @return an instance of SALOME_MED::MESH
@@ -1811,6 +1938,12 @@ class Mesh:
     def Nb0DElements(self):
         return self.mesh.Nb0DElements()
 
+    ## Returns the number of ball discrete elements in the mesh
+    #  @return an integer value
+    #  @ingroup l1_meshinfo
+    def NbBalls(self):
+        return self.mesh.NbBalls()
+
     ## Returns the number of edges in the mesh
     #  @return an integer value
     #  @ingroup l1_meshinfo
@@ -2027,7 +2160,7 @@ class Mesh:
     #  @ingroup l1_meshinfo
     def GetSubMeshNodesId(self, Shape, all):
         if ( isinstance( Shape, geompyDC.GEOM._objref_GEOM_Object)):
-            ShapeID = Shape.GetSubShapeIndices()[0]
+            ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
         else:
             ShapeID = Shape
         return self.mesh.GetSubMeshNodesId(ShapeID, all)
@@ -2074,6 +2207,12 @@ class Mesh:
     def GetNodePosition(self,NodeID):
         return self.mesh.GetNodePosition(NodeID)
 
+    ## @brief Returns the position of an element on the shape
+    #  @return SMESH::ElementPosition
+    #  @ingroup l1_meshinfo
+    def GetElementPosition(self,ElemID):
+        return self.mesh.GetElementPosition(ElemID)
+
     ## If the given element is a node, returns the ID of shape
     #  \n If there is no node for the given ID - returns -1
     #  @return an integer value
@@ -2096,7 +2235,7 @@ class Mesh:
     def GetElemNbNodes(self, id):
         return self.mesh.GetElemNbNodes(id)
 
-    ## Returns the node ID the given index for the given element
+    ## Returns the node ID the given (zero based) index for the given element
     #  \n If there is no element for the given ID - returns -1
     #  \n If there is no node for the given index - returns -2
     #  @return an integer value
@@ -2150,6 +2289,11 @@ class Mesh:
     def IsQuadratic(self, id):
         return self.mesh.IsQuadratic(id)
 
+    ## Returns diameter of a ball discrete element or zero in case of an invalid \a id
+    #  @ingroup l1_meshinfo
+    def GetBallDiameter(self, id):
+        return self.mesh.GetBallDiameter(id)
+
     ## Returns XYZ coordinates of the barycenter of the given element
     #  \n If there is no element for the given ID - returns an empty list
     #  @return a list of three double values
@@ -2157,6 +2301,26 @@ class Mesh:
     def BaryCenter(self, id):
         return self.mesh.BaryCenter(id)
 
+    ## Passes mesh elements through the given filter and return IDs of fitting elements
+    #  @param theFilter SMESH_Filter
+    #  @return a list of ids
+    #  @ingroup l1_controls
+    def GetIdsFromFilter(self, theFilter):
+        theFilter.SetMesh( self.mesh )
+        return theFilter.GetIDs()
+
+    ## Verifies whether a 2D mesh element has free edges (edges connected to one face only)\n
+    #  Returns a list of special structures (borders).
+    #  @return a list of SMESH.FreeEdges.Border structure: edge id and ids of two its nodes.
+    #  @ingroup l1_controls
+    def GetFreeBorders(self):
+        aFilterMgr = self.smeshpyD.CreateFilterManager()
+        aPredicate = aFilterMgr.CreateFreeEdges()
+        aPredicate.SetMesh(self.mesh)
+        aBorders = aPredicate.GetBorders()
+        aFilterMgr.UnRegister()
+        return aBorders
+
 
     # Get mesh measurements information:
     # ------------------------------------
@@ -2274,8 +2438,8 @@ class Mesh:
     #  @return Id of the new node
     #  @ingroup l2_modif_add
     def AddNode(self, x, y, z):
-        x,y,z,Parameters = ParseParameters(x,y,z)
-        self.mesh.SetParameters(Parameters)
+        x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
+        if hasVars: self.mesh.SetParameters(Parameters)
         return self.editor.AddNode( x, y, z)
 
     ## Creates a 0D element on a node with given number.
@@ -2285,6 +2449,32 @@ class Mesh:
     def Add0DElement(self, IDOfNode):
         return self.editor.Add0DElement(IDOfNode)
 
+    ## Create 0D elements on all nodes of the given elements except those 
+    #  nodes on which a 0D element already exists.
+    #  @param theObject an object on whose nodes 0D elements will be created.
+    #         It can be mesh, sub-mesh, group, list of element IDs or a holder
+    #         of nodes IDs created by calling mesh.GetIDSource( nodes, SMESH.NODE )
+    #  @param theGroupName optional name of a group to add 0D elements created
+    #         and/or found on nodes of \a theObject.
+    #  @return an object (a new group or a temporary SMESH_IDSource) holding
+    #          IDs of new and/or found 0D elements. IDs of 0D elements 
+    #          can be retrieved from the returned object by calling GetIDs()
+    #  @ingroup l2_modif_add
+    def Add0DElementsToAllNodes(self, theObject, theGroupName=""):
+        if isinstance( theObject, Mesh ):
+            theObject = theObject.GetMesh()
+        if isinstance( theObject, list ):
+            theObject = self.GetIDSource( theObject, SMESH.ALL )
+        return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName )
+
+    ## Creates a ball element on a node with given ID.
+    #  @param IDOfNode the ID of node for creation of the element.
+    #  @param diameter the bal diameter.
+    #  @return the Id of the new ball element
+    #  @ingroup l2_modif_add
+    def AddBall(self, IDOfNode, diameter):
+        return self.editor.AddBall( IDOfNode, diameter )
+
     ## Creates a linear or quadratic edge (this is determined
     #  by the number of given nodes).
     #  @param IDsOfNodes the list of node IDs for creation of the element.
@@ -2438,8 +2628,8 @@ class Mesh:
     #  @return True if succeed else False
     #  @ingroup l2_modif_movenode
     def MoveNode(self, NodeID, x, y, z):
-        x,y,z,Parameters = ParseParameters(x,y,z)
-        self.mesh.SetParameters(Parameters)
+        x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
+        if hasVars: self.mesh.SetParameters(Parameters)
         return self.editor.MoveNode(NodeID, x, y, z)
 
     ## Finds the node closest to a point and moves it to a point location
@@ -2451,8 +2641,8 @@ class Mesh:
     #  @return the ID of a node
     #  @ingroup l2_modif_throughp
     def MoveClosestNodeToPoint(self, x, y, z, NodeID):
-        x,y,z,Parameters = ParseParameters(x,y,z)
-        self.mesh.SetParameters(Parameters)
+        x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
+        if hasVars: self.mesh.SetParameters(Parameters)
         return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
 
     ## Finds the node closest to a point
@@ -2471,7 +2661,7 @@ class Mesh:
     #  @param y  the Y coordinate of a point
     #  @param z  the Z coordinate of a point
     #  @param elementType type of elements to find (SMESH.ALL type
-    #         means elements of any type excluding nodes and 0D elements)
+    #         means elements of any type excluding nodes, discrete and 0D elements)
     #  @param meshPart a part of mesh (group, sub-mesh) to search within
     #  @return list of IDs of found elements
     #  @ingroup l2_modif_throughp
@@ -2481,7 +2671,8 @@ class Mesh:
         else:
             return self.editor.FindElementsByPoint(x, y, z, elementType)
 
-    # Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
+    # Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
+    # 0-IN, 1-OUT, 2-ON, 3-UNKNOWN
     # TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
 
     def GetPointState(self, x, y, z):
@@ -2532,62 +2723,105 @@ class Mesh:
             theObject = theObject.GetMesh()
         return self.editor.ReorientObject(theObject)
 
+    ## Reorient faces contained in \a the2DObject.
+    #  @param the2DObject is a mesh, sub-mesh, group or list of IDs of 2D elements
+    #  @param theDirection is a desired direction of normal of \a theFace.
+    #         It can be either a GEOM vector or a list of coordinates [x,y,z].
+    #  @param theFaceOrPoint defines a face of \a the2DObject whose normal will be
+    #         compared with theDirection. It can be either ID of face or a point
+    #         by which the face will be found. The point can be given as either
+    #         a GEOM vertex or a list of point coordinates.
+    #  @return number of reoriented faces
+    #  @ingroup l2_modif_changori
+    def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
+        # check the2DObject
+        if isinstance( the2DObject, Mesh ):
+            the2DObject = the2DObject.GetMesh()
+        if isinstance( the2DObject, list ):
+            the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
+        # check theDirection
+        if isinstance( theDirection, geompyDC.GEOM._objref_GEOM_Object):
+            theDirection = self.smeshpyD.GetDirStruct( theDirection )
+        if isinstance( theDirection, list ):
+            theDirection = self.smeshpyD.MakeDirStruct( *theDirection  )
+        # prepare theFace and thePoint
+        theFace = theFaceOrPoint
+        thePoint = PointStruct(0,0,0)
+        if isinstance( theFaceOrPoint, geompyDC.GEOM._objref_GEOM_Object):
+            thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
+            theFace = -1
+        if isinstance( theFaceOrPoint, list ):
+            thePoint = PointStruct( *theFaceOrPoint )
+            theFace = -1
+        if isinstance( theFaceOrPoint, PointStruct ):
+            thePoint = theFaceOrPoint
+            theFace = -1
+        return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
+
     ## Fuses the neighbouring triangles into quadrangles.
     #  @param IDsOfElements The triangles to be fused,
-    #  @param theCriterion  is FT_...; used to choose a neighbour to fuse with.
+    #  @param theCriterion  is a numerical functor, in terms of enum SMESH.FunctorType, used to
+    #                       choose a neighbour to fuse with.
     #  @param MaxAngle      is the maximum angle between element normals at which the fusion
     #                       is still performed; theMaxAngle is mesured in radians.
     #                       Also it could be a name of variable which defines angle in degrees.
     #  @return TRUE in case of success, FALSE otherwise.
     #  @ingroup l2_modif_unitetri
     def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
-        flag = False
-        if isinstance(MaxAngle,str):
-            flag = True
-        MaxAngle,Parameters = ParseAngles(MaxAngle)
+        MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
         self.mesh.SetParameters(Parameters)
         if not IDsOfElements:
             IDsOfElements = self.GetElementsId()
-        Functor = 0
-        if ( isinstance( theCriterion, SMESH._objref_NumericalFunctor ) ):
-            Functor = theCriterion
-        else:
-            Functor = self.smeshpyD.GetFunctor(theCriterion)
+        Functor = self.smeshpyD.GetFunctor(theCriterion)
         return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
 
     ## Fuses the neighbouring triangles of the object into quadrangles
     #  @param theObject is mesh, submesh or group
-    #  @param theCriterion is FT_...; used to choose a neighbour to fuse with.
+    #  @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to
+    #         choose a neighbour to fuse with.
     #  @param MaxAngle   a max angle between element normals at which the fusion
     #                   is still performed; theMaxAngle is mesured in radians.
     #  @return TRUE in case of success, FALSE otherwise.
     #  @ingroup l2_modif_unitetri
     def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
-        MaxAngle,Parameters = ParseAngles(MaxAngle)
+        MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
         self.mesh.SetParameters(Parameters)
-        if ( isinstance( theObject, Mesh )):
+        if isinstance( theObject, Mesh ):
             theObject = theObject.GetMesh()
-        return self.editor.TriToQuadObject(theObject, self.smeshpyD.GetFunctor(theCriterion), MaxAngle)
+        Functor = self.smeshpyD.GetFunctor(theCriterion)
+        return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
 
     ## Splits quadrangles into triangles.
+    #
     #  @param IDsOfElements the faces to be splitted.
-    #  @param theCriterion   FT_...; used to choose a diagonal for splitting.
+    #  @param theCriterion   is a numerical functor, in terms of enum SMESH.FunctorType, used to
+    #         choose a diagonal for splitting. If @a theCriterion is None, which is a default
+    #         value, then quadrangles will be split by the smallest diagonal.
     #  @return TRUE in case of success, FALSE otherwise.
     #  @ingroup l2_modif_cutquadr
-    def QuadToTri (self, IDsOfElements, theCriterion):
+    def QuadToTri (self, IDsOfElements, theCriterion = None):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
-        return self.editor.QuadToTri(IDsOfElements, self.smeshpyD.GetFunctor(theCriterion))
+        if theCriterion is None:
+            theCriterion = FT_MaxElementLength2D
+        Functor = self.smeshpyD.GetFunctor(theCriterion)
+        return self.editor.QuadToTri(IDsOfElements, Functor)
 
     ## Splits quadrangles into triangles.
-    #  @param theObject  the object from which the list of elements is taken, this is mesh, submesh or group
-    #  @param theCriterion   FT_...; used to choose a diagonal for splitting.
+    #  @param theObject the object from which the list of elements is taken,
+    #         this is mesh, submesh or group
+    #  @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to
+    #         choose a diagonal for splitting. If @a theCriterion is None, which is a default
+    #         value, then quadrangles will be split by the smallest diagonal.
     #  @return TRUE in case of success, FALSE otherwise.
     #  @ingroup l2_modif_cutquadr
-    def QuadToTriObject (self, theObject, theCriterion):
+    def QuadToTriObject (self, theObject, theCriterion = None):
         if ( isinstance( theObject, Mesh )):
             theObject = theObject.GetMesh()
-        return self.editor.QuadToTriObject(theObject, self.smeshpyD.GetFunctor(theCriterion))
+        if theCriterion is None:
+            theCriterion = FT_MaxElementLength2D
+        Functor = self.smeshpyD.GetFunctor(theCriterion)
+        return self.editor.QuadToTriObject(theObject, Functor)
 
     ## Splits quadrangles into triangles.
     #  @param IDsOfElements the faces to be splitted
@@ -2600,7 +2834,8 @@ class Mesh:
         return self.editor.SplitQuad(IDsOfElements, Diag13)
 
     ## Splits quadrangles into triangles.
-    #  @param theObject the object from which the list of elements is taken, this is mesh, submesh or group
+    #  @param theObject the object from which the list of elements is taken,
+    #         this is mesh, submesh or group
     #  @param Diag13    is used to choose a diagonal for splitting.
     #  @return TRUE in case of success, FALSE otherwise.
     #  @ingroup l2_modif_cutquadr
@@ -2611,7 +2846,8 @@ class Mesh:
 
     ## Finds a better splitting of the given quadrangle.
     #  @param IDOfQuad   the ID of the quadrangle to be splitted.
-    #  @param theCriterion  FT_...; a criterion to choose a diagonal for splitting.
+    #  @param theCriterion  is a numerical functor, in terms of enum SMESH.FunctorType, used 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.
     #  @ingroup l2_modif_cutquadr
@@ -2785,7 +3021,7 @@ class Mesh:
                MaxNbOfIterations, MaxAspectRatio, Method):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
-        MaxNbOfIterations,MaxAspectRatio,Parameters = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
+        MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
         self.mesh.SetParameters(Parameters)
         return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
                                   MaxNbOfIterations, MaxAspectRatio, Method)
@@ -2819,7 +3055,7 @@ class Mesh:
                          MaxNbOfIterations, MaxAspectRatio, Method):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
-        MaxNbOfIterations,MaxAspectRatio,Parameters = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
+        MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
         self.mesh.SetParameters(Parameters)
         return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
                                             MaxNbOfIterations, MaxAspectRatio, Method)
@@ -2840,19 +3076,23 @@ class Mesh:
         return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
                                                   MaxNbOfIterations, MaxAspectRatio, Method)
 
-    ## Converts the mesh to quadratic, deletes old elements, replacing
+    ## Converts the mesh to quadratic or bi-quadratic, deletes old elements, replacing
     #  them with quadratic with the same id.
     #  @param theForce3d new node creation method:
     #         0 - the medium node lies at the geometrical entity from which the mesh element is built
     #         1 - the medium node lies at the middle of the line segments connecting start and end node of a mesh element
     #  @param theSubMesh a group or a sub-mesh to convert; WARNING: in this case the mesh can become not conformal
+    #  @param theToBiQuad If True, converts the mesh to bi-quadratic
     #  @ingroup l2_modif_tofromqu
-    def ConvertToQuadratic(self, theForce3d, theSubMesh=None):
-        if theSubMesh:
-            self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
+    def ConvertToQuadratic(self, theForce3d, theSubMesh=None, theToBiQuad=False):
+        if theToBiQuad:
+            self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
         else:
-            self.editor.ConvertToQuadratic(theForce3d)
-
+            if theSubMesh:
+                self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
+            else:
+                self.editor.ConvertToQuadratic(theForce3d)
+            
     ## Converts the mesh from quadratic to ordinary,
     #  deletes old quadratic elements, \n replacing
     #  them with ordinary mesh elements with the same id.
@@ -2950,8 +3190,8 @@ class Mesh:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)):
             Axis = self.smeshpyD.GetAxisStruct(Axis)
-        AngleInRadians,AngleParameters = ParseAngles(AngleInRadians)
-        NbOfSteps,Tolerance,Parameters = ParseParameters(NbOfSteps,Tolerance)
+        AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
+        NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
         Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
         if TotalAngle and NbOfSteps:
@@ -2980,8 +3220,8 @@ class Mesh:
             theObject = theObject.GetMesh()
         if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)):
             Axis = self.smeshpyD.GetAxisStruct(Axis)
-        AngleInRadians,AngleParameters = ParseAngles(AngleInRadians)
-        NbOfSteps,Tolerance,Parameters = ParseParameters(NbOfSteps,Tolerance)
+        AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
+        NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
         Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
         if TotalAngle and NbOfSteps:
@@ -3010,8 +3250,8 @@ class Mesh:
             theObject = theObject.GetMesh()
         if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)):
             Axis = self.smeshpyD.GetAxisStruct(Axis)
-        AngleInRadians,AngleParameters = ParseAngles(AngleInRadians)
-        NbOfSteps,Tolerance,Parameters = ParseParameters(NbOfSteps,Tolerance)
+        AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
+        NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
         Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
         if TotalAngle and NbOfSteps:
@@ -3040,8 +3280,8 @@ class Mesh:
             theObject = theObject.GetMesh()
         if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)):
             Axis = self.smeshpyD.GetAxisStruct(Axis)
-        AngleInRadians,AngleParameters = ParseAngles(AngleInRadians)
-        NbOfSteps,Tolerance,Parameters = ParseParameters(NbOfSteps,Tolerance)
+        AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
+        NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
         Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
         if TotalAngle and NbOfSteps:
@@ -3054,7 +3294,9 @@ class Mesh:
 
     ## Generates new elements by extrusion of the elements with given ids
     #  @param IDsOfElements the list of elements ids for extrusion
-    #  @param StepVector vector or DirStruct, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||)
+    #  @param StepVector vector or DirStruct or 3 vector components, defining
+    #         the direction and value of extrusion for one step (the total extrusion
+    #         length will be NbOfSteps * ||StepVector||)
     #  @param NbOfSteps the number of steps
     #  @param MakeGroups forces the generation of new groups from existing ones
     #  @param IsNodes is True if elements with given ids are nodes
@@ -3063,9 +3305,11 @@ class Mesh:
     def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
-        if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)):
+        if isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object):
             StepVector = self.smeshpyD.GetDirStruct(StepVector)
-        NbOfSteps,Parameters = ParseParameters(NbOfSteps)
+        if isinstance( StepVector, list ):
+            StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
+        NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
         Parameters = StepVector.PS.parameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
         if MakeGroups:
@@ -3081,7 +3325,9 @@ class Mesh:
 
     ## Generates new elements by extrusion of the elements with given ids
     #  @param IDsOfElements is ids of elements
-    #  @param StepVector vector, defining the direction and value of extrusion
+    #  @param StepVector vector or DirStruct or 3 vector components, defining
+    #         the direction and value of extrusion for one step (the total extrusion
+    #         length will be NbOfSteps * ||StepVector||)
     #  @param NbOfSteps the number of steps
     #  @param ExtrFlags sets flags for extrusion
     #  @param SewTolerance uses for comparing locations of nodes if flag
@@ -3093,6 +3339,8 @@ class Mesh:
                           ExtrFlags, SewTolerance, MakeGroups=False):
         if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)):
             StepVector = self.smeshpyD.GetDirStruct(StepVector)
+        if isinstance( StepVector, list ):
+            StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
         if MakeGroups:
             return self.editor.AdvancedExtrusionMakeGroups(IDsOfElements, StepVector, NbOfSteps,
                                                            ExtrFlags, SewTolerance)
@@ -3103,7 +3351,9 @@ class Mesh:
     ## Generates new elements by extrusion of the elements which belong to the object
     #  @param theObject the object which elements should be processed.
     #                   It can be a mesh, a sub mesh or a group.
-    #  @param StepVector vector, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||)
+    #  @param StepVector vector or DirStruct or 3 vector components, defining
+    #         the direction and value of extrusion for one step (the total extrusion
+    #         length will be NbOfSteps * ||StepVector||)
     #  @param NbOfSteps the number of steps
     #  @param MakeGroups forces the generation of new groups from existing ones
     #  @param  IsNodes is True if elements which belong to the object are nodes
@@ -3114,7 +3364,9 @@ class Mesh:
             theObject = theObject.GetMesh()
         if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)):
             StepVector = self.smeshpyD.GetDirStruct(StepVector)
-        NbOfSteps,Parameters = ParseParameters(NbOfSteps)
+        if isinstance( StepVector, list ):
+            StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
+        NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
         Parameters = StepVector.PS.parameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
         if MakeGroups:
@@ -3131,7 +3383,9 @@ class Mesh:
     ## Generates new elements by extrusion of the elements which belong to the object
     #  @param theObject object which elements should be processed.
     #                   It can be a mesh, a sub mesh or a group.
-    #  @param StepVector vector, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||)
+    #  @param StepVector vector or DirStruct or 3 vector components, defining
+    #         the direction and value of extrusion for one step (the total extrusion
+    #         length will be NbOfSteps * ||StepVector||)
     #  @param NbOfSteps the number of steps
     #  @param MakeGroups to generate new groups from existing ones
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
@@ -3141,7 +3395,9 @@ class Mesh:
             theObject = theObject.GetMesh()
         if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)):
             StepVector = self.smeshpyD.GetDirStruct(StepVector)
-        NbOfSteps,Parameters = ParseParameters(NbOfSteps)
+        if isinstance( StepVector, list ):
+            StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
+        NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
         Parameters = StepVector.PS.parameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
         if MakeGroups:
@@ -3152,7 +3408,9 @@ class Mesh:
     ## Generates new elements by extrusion of the elements which belong to the object
     #  @param theObject object which elements should be processed.
     #                   It can be a mesh, a sub mesh or a group.
-    #  @param StepVector vector, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||)
+    #  @param StepVector vector or DirStruct or 3 vector components, defining
+    #         the direction and value of extrusion for one step (the total extrusion
+    #         length will be NbOfSteps * ||StepVector||)
     #  @param NbOfSteps the number of steps
     #  @param MakeGroups forces the generation of new groups from existing ones
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
@@ -3162,7 +3420,9 @@ class Mesh:
             theObject = theObject.GetMesh()
         if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)):
             StepVector = self.smeshpyD.GetDirStruct(StepVector)
-        NbOfSteps,Parameters = ParseParameters(NbOfSteps)
+        if isinstance( StepVector, list ):
+            StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
+        NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
         Parameters = StepVector.PS.parameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
         if MakeGroups:
@@ -3196,7 +3456,7 @@ class Mesh:
         if ( isinstance( RefPoint, geompyDC.GEOM._objref_GEOM_Object)):
             RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
             pass
-        Angles,AnglesParameters = ParseAngles(Angles)
+        Angles,AnglesParameters,hasVars = ParseAngles(Angles)
         Parameters = AnglesParameters + var_separator + RefPoint.parameters
         self.mesh.SetParameters(Parameters)
 
@@ -3247,7 +3507,7 @@ class Mesh:
             pass
         if ( isinstance( PathMesh, Mesh )):
             PathMesh = PathMesh.GetMesh()
-        Angles,AnglesParameters = ParseAngles(Angles)
+        Angles,AnglesParameters,hasVars = ParseAngles(Angles)
         Parameters = AnglesParameters + var_separator + RefPoint.parameters
         self.mesh.SetParameters(Parameters)
         if HasAngles and Angles and LinearVariation:
@@ -3288,7 +3548,7 @@ class Mesh:
             RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
         if ( isinstance( PathMesh, Mesh )):
             PathMesh = PathMesh.GetMesh()
-        Angles,AnglesParameters = ParseAngles(Angles)
+        Angles,AnglesParameters,hasVars = ParseAngles(Angles)
         Parameters = AnglesParameters + var_separator + RefPoint.parameters
         self.mesh.SetParameters(Parameters)
         if HasAngles and Angles and LinearVariation:
@@ -3330,7 +3590,7 @@ class Mesh:
             RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
         if ( isinstance( PathMesh, Mesh )):
             PathMesh = PathMesh.GetMesh()
-        Angles,AnglesParameters = ParseAngles(Angles)
+        Angles,AnglesParameters,hasVars = ParseAngles(Angles)
         Parameters = AnglesParameters + var_separator + RefPoint.parameters
         self.mesh.SetParameters(Parameters)
         if HasAngles and Angles and LinearVariation:
@@ -3372,7 +3632,7 @@ class Mesh:
             RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
         if ( isinstance( PathMesh, Mesh )):
             PathMesh = PathMesh.GetMesh()
-        Angles,AnglesParameters = ParseAngles(Angles)
+        Angles,AnglesParameters,hasVars = ParseAngles(Angles)
         Parameters = AnglesParameters + var_separator + RefPoint.parameters
         self.mesh.SetParameters(Parameters)
         if HasAngles and Angles and LinearVariation:
@@ -3420,7 +3680,7 @@ class Mesh:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( Mirror, geompyDC.GEOM._objref_GEOM_Object)):
             Mirror = self.smeshpyD.GetAxisStruct(Mirror)
-        mesh.SetParameters(Mirror.parameters)
+        self.mesh.SetParameters(Mirror.parameters)
         mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
                                           MakeGroups, NewMeshName)
         return Mesh(self.smeshpyD,self.geompyD,mesh)
@@ -3548,6 +3808,10 @@ class Mesh:
             theObject = theObject.GetMesh()
         if ( isinstance( theObject, list )):
             theObject = self.GetIDSource(theObject, SMESH.ALL)
+        if ( isinstance( theScaleFact, float )):
+             theScaleFact = [theScaleFact]
+        if ( isinstance( theScaleFact, int )):
+             theScaleFact = [ float(theScaleFact)]
 
         self.mesh.SetParameters(thePoint.parameters)
 
@@ -3568,6 +3832,10 @@ class Mesh:
             theObject = theObject.GetMesh()
         if ( isinstance( theObject, list )):
             theObject = self.GetIDSource(theObject,SMESH.ALL)
+        if ( isinstance( theScaleFact, float )):
+             theScaleFact = [theScaleFact]
+        if ( isinstance( theScaleFact, int )):
+             theScaleFact = [ float(theScaleFact)]
 
         self.mesh.SetParameters(thePoint.parameters)
         mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
@@ -3589,7 +3857,7 @@ class Mesh:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)):
             Axis = self.smeshpyD.GetAxisStruct(Axis)
-        AngleInRadians,Parameters = ParseAngles(AngleInRadians)
+        AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
         Parameters = Axis.parameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
         if Copy and MakeGroups:
@@ -3610,7 +3878,7 @@ class Mesh:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)):
             Axis = self.smeshpyD.GetAxisStruct(Axis)
-        AngleInRadians,Parameters = ParseAngles(AngleInRadians)
+        AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
         Parameters = Axis.parameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
         mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
@@ -3630,7 +3898,7 @@ class Mesh:
             theObject = theObject.GetMesh()
         if (isinstance(Axis, geompyDC.GEOM._objref_GEOM_Object)):
             Axis = self.smeshpyD.GetAxisStruct(Axis)
-        AngleInRadians,Parameters = ParseAngles(AngleInRadians)
+        AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
         Parameters = Axis.parameters + ":" + Parameters
         self.mesh.SetParameters(Parameters)
         if Copy and MakeGroups:
@@ -3651,7 +3919,7 @@ class Mesh:
             theObject = theObject.GetMesh()
         if (isinstance(Axis, geompyDC.GEOM._objref_GEOM_Object)):
             Axis = self.smeshpyD.GetAxisStruct(Axis)
-        AngleInRadians,Parameters = ParseAngles(AngleInRadians)
+        AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
         Parameters = Axis.parameters + ":" + Parameters
         mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
                                                        MakeGroups, NewMeshName)
@@ -3845,12 +4113,20 @@ class Mesh:
     #  @param theAffectedElems - group of elements to which the replicated nodes
     #         should be associated to.
     #  @param theMakeGroup forces the generation of a group containing new elements.
-    #  @return TRUE or a created group if operation has been completed successfully,
+    #  @param theMakeNodeGroup forces the generation of a group containing new nodes.
+    #  @return TRUE or created groups (one or two) if operation has been completed successfully,
     #          FALSE or None otherwise
     #  @ingroup l2_modif_edit
-    def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems, theMakeGroup=False):
-        if theMakeGroup:
-            return self.editor.DoubleNodeElemGroupNew(theElems, theNodesNot, theAffectedElems)
+    def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
+                             theMakeGroup=False, theMakeNodeGroup=False):
+        if theMakeGroup or theMakeNodeGroup:
+            twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
+                                                            theAffectedElems,
+                                                            theMakeGroup, theMakeNodeGroup)
+            if theMakeGroup and theMakeNodeGroup:
+                return twoGroups
+            else:
+                return twoGroups[ int(theMakeNodeGroup) ]
         return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
 
     ## Creates a hole in a mesh by doubling the nodes of some particular elements
@@ -3871,12 +4147,20 @@ class Mesh:
     #  @param theAffectedElems - group of elements to which the replicated nodes
     #         should be associated to.
     #  @param theMakeGroup forces the generation of a group containing new elements.
-    #  @return TRUE or a created group if operation has been completed successfully,
+    #  @param theMakeNodeGroup forces the generation of a group containing new nodes.
+    #  @return TRUE or created groups (one or two) if operation has been completed successfully,
     #          FALSE or None otherwise
     #  @ingroup l2_modif_edit
-    def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems, theMakeGroup=False):
-        if theMakeGroup:
-            return self.editor.DoubleNodeElemGroupsNew(theElems, theNodesNot, theAffectedElems)
+    def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
+                             theMakeGroup=False, theMakeNodeGroup=False):
+        if theMakeGroup or theMakeNodeGroup:
+            twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
+                                                             theAffectedElems,
+                                                             theMakeGroup, theMakeNodeGroup)
+            if theMakeGroup and theMakeNodeGroup:
+                return twoGroups
+            else:
+                return twoGroups[ int(theMakeNodeGroup) ]
         return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
 
     ## Creates a hole in a mesh by doubling the nodes of some particular elements
@@ -3891,6 +4175,18 @@ class Mesh:
     def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
         return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
 
+    ## Identify the elements that will be affected by node duplication (actual duplication is not performed.
+    #  This method is the first step of DoubleNodeElemGroupsInRegion.
+    #  @param theElems - list of groups of elements (edges or faces) to be replicated
+    #  @param theNodesNot - list of groups of nodes not to replicated
+    #  @param theShape - shape to detect affected elements (element which geometric center
+    #         located on or inside shape).
+    #         The replicated nodes should be associated to affected elements.
+    #  @return groups of affected elements
+    #  @ingroup l2_modif_edit
+    def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
+        return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
+
     ## Double nodes on shared faces between groups of volumes and create flat elements on demand.
     # The list of groups must describe a partition of the mesh volumes.
     # The nodes of the internal faces at the boundaries of the groups are doubled.
@@ -3911,10 +4207,22 @@ class Mesh:
     # @return TRUE if operation has been completed successfully, FALSE otherwise
     def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
         return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
+    
+    ## identify all the elements around a geom shape, get the faces delimiting the hole
+    #
+    def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
+        return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
+
+    def _getFunctor(self, funcType ):
+        fn = self.functors[ funcType._v ]
+        if not fn:
+            fn = self.smeshpyD.GetFunctor(funcType)
+            fn.SetMesh(self.mesh)
+            self.functors[ funcType._v ] = fn
+        return fn
 
     def _valueFromFunctor(self, funcType, elemId):
-        fn = self.smeshpyD.GetFunctor(funcType)
-        fn.SetMesh(self.mesh)
+        fn = self._getFunctor( funcType )
         if fn.GetElementType() == self.GetElementType(elemId, True):
             val = fn.GetValue(elemId)
         else:
@@ -3992,308 +4300,27 @@ class Mesh:
     def GetSkew(self, elemId):
         return self._valueFromFunctor(SMESH.FT_Skew, elemId)
 
-## The mother class to define algorithm, it is not recommended to use it directly.
+    pass # end of Mesh class
+    
+## Helper class for wrapping of SMESH.SMESH_Pattern CORBA class
 #
-#  For each meshing algorithm, a python class inheriting from class Mesh_Algorithm
-#  should be defined. This descendant class sould have two attributes defining the way
-# it is created by class Mesh (see e.g. class StdMeshersDC_Segment in StdMeshersDC.py).
-# - meshMethod attribute defines name of method of class Mesh by calling which the
-#   python class of algorithm is created. E.g. if in class MyPlugin_Algorithm
-#   meshMethod = "MyAlgorithm", then an instance of MyPlugin_Algorithm is created
-#   by the following code: my_algo = mesh.MyAlgorithm()
-# - algoType defines name of algorithm type and is used mostly to discriminate
-#   algorithms that are created by the same method of class Mesh. E.g. if
-#   MyPlugin_Algorithm.algoType = "MyPLUGIN" then it's creation code can be:
-#   my_algo = mesh.MyAlgorithm(algo="MyPLUGIN")
-#  @ingroup l2_algorithms
-class Mesh_Algorithm:
-    #  @class Mesh_Algorithm
-    #  @brief Class Mesh_Algorithm
-
-    #def __init__(self,smesh):
-    #    self.smesh=smesh
-    def __init__(self):
-        self.mesh = None
-        self.geom = None
-        self.subm = None
-        self.algo = None
-
-    ## Finds a hypothesis in the study by its type name and parameters.
-    #  Finds only the hypotheses created in smeshpyD engine.
-    #  @return SMESH.SMESH_Hypothesis
-    def FindHypothesis (self, hypname, args, CompareMethod, smeshpyD):
-        study = smeshpyD.GetCurrentStudy()
-        #to do: find component by smeshpyD object, not by its data type
-        scomp = study.FindComponent(smeshpyD.ComponentDataType())
-        if scomp is not None:
-            res,hypRoot = scomp.FindSubObject(SMESH.Tag_HypothesisRoot)
-            # Check if the root label of the hypotheses exists
-            if res and hypRoot is not None:
-                iter = study.NewChildIterator(hypRoot)
-                # Check all published hypotheses
-                while iter.More():
-                    hypo_so_i = iter.Value()
-                    attr = hypo_so_i.FindAttribute("AttributeIOR")[1]
-                    if attr is not None:
-                        anIOR = attr.Value()
-                        hypo_o_i = salome.orb.string_to_object(anIOR)
-                        if hypo_o_i is not None:
-                            # Check if this is a hypothesis
-                            hypo_i = hypo_o_i._narrow(SMESH.SMESH_Hypothesis)
-                            if hypo_i is not None:
-                                # Check if the hypothesis belongs to current engine
-                                if smeshpyD.GetObjectId(hypo_i) > 0:
-                                    # Check if this is the required hypothesis
-                                    if hypo_i.GetName() == hypname:
-                                        # Check arguments
-                                        if CompareMethod(hypo_i, args):
-                                            # found!!!
-                                            return hypo_i
-                                        pass
-                                    pass
-                                pass
-                            pass
-                        pass
-                    iter.Next()
-                    pass
-                pass
-            pass
-        return None
-
-    ## Finds the algorithm in the study by its type name.
-    #  Finds only the algorithms, which have been created in smeshpyD engine.
-    #  @return SMESH.SMESH_Algo
-    def FindAlgorithm (self, algoname, smeshpyD):
-        study = smeshpyD.GetCurrentStudy()
-        #to do: find component by smeshpyD object, not by its data type
-        scomp = study.FindComponent(smeshpyD.ComponentDataType())
-        if scomp is not None:
-            res,hypRoot = scomp.FindSubObject(SMESH.Tag_AlgorithmsRoot)
-            # Check if the root label of the algorithms exists
-            if res and hypRoot is not None:
-                iter = study.NewChildIterator(hypRoot)
-                # Check all published algorithms
-                while iter.More():
-                    algo_so_i = iter.Value()
-                    attr = algo_so_i.FindAttribute("AttributeIOR")[1]
-                    if attr is not None:
-                        anIOR = attr.Value()
-                        algo_o_i = salome.orb.string_to_object(anIOR)
-                        if algo_o_i is not None:
-                            # Check if this is an algorithm
-                            algo_i = algo_o_i._narrow(SMESH.SMESH_Algo)
-                            if algo_i is not None:
-                                # Checks if the algorithm belongs to the current engine
-                                if smeshpyD.GetObjectId(algo_i) > 0:
-                                    # Check if this is the required algorithm
-                                    if algo_i.GetName() == algoname:
-                                        # found!!!
-                                        return algo_i
-                                    pass
-                                pass
-                            pass
-                        pass
-                    iter.Next()
-                    pass
-                pass
-            pass
-        return None
-
-    ## If the algorithm is global, returns 0; \n
-    #  else returns the submesh associated to this algorithm.
-    def GetSubMesh(self):
-        return self.subm
-
-    ## Returns the wrapped mesher.
-    def GetAlgorithm(self):
-        return self.algo
-
-    ## Gets the list of hypothesis that can be used with this algorithm
-    def GetCompatibleHypothesis(self):
-        mylist = []
-        if self.algo:
-            mylist = self.algo.GetCompatibleHypothesis()
-        return mylist
-
-    ## Gets the name of the algorithm
-    def GetName(self):
-        GetName(self.algo)
-
-    ## Sets the name to the algorithm
-    def SetName(self, name):
-        self.mesh.smeshpyD.SetName(self.algo, name)
-
-    ## Gets the id of the algorithm
-    def GetId(self):
-        return self.algo.GetId()
-
-    ## 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 = self.FindAlgorithm(hypo, mesh.smeshpyD)
-        if algo is None:
-            algo = mesh.smeshpyD.CreateHypothesis(hypo, so)
-            pass
-        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 " + algo + " algoritm on None shape"
-        self.mesh = mesh
-        name = ""
-        if not geom:
-            self.geom = mesh.geom
-        else:
-            self.geom = geom
-            AssureGeomPublished( mesh, geom )
-            try:
-                name = GetName(geom)
-                pass
-            except:
-                pass
-            self.subm = mesh.mesh.GetSubMesh(geom, algo.GetName())
-        self.algo = algo
-        status = mesh.mesh.AddHypothesis(self.geom, self.algo)
-        TreatHypoStatus( status, algo.GetName(), name, True )
-        return
-
-    def CompareHyp (self, hyp, args):
-        print "CompareHyp is not implemented for ", self.__class__.__name__, ":", hyp.GetName()
-        return False
-
-    def CompareEqualHyp (self, hyp, args):
-        return True
-
-    ## Private method
-    def Hypothesis (self, hyp, args=[], so="libStdMeshersEngine.so",
-                    UseExisting=0, CompareMethod=""):
-        hypo = None
-        if UseExisting:
-            if CompareMethod == "": CompareMethod = self.CompareHyp
-            hypo = self.FindHypothesis(hyp, args, CompareMethod, self.mesh.smeshpyD)
-            pass
-        if hypo is None:
-            hypo = self.mesh.smeshpyD.CreateHypothesis(hyp, so)
-            a = ""
-            s = "="
-            for arg in args:
-                argStr = str(arg)
-                if isinstance( arg, geompyDC.GEOM._objref_GEOM_Object ):
-                    argStr = arg.GetStudyEntry()
-                    if not argStr: argStr = "GEOM_Obj_%s", arg.GetEntry()
-                if len( argStr ) > 10:
-                    argStr = argStr[:7]+"..."
-                    if argStr[0] == '[': argStr += ']'
-                a = a + s + argStr
-                s = ","
-                pass
-            if len(a) > 50:
-                a = a[:47]+"..."
-            self.mesh.smeshpyD.SetName(hypo, hyp + a)
-            pass
-        geomName=""
-        if self.geom:
-            geomName = GetName(self.geom)
-        status = self.mesh.mesh.AddHypothesis(self.geom, hypo)
-        TreatHypoStatus( status, GetName(hypo), geomName, 0 )
-        return hypo
-
-    ## Returns entry of the shape to mesh in the study
-    def MainShapeEntry(self):
-        entry = ""
-        if not self.mesh or not self.mesh.GetMesh(): return entry
-        if not self.mesh.GetMesh().HasShapeToMesh(): return entry
-        study = self.mesh.smeshpyD.GetCurrentStudy()
-        ior  = salome.orb.object_to_string( self.mesh.GetShape() )
-        sobj = study.FindObjectIOR(ior)
-        if sobj: entry = sobj.GetID()
-        if not entry: return ""
-        return entry
-
-    ## Defines "ViscousLayers" hypothesis to give parameters of layers of prisms to build
-    #  near mesh boundary. This hypothesis can be used by several 3D algorithms:
-    #  NETGEN 3D, GHS3D, Hexahedron(i,j,k)
-    #  @param thickness total thickness of layers of prisms
-    #  @param numberOfLayers number of layers of prisms
-    #  @param stretchFactor factor (>1.0) of growth of layer thickness towards inside of mesh
-    #  @param ignoreFaces list of geometrical faces (or their ids) not to generate layers on
-    #  @ingroup l3_hypos_additi
-    def ViscousLayers(self, thickness, numberOfLayers, stretchFactor, ignoreFaces=[]):
-        if not isinstance(self.algo, SMESH._objref_SMESH_3D_Algo):
-            raise TypeError, "ViscousLayers are supported by 3D algorithms only"
-        if not "ViscousLayers" in self.GetCompatibleHypothesis():
-            raise TypeError, "ViscousLayers are not supported by %s"%self.algo.GetName()
-        if ignoreFaces and isinstance( ignoreFaces[0], geompyDC.GEOM._objref_GEOM_Object ):
-            ignoreFaces = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f) for f in ignoreFaces ]
-        hyp = self.Hypothesis("ViscousLayers",
-                              [thickness, numberOfLayers, stretchFactor, ignoreFaces])
-        hyp.SetTotalThickness(thickness)
-        hyp.SetNumberLayers(numberOfLayers)
-        hyp.SetStretchFactor(stretchFactor)
-        hyp.SetIgnoreFaces(ignoreFaces)
-        return hyp
-
-    ## Transform a list of ether edges or tuples (edge 1st_vertex_of_edge)
-    #  into a list acceptable to SetReversedEdges() of some 1D hypotheses
-    #  @ingroup l3_hypos_1dhyps
-    def ReversedEdgeIndices(self, reverseList):
-        resList = []
-        geompy = self.mesh.geompyD
-        for i in reverseList:
-            if isinstance( i, int ):
-                s = geompy.SubShapes(self.mesh.geom, [i])[0]
-                if s.GetShapeType() != geompyDC.GEOM.EDGE:
-                    raise TypeError, "Not EDGE index given"
-                resList.append( i )
-            elif isinstance( i, geompyDC.GEOM._objref_GEOM_Object ):
-                if i.GetShapeType() != geompyDC.GEOM.EDGE:
-                    raise TypeError, "Not an EDGE given"
-                resList.append( geompy.GetSubShapeID(self.mesh.geom, i ))
-            elif len( i ) > 1:
-                e = i[0]
-                v = i[1]
-                if not isinstance( e, geompyDC.GEOM._objref_GEOM_Object ) or \
-                   not isinstance( v, geompyDC.GEOM._objref_GEOM_Object ):
-                    raise TypeError, "A list item must be a tuple (edge 1st_vertex_of_edge)"
-                if v.GetShapeType() == geompyDC.GEOM.EDGE and \
-                   e.GetShapeType() == geompyDC.GEOM.VERTEX:
-                    v,e = e,v
-                if e.GetShapeType() != geompyDC.GEOM.EDGE or \
-                   v.GetShapeType() != geompyDC.GEOM.VERTEX:
-                    raise TypeError, "A list item must be a tuple (edge 1st_vertex_of_edge)"
-                vFirst = FirstVertexOnCurve( e )
-                tol    = geompy.Tolerance( vFirst )[-1]
-                if geompy.MinDistance( v, vFirst ) > 1.5*tol:
-                    resList.append( geompy.GetSubShapeID(self.mesh.geom, e ))
-            else:
-                raise TypeError, "Item must be either an edge or tuple (edge 1st_vertex_of_edge)"
-        return resList
-
-
 class Pattern(SMESH._objref_SMESH_Pattern):
 
     def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
         decrFun = lambda i: i-1
-        theNodeIndexOnKeyPoint1,Parameters = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
+        theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
         theMesh.SetParameters(Parameters)
         return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
 
     def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
         decrFun = lambda i: i-1
-        theNode000Index,theNode001Index,Parameters = ParseParameters(theNode000Index,theNode001Index, decrFun)
+        theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
         theMesh.SetParameters(Parameters)
         return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
 
-#Registering the new proxy for Pattern
+# Registering the new proxy for Pattern
 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
 
-
-
-
-
 ## Private class used to bind methods creating algorithms to the class Mesh
 #
 class algoCreator:
@@ -4323,7 +4350,7 @@ class algoCreator:
     # creates an instance of algorithm
     def __call__(self,algo="",geom=0,*args):
         algoType = self.defaultAlgoType
-        for arg in args + (algo,):
+        for arg in args + (algo,geom):
             if isinstance( arg, geompyDC.GEOM._objref_GEOM_Object ):
                 geom = arg
             if isinstance( arg, str ) and arg:
@@ -4333,10 +4360,11 @@ class algoCreator:
         if self.algoTypeToClass.has_key( algoType ):
             #print "Create algo",algoType
             return self.algoTypeToClass[ algoType ]( self.mesh, geom )
-        raise RuntimeError, "No class found for algo type" % algoType
+        raise RuntimeError, "No class found for algo type %s" % algoType
         return None
 
 # Private class used to substitute and store variable parameters of hypotheses.
+#
 class hypMethodWrapper:
     def __init__(self, hyp, method):
         self.hyp    = hyp
@@ -4352,8 +4380,8 @@ class hypMethodWrapper:
         #print "MethWrapper.__call__",self.method.__name__, args
         try:
             parsed = ParseParameters(*args)     # replace variables with their values
-            self.hyp.SetVarParameter( parsed[-1], self.method.__name__ )
-            result = self.method( self.hyp, *parsed[:-1] ) # call hypothesis method
+            self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
+            result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
         except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
             # maybe there is a replaced string arg which is not variable
             result = self.method( self.hyp, *args )
@@ -4364,3 +4392,32 @@ class hypMethodWrapper:
                 raise ValueError, detail # wrong variable name
 
         return result
+
+for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
+    #
+    print "pluginName: ", pluginName
+    pluginName += "DC"
+    try:
+        exec( "from %s import *" % pluginName )
+    except Exception, e:
+        print "Exception while loading %s: %s" % ( pluginName, e )
+        continue
+    exec( "import %s" % pluginName )
+    plugin = eval( pluginName )
+    print "  plugin:" , str(plugin)
+
+    # add methods creating algorithms to Mesh
+    for k in dir( plugin ):
+        if k[0] == '_': continue
+        algo = getattr( plugin, k )
+        print "             algo:", str(algo)
+        if type( algo ).__name__ == 'classobj' and hasattr( algo, "meshMethod" ):
+            print "                     meshMethod:" , str(algo.meshMethod)
+            if not hasattr( Mesh, algo.meshMethod ):
+                setattr( Mesh, algo.meshMethod, algoCreator() )
+                pass
+            getattr( Mesh, algo.meshMethod ).add( algo )
+            pass
+        pass
+    pass
+del pluginName