Salome HOME
CoTech decision: move MEDWrapper from MED to SMESH
[modules/smesh.git] / src / SMESH_SWIG / smeshBuilder.py
index 78089201d2099facc7cdee6f100b041a1380e2c9..852b6ba50aa820e632cc78b54f3d8c4e2f133f57 100644 (file)
@@ -520,25 +520,19 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
         return aMesh
 
     ## Creates a Mesh object(s) importing data from the given MED file
-    #  @return a list of Mesh class instances
+    #  @return a tuple ( list of Mesh class instances, SMESH.DriverMED_ReadStatus )
     #  @ingroup l2_impexp
     def CreateMeshesFromMED( self,theFileName ):
         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
-        aMeshes = []
-        for iMesh in range(len(aSmeshMeshes)) :
-            aMesh = Mesh(self, self.geompyD, aSmeshMeshes[iMesh])
-            aMeshes.append(aMesh)
+        aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
         return aMeshes, aStatus
 
     ## Creates a Mesh object(s) importing data from the given SAUV file
-    #  @return a list of Mesh class instances
+    #  @return a tuple ( list of Mesh class instances, SMESH.DriverMED_ReadStatus )
     #  @ingroup l2_impexp
     def CreateMeshesFromSAUV( self,theFileName ):
         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
-        aMeshes = []
-        for iMesh in range(len(aSmeshMeshes)) :
-            aMesh = Mesh(self, self.geompyD, aSmeshMeshes[iMesh])
-            aMeshes.append(aMesh)
+        aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
         return aMeshes, aStatus
 
     ## Creates a Mesh object importing data from the given STL file
@@ -550,18 +544,15 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
         return aMesh
 
     ## Creates Mesh objects importing data from the given CGNS file
-    #  @return an instance of Mesh class
+    #  @return a tuple ( list of Mesh class instances, SMESH.DriverMED_ReadStatus )
     #  @ingroup l2_impexp
     def CreateMeshesFromCGNS( self, theFileName ):
         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
-        aMeshes = []
-        for iMesh in range(len(aSmeshMeshes)) :
-            aMesh = Mesh(self, self.geompyD, aSmeshMeshes[iMesh])
-            aMeshes.append(aMesh)
+        aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
         return aMeshes, aStatus
 
     ## Creates a Mesh object importing data from the given GMF file
-    #  @return [ an instance of Mesh class, SMESH::ComputeError ]
+    #  @return [ an instance of Mesh class, SMESH.ComputeError ]
     #  @ingroup l2_impexp
     def CreateMeshesFromGMF( self, theFileName ):
         aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
@@ -675,10 +666,10 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
                      Tolerance=1e-07):
         if not CritType in SMESH.FunctorType._items:
             raise TypeError, "CritType should be of SMESH.FunctorType"
-        aCriterion = self.GetEmptyCriterion()
+        aCriterion               = self.GetEmptyCriterion()
         aCriterion.TypeOfElement = elementType
-        aCriterion.Type = self.EnumToLong(CritType)
-        aCriterion.Tolerance = Tolerance
+        aCriterion.Type          = self.EnumToLong(CritType)
+        aCriterion.Tolerance     = Tolerance
 
         aThreshold = Threshold
 
@@ -732,6 +723,30 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
             else:
                 raise ValueError,\
                       "The Threshold should be an ID of mesh face and not '%s'"%aThreshold
+        elif CritType == FT_ConnectedElements:
+            # Checks the Threshold
+            if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
+                aCriterion.ThresholdID = aThreshold.GetStudyEntry()
+                if not aCriterion.ThresholdID:
+                    name = aThreshold.GetName()
+                    if not name:
+                        name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
+                    aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
+            elif isinstance(aThreshold, int): # node id
+                aCriterion.Threshold = aThreshold
+            elif isinstance(aThreshold, list): # 3 point coordinates
+                if len( aThreshold ) < 3:
+                    raise ValueError, "too few point coordinates, must be 3"
+                aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
+            elif isinstance(aThreshold, str):
+                if aThreshold.isdigit():
+                    aCriterion.Threshold = aThreshold # node id
+                else:
+                    aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
+            else:
+                raise ValueError,\
+                      "The Threshold should either a VERTEX, or a node ID, "\
+                      "or a list of point coordinates and not '%s'"%aThreshold
         elif CritType == FT_ElemGeomType:
             # Checks the Threshold
             try:
