Salome HOME
Merge Python 3 porting.
[modules/smesh.git] / src / SMESH_SWIG / smeshBuilder.py
index 775faa89aa85275c92fae2d2c5f9670e8414c8be..6da2aaf29ba637d254f751255cb7afb9f1fd2a2c 100644 (file)
@@ -92,6 +92,80 @@ import SALOMEDS
 import os
 import inspect
 
+# In case the omniORBpy EnumItem class does not fully support Python 3
+# (for instance in version 4.2.1-2), the comparison ordering methods must be
+# defined
+#
+try:
+    SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
+except TypeError:
+    def enumitem_eq(self, other):
+        try:
+            if isinstance(other, omniORB.EnumItem):
+                if other._parent_id == self._parent_id:
+                    return self._v == other._v
+                else:
+                    return self._parent_id == other._parent_id
+            else:
+                return id(self) == id(other)
+        except:
+            return id(self) == id(other)
+
+    def enumitem_lt(self, other):
+        try:
+            if isinstance(other, omniORB.EnumItem):
+                if other._parent_id == self._parent_id:
+                    return self._v < other._v
+                else:
+                    return self._parent_id < other._parent_id
+            else:
+                return id(self) < id(other)
+        except:
+            return id(self) < id(other)
+
+    def enumitem_le(self, other):
+        try:
+            if isinstance(other, omniORB.EnumItem):
+                if other._parent_id == self._parent_id:
+                    return self._v <= other._v
+                else:
+                    return self._parent_id <= other._parent_id
+            else:
+                return id(self) <= id(other)
+        except:
+            return id(self) <= id(other)
+
+    def enumitem_gt(self, other):
+        try:
+            if isinstance(other, omniORB.EnumItem):
+                if other._parent_id == self._parent_id:
+                    return self._v > other._v
+                else:
+                    return self._parent_id > other._parent_id
+            else:
+                return id(self) > id(other)
+        except:
+            return id(self) > id(other)
+
+    def enumitem_ge(self, other):
+        try:
+            if isinstance(other, omniORB.EnumItem):
+                if other._parent_id == self._parent_id:
+                    return self._v >= other._v
+                else:
+                    return self._parent_id >= other._parent_id
+            else:
+                return id(self) >= id(other)
+        except:
+            return id(self) >= id(other)
+
+    omniORB.EnumItem.__eq__ = enumitem_eq
+    omniORB.EnumItem.__lt__ = enumitem_lt
+    omniORB.EnumItem.__le__ = enumitem_le
+    omniORB.EnumItem.__gt__ = enumitem_gt
+    omniORB.EnumItem.__ge__ = enumitem_ge
+
+
 ## Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
 #
 class MeshMeta(type):
@@ -189,13 +263,8 @@ def GetName(obj):
         except:
             ior = None
         if ior:
-            # CORBA object
-            studies = salome.myStudyManager.GetOpenStudies()
-            for sname in studies:
-                s = salome.myStudyManager.GetStudyByName(sname)
-                if not s: continue
-                sobj = s.FindObjectIOR(ior)
-                if not sobj: continue
+            sobj = salome.myStudy.FindObjectIOR(ior)
+            if sobj:
                 return sobj.GetName()
             if hasattr(obj, "GetName"):
                 # unknown CORBA object, having GetName() method
@@ -219,21 +288,21 @@ def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
         pass
     reason = ""
     if hasattr( status, "__getitem__" ):
-        status,reason = status[0],status[1]
-    if status == HYP_UNKNOWN_FATAL :
+        status, reason = status[0], status[1]
+    if status == HYP_UNKNOWN_FATAL:
         reason = "for unknown reason"
-    elif status == HYP_INCOMPATIBLE :
+    elif status == HYP_INCOMPATIBLE:
         reason = "this hypothesis mismatches the algorithm"
-    elif status == HYP_NOTCONFORM :
+    elif status == HYP_NOTCONFORM:
         reason = "a non-conform mesh would be built"
