Salome HOME
54122: Bad quality prismatic mesh
[modules/smesh.git] / src / SMESH_SWIG / smeshBuilder.py
index 1b5f9ecfc739e314b7d9f64fb96640990e992d96..88d2b0b1a1ed1f59f26c7f8cb83e33a7829b76d7 100644 (file)
@@ -1469,7 +1469,7 @@ class Mesh:
                     errText = "code %s" % -err.code
                 if errText: errText += ". "
                 errText += err.comment
-                if allReasons != "":allReasons += "\n"
+                if allReasonsallReasons += "\n"
                 if ok:
                     allReasons += '-  "%s"%s - %s' %(err.algoName, shapeText, errText)
                 else:
@@ -1507,7 +1507,7 @@ class Mesh:
                     reason = ("For unknown reason. "
                               "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
                     pass
-                if allReasons != "":allReasons += "\n"
+                if allReasonsallReasons += "\n"
                 allReasons += "-  " + reason
                 pass
             if not ok or allReasons != "":
@@ -1630,7 +1630,7 @@ class Mesh:
     def GetMeshOrder(self):
         return self.mesh.GetMeshOrder()
 
-    ## Set order in which concurrent sub-meshes sould be meshed
+    ## Set order in which concurrent sub-meshes should be meshed
     #  @param submeshes list of lists of sub-meshes
     #  @ingroup l2_construct
     def SetMeshOrder(self, submeshes):
@@ -1787,27 +1787,29 @@ class Mesh:
             pass
         pass
 
-    ## Export the mesh in a file in MED format and chooses the \a version of MED format
+    ## Export the mesh in a file in 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
     #  the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
-    #  the typical use is auto_groups=false.
-    #  @param version MED format version(MED_V2_1 or MED_V2_2)
+    #  the typical use is auto_groups=False.
+    #  @param version MED format version (MED_V2_1 or MED_V2_2,
+    #                 the latter meaning any current version). The parameter is
+    #                 obsolete since MED_V2_1 is no longer supported.
     #  @param overwrite boolean parameter for overwriting/not overwriting the file
     #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
-    #  @param autoDimension: if @c True (default), a space dimension of a MED mesh can be either
+    #  @param autoDimension if @c True (default), a space dimension of a MED mesh can be either
     #         - 1D if all mesh nodes lie on OX coordinate axis, or
     #         - 2D if all mesh nodes lie on XOY coordinate plane, or
-    #         - 3D in the rest cases.
+    #         - 3D in the rest cases.<br>
     #         If @a autoDimension is @c False, the space dimension is always 3.
-    #  @param fields list of GEOM fields defined on the shape to mesh.
-    #  @param geomAssocFields each character of this string means a need to export a 
+    #  @param fields list of GEOM fields defined on the shape to mesh.
+    #  @param geomAssocFields each character of this string means a need to export a 
     #         corresponding field; correspondence between fields and characters is following:
-    #         - 'v' stands for _vertices_ field;
-    #         - 'e' stands for _edges_ field;
-    #         - 'f' stands for _faces_ field;
-    #         - 's' stands for _solids_ field.
+    #         - 'v' stands for "_vertices _" field;
+    #         - 'e' stands for "_edges _" field;
+    #         - 'f' stands for "_faces _" field;
+    #         - 's' stands for "_solids _" field.
     #  @ingroup l2_impexp
     def ExportMED(self, f, auto_groups=0, version=MED_V2_2,
                   overwrite=1, meshPart=None, autoDimension=True, fields=[], geomAssocFields=''):
@@ -1906,22 +1908,23 @@ class Mesh:
             meshPart = self.mesh
         self.mesh.ExportGMF(meshPart, f, True)
 
-    ## Deprecated, used only for compatibility! Please, use ExportToMEDX() method instead.
-    #  Export 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
+    ## Deprecated, used only for compatibility! Please, use ExportMED() method instead.
+    #  Export the mesh in a file in 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 version MED format version (MED_V2_1 or MED_V2_2,
+    #                 the latter meaning any current version). The parameter is
+    #                 obsolete since MED_V2_1 is no longer supported.
     #  @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
-    #  @param autoDimension: if @c True (default), a space dimension of a MED mesh can be either
+    #  @param autoDimension if @c True (default), a space dimension of a MED mesh can be either
     #         - 1D if all mesh nodes lie on OX coordinate axis, or
     #         - 2D if all mesh nodes lie on XOY coordinate plane, or
-    #         - 3D in the rest cases.
-    #
+    #         - 3D in the rest cases.<br>
     #         If @a autoDimension is @c False, the space dimension is always 3.
     #  @ingroup l2_impexp
-    def ExportToMED(self, f, version, opt=0, overwrite=1, autoDimension=True):
+    def ExportToMED(self, f, version=MED_V2_2, opt=0, overwrite=1, autoDimension=True):
         self.mesh.ExportToMEDX(f, opt, version, overwrite, autoDimension)
 
     # Operations with groups:
@@ -2684,9 +2687,14 @@ class Mesh:
 
     ## 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):
@@ -4563,10 +4571,12 @@ class Mesh:
     #  @param NodesToKeep nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
     #         If @a NodesToKeep does not include a node to keep for some group to merge,
     #         then the first node in the group is kept.
+    #  @param AvoidMakingHoles prevent merging nodes which cause removal of elements becoming
+    #         invalid
     #  @ingroup l2_modif_trsf
-    def MergeNodes (self, GroupsOfNodes, NodesToKeep=[]):
+    def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
         # NodesToKeep are converted to SMESH_IDSource in meshEditor.MergeNodes()
-        self.editor.MergeNodes(GroupsOfNodes,NodesToKeep)
+        self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
 
     ## Find the elements built on the same nodes.
     #  @param MeshOrSubMeshOrGroup Mesh or SubMesh, or Group of elements for searching
@@ -5122,17 +5132,18 @@ class meshEditor(SMESH._objref_SMESH_MeshEditor):
     def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
         if len( args ) == 2: args += False,
         return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
-    def MergeNodes(self,*args): # a 2nd arg added (NodesToKeep)
+    def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
         if len( args ) == 1:
-            return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [] )
+            return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
         NodesToKeep = args[1]
+        AvoidMakingHoles = args[2] if len( args ) == 3 else False
         unRegister  = genObjUnRegister()
         if NodesToKeep:
             if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
                 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
             if not isinstance( NodesToKeep, list ):
                 NodesToKeep = [ NodesToKeep ]
-        return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep )
+        return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
     pass
 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
 
@@ -5171,10 +5182,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):
@@ -5188,25 +5200,48 @@ 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 = self.algoTypeToClass.keys()[0]
         if self.algoTypeToClass.has_key( algoType ):
             #print "Create algo",algoType
-            return self.algoTypeToClass[ algoType ]( self.mesh, geom )
+            return self.algoTypeToClass[ algoType ]( self.mesh, shape )
         raise RuntimeError, "No class found for algo type %s" % algoType
         return None
 
@@ -5288,7 +5323,7 @@ for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
         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()
+                setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
                 pass
             getattr( Mesh, algo.meshMethod ).add( algo )
             pass