@@ -808,6 +823,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
     #  @param UnaryOp  FT_LogicalNOT or FT_Undefined
     #  @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface,
     #         FT_LyingOnGeom, FT_CoplanarFaces and FT_EqualNodes criteria
+    #  @param mesh the mesh to initialize the filter with
     #  @return SMESH_Filter
     #
     #  <a href="../tui_filters_page.html#tui_filters">Example of Filters usage</a>
@@ -817,13 +833,17 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
                   Compare=FT_EqualTo,
                   Threshold="",
                   UnaryOp=FT_Undefined,
-                  Tolerance=1e-07):
+                  Tolerance=1e-07,
+                  mesh=None):
         aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
         aFilterMgr = self.CreateFilterManager()
         aFilter = aFilterMgr.CreateFilter()
         aCriteria = []
         aCriteria.append(aCriterion)
         aFilter.SetCriteria(aCriteria)
+        if mesh:
+            if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
+            else                       : aFilter.SetMesh( mesh )
         aFilterMgr.UnRegister()
         return aFilter
 
@@ -1334,7 +1354,10 @@ class Mesh:
                 if errText: errText += ". "
                 errText += err.comment
                 if allReasons != "":allReasons += "\n"
-                allReasons += '-  "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
+                if ok:
+                    allReasons += '-  "%s"%s - %s' %(err.algoName, shapeText, errText)
+                else:
+                    allReasons += '-  "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
                 pass
 
             # Treat hyp errors
@@ -1503,6 +1526,8 @@ class Mesh:
     #  @return SMESH.Hypothesis_Status
     #  @ingroup l2_hypotheses
     def RemoveHypothesis(self, hyp, geom=0):
+        if not hyp:
+            return None
         if isinstance( hyp, Mesh_Algorithm ):
             hyp = hyp.GetAlgorithm()
             pass
@@ -1542,14 +1567,21 @@ class Mesh:
     #  @param version MED format version(MED_V2_1 or MED_V2_2)
     #  @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
+    #         - 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.
+    #
+    #         If @a autoDimension is @c False, the space dimension is always 3.
     #  @ingroup l2_impexp
-    def ExportMED(self, f, auto_groups=0, version=MED_V2_2, overwrite=1, meshPart=None):
+    def ExportMED(self, f, auto_groups=0, version=MED_V2_2,
+                  overwrite=1, meshPart=None, autoDimension=True):
         if meshPart:
             if isinstance( meshPart, list ):
                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
-            self.mesh.ExportPartToMED( meshPart, f, auto_groups, version, overwrite )
+            self.mesh.ExportPartToMED( meshPart, f, auto_groups, version, overwrite, autoDimension)
         else:
-            self.mesh.ExportToMEDX(f, auto_groups, version, overwrite)
+            self.mesh.ExportToMEDX(f, auto_groups, version, overwrite, autoDimension)
 
     ## Exports the mesh in a file in SAUV format
     #  @param f is the file name
@@ -1940,12 +1972,6 @@ class Mesh:
     def GetIDSource(self, ids, elemType):
         return self.editor.MakeIDSource(ids, elemType)
 
-    ## Gets MED Mesh
-    #  @return an instance of SALOME_MED::MESH
-    #  @ingroup l1_auxiliary
-    def GetMEDMesh(self):
-        return self.mesh.GetMEDMesh()
-
 
     # Get informations about mesh contents:
     # ------------------------------------
@@ -2023,6 +2049,12 @@ class Mesh:
     def NbTrianglesOfOrder(self, elementOrder):
         return self.mesh.NbTrianglesOfOrder(elementOrder)
 