-    elif status == HYP_ALREADY_EXIST :
+    elif status == HYP_ALREADY_EXIST:
         if isAlgo: return # it does not influence anything
         reason = hypType + " of the same dimension is already assigned to this shape"
-    elif status == HYP_BAD_DIM :
+    elif status == HYP_BAD_DIM:
         reason = hypType + " mismatches the shape"
-    elif status == HYP_CONCURENT :
+    elif status == HYP_CONCURENT:
         reason = "there are concurrent hypotheses on sub-shapes"
-    elif status == HYP_BAD_SUBSHAPE :
+    elif status == HYP_BAD_SUBSHAPE:
         reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
     elif status == HYP_BAD_GEOMETRY:
         reason = "the algorithm is not applicable to this geometry"
@@ -266,12 +335,7 @@ def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
 def AssureGeomPublished(mesh, geom, name=''):
     if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
         return
-    if not geom.GetStudyEntry() and \
-           mesh.smeshpyD.GetCurrentStudy():
-        ## set the study
-        studyID = mesh.smeshpyD.GetCurrentStudy()._get_StudyId()
-        if studyID != mesh.geompyD.myStudyId:
-            mesh.geompyD.init_geom( mesh.smeshpyD.GetCurrentStudy())
+    if not geom.GetStudyEntry():
         ## get a name
         if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
             # for all groups SubShapeName() return "Compound_-1"
@@ -301,6 +365,10 @@ def FirstVertexOnCurve(mesh, edge):
     else:
         return vv[1]
 
+## Return a long value from enumeration
+def EnumToLong(theItem):
+    return theItem._v
+
 # end of l1_auxiliary
 ## @}
 
@@ -380,8 +448,8 @@ class smeshBuilder(SMESH._objref_SMESH_Gen):
     ## Dump component to the Python script
     #  This method overrides IDL function to allow default values for the parameters.
     #  @ingroup l1_auxiliary
-    def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
-        return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
+    def DumpPython(self, theIsPublished=True, theIsMultiFile=True):
+        return SMESH._objref_SMESH_Gen.DumpPython(self, theIsPublished, theIsMultiFile)
 
     ## Set mode of DumpPython(), \a historical or \a snapshot.
     #  In the \a historical mode, the Python Dump script includes all commands
@@ -394,14 +462,14 @@ class smeshBuilder(SMESH._objref_SMESH_Gen):
         else:            val = "false"
         SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
 
-    ## Set the current study and Geometry component
+    ## Set Geometry component
     #  @ingroup l1_auxiliary
-    def init_smesh(self,theStudy,geompyD = None):
+    def init_smesh(self,isPublished = True,geompyD = None):
         #print "init_smesh"
-        self.SetCurrentStudy(theStudy,geompyD)
-        if theStudy:
+        self.UpdateStudy(geompyD)
+        if isPublished:
             global notebook
-            notebook.myStudy = theStudy
+            notebook.myStudy = salome.myStudy
 
     ## Create a mesh. This can be either an empty mesh, possibly having an underlying geometry,
     #  or a mesh wrapping a CORBA mesh given as a parameter.
@@ -417,11 +485,6 @@ class smeshBuilder(SMESH._objref_SMESH_Gen):
             obj,name = name,obj
         return Mesh(self,self.geompyD,obj,name)
 
-    ## Return a long value from enumeration
-    #  @ingroup l1_auxiliary
-    def EnumToLong(self,theItem):
-        return theItem._v
-
     ## Return a string representation of the color.
     #  To be used with filters.
     #  @param c color value (SALOMEDS.Color)
@@ -523,34 +586,32 @@ class smeshBuilder(SMESH._objref_SMESH_Gen):
     #  @ingroup l1_auxiliary
     def IsEmbeddedMode(self):
         return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
-
-    ## Set the current study. Calling SetCurrentStudy( None ) allows to
-    #  switch OFF automatic pubilishing in the Study of mesh objects.
+    
+    ## Update the current study. Calling UpdateStudy() allows to 
+    #  update meshes at switching GEOM->SMESH
     #  @ingroup l1_auxiliary