+    ## Returns the number of biquadratic triangles in the mesh
+    #  @return an integer value
+    #  @ingroup l1_meshinfo
+    def NbBiQuadTriangles(self):
+        return self.mesh.NbBiQuadTriangles()
+
     ## Returns the number of quadrangles in the mesh
     #  @return an integer value
     #  @ingroup l1_meshinfo
@@ -2829,7 +2861,6 @@ class Mesh:
         return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
 
     ## Splits quadrangles into triangles.
-    #
     #  @param IDsOfElements the faces to be splitted.
     #  @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
@@ -2860,6 +2891,20 @@ class Mesh:
         Functor = self.smeshpyD.GetFunctor(theCriterion)
         return self.editor.QuadToTriObject(theObject, Functor)
 
+    ## Splits each of given quadrangles into 4 triangles. A node is added at the center of
+    #  a quadrangle.
+    #  @param theElements the faces to be splitted. This can be either mesh, sub-mesh,
+    #         group or a list of face IDs. By default all quadrangles are split
+    #  @ingroup l2_modif_cutquadr
+    def QuadTo4Tri (self, theElements=[]):
+        if isinstance( theElements, Mesh ):
+            theElements = theElements.mesh
+        elif not theElements:
+            theElements = self.mesh
+        elif isinstance( theElements, list ):
+            theElements = self.GetIDSource( theElements, SMESH.FACE )
+        return self.editor.QuadTo4Tri( theElements )
+
     ## Splits quadrangles into triangles.
     #  @param IDsOfElements the faces to be splitted
     #  @param Diag13        is used to choose a diagonal for splitting.
@@ -3122,6 +3167,8 @@ class Mesh:
     #  @param theToBiQuad If True, converts the mesh to bi-quadratic
     #  @ingroup l2_modif_tofromqu
     def ConvertToQuadratic(self, theForce3d, theSubMesh=None, theToBiQuad=False):
+        if isinstance( theSubMesh, Mesh ):
+            theSubMesh = theSubMesh.mesh
         if theToBiQuad:
             self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
         else:
@@ -3129,6 +3176,9 @@ class Mesh:
                 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
             else:
                 self.editor.ConvertToQuadratic(theForce3d)
+        error = self.editor.GetLastError()
+        if error and error.comment:
+            print error.comment
             
     ## Converts the mesh from quadratic to ordinary,
     #  deletes old quadratic elements, \n replacing
@@ -4084,7 +4134,30 @@ class Mesh:
     def GetLastCreatedElems(self):
         return self.editor.GetLastCreatedElems()
 
-     ## Creates a hole in a mesh by doubling the nodes of some particular elements
+    ## Clears sequences of nodes and elements created by mesh edition oparations
+    #  @ingroup l1_auxiliary
+    def ClearLastCreated(self):
+        self.editor.ClearLastCreated()
+
+    ## Creates Duplicates given elements, i.e. creates new elements based on the 
+    #  same nodes as the given ones.
+    #  @param theElements - container of elements to duplicate. It can be a Mesh,
+    #         sub-mesh, group, filter or a list of element IDs.
+    # @param theGroupName - a name of group to contain the generated elements.
+    #                    If a group with such a name already exists, the new elements
+    #                    are added to the existng group, else a new group is created.
+    #                    If \a theGroupName is empty, new elements are not added 
+    #                    in any group.
+    # @return a group where the new elements are added. None if theGroupName == "".
+    #  @ingroup l2_modif_edit
+    def DoubleElements(self, theElements, theGroupName=""):
+        if isinstance( theElements, Mesh ):
+            theElements = theElements.mesh
+        elif isinstance( theElements, list ):
+            theElements = self.GetIDSource( theElements, SMESH.ALL )
+        return self.editor.DoubleElements(theElements, theGroupName)
+
+    ## Creates a hole in a mesh by doubling the nodes of some particular elements
     #  @param theNodes identifiers of nodes to be doubled
     #  @param theModifiedElems identifiers of elements to be updated by the new (doubled)
     #         nodes. If list of element identifiers is empty then nodes are doubled but