-    def SetCurrentStudy( self, theStudy, geompyD = None ):
+    def UpdateStudy( self, geompyD = None  ):
+        #self.UpdateStudy()
         if not geompyD:
             from salome.geom import geomBuilder
             geompyD = geomBuilder.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() )
-        if theStudy:
-            sb = theStudy.NewBuilder()
-            sc = theStudy.FindComponent("SMESH")
-            if sc: sb.LoadWith(sc, self)
-            pass
+        SMESH._objref_SMESH_Gen.UpdateStudy(self)
+        sb = salome.myStudy.NewBuilder()
+        sc = salome.myStudy.FindComponent("SMESH")
+        if sc: sb.LoadWith(sc, self)
         pass
-
-    ## Get the current study
+        
+    ## Sets enable publishing in the study. Calling SetEnablePublish( false ) allows to
+    #  switch OFF publishing in the Study of mesh objects.
     #  @ingroup l1_auxiliary
-    def GetCurrentStudy(self):
-        return SMESH._objref_SMESH_Gen.GetCurrentStudy(self)
+    def SetEnablePublish( self, theIsEnablePublish ):
+        #self.SetEnablePublish(theIsEnablePublish)
+        SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
+        global notebook
+        notebook = salome_notebook.NoteBook( theIsEnablePublish )
 
     ## Create a Mesh object importing data from the given UNV file
     #  @return an instance of Mesh class
@@ -675,13 +736,13 @@ class smeshBuilder(SMESH._objref_SMESH_Gen):
     #  @return SMESH.Filter.Criterion
     #  @ingroup l1_controls
     def GetEmptyCriterion(self):
-        Type = self.EnumToLong(FT_Undefined)
-        Compare = self.EnumToLong(FT_Undefined)
+        Type = EnumToLong(FT_Undefined)
+        Compare = EnumToLong(FT_Undefined)
         Threshold = 0
         ThresholdStr = ""
         ThresholdID = ""
-        UnaryOp = self.EnumToLong(FT_Undefined)
-        BinaryOp = self.EnumToLong(FT_Undefined)
+        UnaryOp = EnumToLong(FT_Undefined)
+        BinaryOp = EnumToLong(FT_Undefined)
         Tolerance = 1e-07
         TypeOfElement = ALL
         Precision = -1 ##@1e-07
@@ -716,21 +777,21 @@ class smeshBuilder(SMESH._objref_SMESH_Gen):
             raise TypeError("CritType should be of SMESH.FunctorType")
         aCriterion               = self.GetEmptyCriterion()
         aCriterion.TypeOfElement = elementType
-        aCriterion.Type          = self.EnumToLong(CritType)
+        aCriterion.Type          = EnumToLong(CritType)
         aCriterion.Tolerance     = Tolerance
 
         aThreshold = Threshold
 
         if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
-            aCriterion.Compare = self.EnumToLong(Compare)
+            aCriterion.Compare = EnumToLong(Compare)
         elif Compare == "=" or Compare == "==":
-            aCriterion.Compare = self.EnumToLong(FT_EqualTo)
+            aCriterion.Compare = EnumToLong(FT_EqualTo)
         elif Compare == "<":
-            aCriterion.Compare = self.EnumToLong(FT_LessThan)
+            aCriterion.Compare = EnumToLong(FT_LessThan)
         elif Compare == ">":
-            aCriterion.Compare = self.EnumToLong(FT_MoreThan)
+            aCriterion.Compare = EnumToLong(FT_MoreThan)
         elif Compare != FT_Undefined:
-            aCriterion.Compare = self.EnumToLong(FT_EqualTo)
+            aCriterion.Compare = EnumToLong(FT_EqualTo)
             aThreshold = Compare
 
         if CritType in [FT_BelongToGeom,     FT_BelongToPlane, FT_BelongToGenSurface,
@@ -760,7 +821,7 @@ class smeshBuilder(SMESH._objref_SMESH_Gen):
                     raise ValueError("Group type mismatches Element type")
                 aCriterion.ThresholdStr = aThreshold.GetName()
                 aCriterion.ThresholdID  = salome.orb.object_to_string( aThreshold )
-                study = self.GetCurrentStudy()
+                study = salome.myStudy
                 if study:
                     so = study.FindObjectIOR( aCriterion.ThresholdID )
                     if so:
@@ -812,7 +873,7 @@ class smeshBuilder(SMESH._objref_SMESH_Gen):
         elif CritType == FT_ElemGeomType:
             # Check the Threshold
             try:
-                aCriterion.Threshold = self.EnumToLong(aThreshold)
+                aCriterion.Threshold = EnumToLong(aThreshold)
                 assert( aThreshold in SMESH.GeometryType._items )
             except:
                 if isinstance(aThreshold, int):
@@ -824,7 +885,7 @@ class smeshBuilder(SMESH._objref_SMESH_Gen):
         elif CritType == FT_EntityType:
             # Check the Threshold
             try:
-                aCriterion.Threshold = self.EnumToLong(aThreshold)
+                aCriterion.Threshold = EnumToLong(aThreshold)
                 assert( aThreshold in SMESH.EntityType._items )
             except:
                 if isinstance(aThreshold, int):
@@ -848,7 +909,7 @@ class smeshBuilder(SMESH._objref_SMESH_Gen):
                           FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
             # At this point the Threshold is unnecessary
             if aThreshold ==  FT_LogicalNOT:
-                aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
+                aCriterion.UnaryOp = EnumToLong(FT_LogicalNOT)
             elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
                 aCriterion.BinaryOp = aThreshold
         else:
@@ -861,16 +922,16 @@ class smeshBuilder(SMESH._objref_SMESH_Gen):
                 return None
 
         if Threshold ==  FT_LogicalNOT or UnaryOp ==  FT_LogicalNOT:
-            aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
+            aCriterion.UnaryOp = EnumToLong(FT_LogicalNOT)
 
         if Threshold in [FT_LogicalAND, FT_LogicalOR]:
-            aCriterion.BinaryOp = self.EnumToLong(Threshold)
+            aCriterion.BinaryOp = EnumToLong(Threshold)
 
         if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
-            aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
+            aCriterion.BinaryOp = EnumToLong(UnaryOp)
 
         if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
-            aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
+            aCriterion.BinaryOp = EnumToLong(BinaryOp)
 
         return aCriterion
 
@@ -917,8 +978,8 @@ class smeshBuilder(SMESH._objref_SMESH_Gen):
     #  @ingroup l1_controls
     def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
         for i in range( len( criteria ) - 1 ):
-            if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
-                criteria[i].BinaryOp = self.EnumToLong( binOp )
+            if criteria[i].BinaryOp == EnumToLong( SMESH.FT_Undefined ):
+                criteria[i].BinaryOp = EnumToLong( binOp )
         aFilterMgr = self.CreateFilterManager()
         aFilter = aFilterMgr.CreateFilter()
         aFilter.SetCriteria(criteria)
@@ -1003,7 +1064,7 @@ class smeshBuilder(SMESH._objref_SMESH_Gen):
         d = {}
         if hasattr(obj, "GetMeshInfo"):
             values = obj.GetMeshInfo()
-            for i in range(SMESH.Entity_Last._v):
+            for i in range(EnumToLong(SMESH.Entity_Last)):
                 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
             pass
         return d
@@ -1165,13 +1226,13 @@ omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
 #    import salome
 #    salome.salome_init()
 #    from salome.smesh import smeshBuilder
-#    smesh = smeshBuilder.New(salome.myStudy)
+#    smesh = smeshBuilder.New()
 #  \endcode
-#  @param  study     SALOME study, generally obtained by salome.myStudy.
+#  @param  isPublished If False, the notebool will not be used.
 #  @param  instance  CORBA proxy of SMESH Engine. If None, the default Engine is used.
 #  @return smeshBuilder instance
 
-def New( study, instance=None):
+def New( isPublished = True, instance=None):
     """
     Create a new smeshBuilder instance.The smeshBuilder class provides the Python
     interface to create or load meshes.
@@ -1180,10 +1241,10 @@ def New( study, instance=None):
         import salome
         salome.salome_init()
         from salome.smesh import smeshBuilder
-        smesh = smeshBuilder.New(salome.myStudy)
+        smesh = smeshBuilder.New()
 
     Parameters:
-        study     SALOME study, generally obtained by salome.myStudy.
+        isPublished If False, the notebool will not be used.
         instance  CORBA proxy of SMESH Engine. If None, the default Engine is used.
     Returns:
         smeshBuilder instance
@@ -1196,7 +1257,7 @@ def New( study, instance=None):
         doLcc = True
     smeshInst = smeshBuilder()
     assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
-    smeshInst.init_smesh(study)
+    smeshInst.init_smesh(isPublished)
     return smeshInst
 
 
@@ -1233,12 +1294,9 @@ class Mesh(metaclass=MeshMeta):
                 self.geom = obj
                 objHasName = True
                 # publish geom of mesh (issue 0021122)
-                if not self.geom.GetStudyEntry() and smeshpyD.GetCurrentStudy():
+                if not self.geom.GetStudyEntry():
                     objHasName = False
-                    studyID = smeshpyD.GetCurrentStudy()._get_StudyId()
-                    if studyID != geompyD.myStudyId:
-                        geompyD.init_geom( smeshpyD.GetCurrentStudy())
-                        pass
+                    geompyD.init_geom()
                     if name:
                         geo_name = name + " shape"
                     else:
@@ -1259,7 +1317,7 @@ class Mesh(metaclass=MeshMeta):
             self.geom = self.mesh.GetShapeToMesh()
 
         self.editor   = self.mesh.GetMeshEditor()
-        self.functors = [None] * SMESH.FT_Undefined._v
+        self.functors = [None] * EnumToLong(SMESH.FT_Undefined)
 
         # set self to algoCreator's
         for attrName in dir(self):
@@ -1515,12 +1573,12 @@ class Mesh(metaclass=MeshMeta):
                 print(msg)
                 print(allReasons)
             pass
-        if salome.sg.hasDesktop() and self.mesh.GetStudyId() >= 0:
+        if salome.sg.hasDesktop():
             if not isinstance( refresh, list): # not a call from subMesh.Compute()
                 smeshgui = salome.ImportComponentGUI("SMESH")
-                smeshgui.Init(self.mesh.GetStudyId())
+                smeshgui.Init()
                 smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok, (self.NbNodes()==0) )
-                if refresh: salome.sg.updateObjBrowser(True)
+                if refresh: salome.sg.updateObjBrowser()
 
         return ok
 
@@ -1545,11 +1603,9 @@ class Mesh(metaclass=MeshMeta):
         try:
             shapeText = ""
             mainIOR  = salome.orb.object_to_string( self.GetShape() )
-            for sname in salome.myStudyManager.GetOpenStudies():
-                s = salome.myStudyManager.GetStudyByName(sname)
-                if not s: continue
-                mainSO = s.FindObjectIOR(mainIOR)
-                if not mainSO: continue
+            s = salome.myStudy
+            mainSO = s.FindObjectIOR(mainIOR)
+            if mainSO:
                 if subShapeID == 1:
                     shapeText = '"%s"' % mainSO.GetName()
                 subIt = s.NewChildIterator(mainSO)
@@ -1566,7 +1622,6 @@ class Mesh(metaclass=MeshMeta):
                         continue
                     if ids == subShapeID:
                         shapeText = '"%s"' % subSO.GetName()
-                        break
             if not shapeText:
                 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
                 if shape:
@@ -1598,7 +1653,7 @@ class Mesh(metaclass=MeshMeta):
         groups = []
         for algoName, shapes in list(algo2shapes.items()):
             while shapes:
-                groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
+                groupType = EnumToLong( shapes[0].GetShapeType() )
                 otherTypeShapes = []
                 sameTypeShapes  = []
                 group = self.geompyD.CreateGroup( self.geom, groupType )
@@ -1637,12 +1692,11 @@ class Mesh(metaclass=MeshMeta):
     #  @ingroup l2_construct
     def Clear(self, refresh=False):
         self.mesh.Clear()
-        if ( salome.sg.hasDesktop() and
-             salome.myStudyManager.GetStudyByID( self.mesh.GetStudyId() ) ):
+        if ( salome.sg.hasDesktop() ):
             smeshgui = salome.ImportComponentGUI("SMESH")
-            smeshgui.Init(self.mesh.GetStudyId())
+            smeshgui.Init()
             smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
-            if refresh: salome.sg.updateObjBrowser(True)
+            if refresh: salome.sg.updateObjBrowser()
 
     ## Remove all nodes and elements of indicated shape
     #  @param refresh if @c True, Object browser is automatically updated (when running in GUI)
@@ -1652,9 +1706,9 @@ class Mesh(metaclass=MeshMeta):
         self.mesh.ClearSubMesh(geomId)
         if salome.sg.hasDesktop():
             smeshgui = salome.ImportComponentGUI("SMESH")
-            smeshgui.Init(self.mesh.GetStudyId())
+            smeshgui.Init()
             smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
-            if refresh: salome.sg.updateObjBrowser(True)
+            if refresh: salome.sg.updateObjBrowser()
 
     ## Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
     #  @param fineness [0.0,1.0] defines mesh fineness
@@ -1719,7 +1773,7 @@ class Mesh(metaclass=MeshMeta):
             AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
             status = self.mesh.AddHypothesis(geom, hyp)
         else:
-            status = HYP_BAD_GEOMETRY,""
+            status = HYP_BAD_GEOMETRY, ""
         hyp_name = GetName( hyp )
         geom_name = ""
         if geom:
@@ -2254,12 +2308,6 @@ class Mesh(metaclass=MeshMeta):
     def GetId(self):
         return self.mesh.GetId()
 
-    ## Get the study Id
-    #  @return integer value, which is the study Id of the mesh
-    #  @ingroup l1_auxiliary
-    def GetStudyId(self):
-        return self.mesh.GetStudyId()
-
     ## Check the group names for duplications.
     #  Consider the maximum group name length stored in MED file.
     #  @return True or False
@@ -2682,9 +2730,14 @@ class Mesh(metaclass=MeshMeta):
 
     ## Return an element based on all given nodes.
     #  @ingroup l1_meshinfo
-    def FindElementByNodes(self,nodes):
+    def FindElementByNodes(self, nodes):
         return self.mesh.FindElementByNodes(nodes)
 
+    ## Return elements including all given nodes.
+    #  @ingroup l1_meshinfo
+    def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
+        return self.mesh.GetElementsByNodes( nodes, elemType )
+
     ## Return true if the given element is a polygon
     #  @ingroup l1_meshinfo
     def IsPoly(self, id):
@@ -4908,11 +4961,11 @@ class Mesh(metaclass=MeshMeta):
         return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
 
     def _getFunctor(self, funcType ):
-        fn = self.functors[ funcType._v ]
+        fn = self.functors[ EnumToLong(funcType) ]
         if not fn:
             fn = self.smeshpyD.GetFunctor(funcType)
             fn.SetMesh(self.mesh)
-            self.functors[ funcType._v ] = fn
+            self.functors[ EnumToLong(funcType) ] = fn
         return fn
 
     ## Return value of a functor for a given element
@@ -5051,7 +5104,7 @@ class meshProxy(SMESH._objref_SMESH_Mesh):
     def __init__(self, *args):
         SMESH._objref_SMESH_Mesh.__init__(self, *args)
     def __deepcopy__(self, memo=None):
-        new = self.__class__()
+        new = self.__class__(self)
         return new
     def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
         if len( args ) == 3:
@@ -5068,7 +5121,7 @@ class submeshProxy(SMESH._objref_SMESH_subMesh):
         SMESH._objref_SMESH_subMesh.__init__(self, *args)
         self.mesh = None
     def __deepcopy__(self, memo=None):
-        new = self.__class__()
+        new = self.__class__(self)
         return new
 
     ## Compute the sub-mesh and return the status of the computation
@@ -5084,11 +5137,11 @@ class submeshProxy(SMESH._objref_SMESH_subMesh):
 
         ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
 
-        if salome.sg.hasDesktop() and self.mesh.GetStudyId() >= 0:
+        if salome.sg.hasDesktop():
             smeshgui = salome.ImportComponentGUI("SMESH")
-            smeshgui.Init(self.mesh.GetStudyId())
+            smeshgui.Init()
             smeshgui.SetMeshIcon( salome.ObjectToID( self ), ok, (self.GetNumberOfElements()==0) )
-            if refresh: salome.sg.updateObjBrowser(True)
+            if refresh: salome.sg.updateObjBrowser()
             pass
 
         return ok
@@ -5114,7 +5167,7 @@ class meshEditor(SMESH._objref_SMESH_MeshEditor):
         print("meshEditor: attribute '%s' NOT FOUND" % name)
         return None
     def __deepcopy__(self, memo=None):
-        new = self.__class__()
+        new = self.__class__(self)
         return new
     def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
         if len( args ) == 1: args += False,
@@ -5172,10 +5225,11 @@ omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
 ## Private class used to bind methods creating algorithms to the class Mesh
 #
 class algoCreator:
-    def __init__(self):
+    def __init__(self, method):
         self.mesh = None
         self.defaultAlgoType = ""
         self.algoTypeToClass = {}
+        self.method = method
 
     # Store a python class of algorithm
     def add(self, algoClass):
@@ -5189,26 +5243,50 @@ class algoCreator:
 
     # Create a copy of self and assign mesh to the copy
     def copy(self, mesh):
-        other = algoCreator()
+        other = algoCreator( self.method )
         other.defaultAlgoType = self.defaultAlgoType
-        other.algoTypeToClass  = self.algoTypeToClass
+        other.algoTypeToClass = self.algoTypeToClass
         other.mesh = mesh
         return other
 
     # Create an instance of algorithm
     def __call__(self,algo="",geom=0,*args):
-        algoType = self.defaultAlgoType
-        for arg in args + (algo,geom):
-            if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ):
-                geom = arg
-            if isinstance( arg, str ) and arg:
+        algoType = ""
+        shape = 0
+        if isinstance( algo, str ):
+            algoType = algo
+        elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
+               not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
+            shape = algo
+        elif algo:
+            args += (algo,)
+
+        if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
+            shape = geom
+        elif not algoType and isinstance( geom, str ):
+            algoType = geom
+        elif geom:
+            args += (geom,)
+        for arg in args:
+            if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
+                shape = arg
+            elif isinstance( arg, str ) and not algoType:
                 algoType = arg
+            else:
+                import traceback, sys
+                msg = "Warning. Unexpected argument in mesh.%s() --->  %s" % ( self.method, arg )
+                sys.stderr.write( msg + '\n' )
+                tb = traceback.extract_stack(None,2)
+                traceback.print_list( [tb[0]] )
+        if not algoType:
+            algoType = self.defaultAlgoType
         if not algoType and self.algoTypeToClass:
             algoType = list(self.algoTypeToClass.keys())[0]
         if algoType in self.algoTypeToClass:
             #print "Create algo",algoType
-            return self.algoTypeToClass[ algoType ]( self.mesh, geom )
-        raise RuntimeError("No class found for algo type %s" % algoType)
+
+            return self.algoTypeToClass[ algoType ]( self.mesh, shape )
+        raise RuntimeError( "No class found for algo type %s" % algoType)
         return None
 
 ## Private class used to substitute and store variable parameters of hypotheses.
@@ -5289,7 +5367,7 @@ for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
         if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
             #print "                     meshMethod:" , str(algo.meshMethod)
             if not hasattr( Mesh, algo.meshMethod ):
-                setattr( Mesh, algo.meshMethod, algoCreator()
+                setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
                 pass
             getattr( Mesh, algo.meshMethod ).add( algo )
             pass