Salome HOME
fix bug 12361. In SetName(): there may be no study
[modules/smesh.git] / src / SMESH_SWIG / smesh.py
index 50df727f9aa4f5aa0ec9b61d52aaf30b3d842b78..6b95891c7b07192fd00a02938010890048c4ab08 100644 (file)
@@ -60,8 +60,9 @@ def GetName(obj):
 def SetName(obj, name):
     ior  = salome.orb.object_to_string(obj)
     sobj = salome.myStudy.FindObjectIOR(ior)
 def SetName(obj, name):
     ior  = salome.orb.object_to_string(obj)
     sobj = salome.myStudy.FindObjectIOR(ior)
-    attr = sobj.FindAttribute("AttributeName")[1]
-    attr.SetValue(name)
+    if not sobj is None:
+        attr = sobj.FindAttribute("AttributeName")[1]
+        attr.SetValue(name)
 
 # Algorithms and hypothesis
 # =========================
 
 # Algorithms and hypothesis
 # =========================
@@ -77,6 +78,7 @@ class Mesh_Algorithm:
     mesh = 0
     geom = 0
     subm = 0
     mesh = 0
     geom = 0
     subm = 0
+    algo = 0
 
     def GetSubMesh(self):
         """
 
     def GetSubMesh(self):
         """
@@ -85,10 +87,50 @@ class Mesh_Algorithm:
         """
         return self.subm
 
         """
         return self.subm
 
+    def GetAlgorithm(self):
+        """
+         Return the wrapped mesher
+        """
+        return self.algo
+
+    def TreatHypoStatus(self, status, hypName, geomName, isAlgo):
+        """
+        Private method. Print error message if a hypothesis was not assigned
+        """
+        if isAlgo:
+            hypType = "algorithm"
+        else:
+            hypType = "hypothesis"
+        if status == SMESH.HYP_UNKNOWN_FATAL :
+            reason = "for unknown reason"
+        elif status == SMESH.HYP_INCOMPATIBLE :
+            reason = "this hypothesis mismatches algorithm"
+        elif status == SMESH.HYP_NOTCONFORM :
+            reason = "not conform mesh would be built"
+        elif status == SMESH.HYP_ALREADY_EXIST :
+            reason = hypType + " of the same dimension already assigned to this shape"
+        elif status == SMESH.HYP_BAD_DIM :
+            reason = hypType + " mismatches shape"
+        elif status == SMESH.HYP_CONCURENT :
+            reason = "there are concurrent hypotheses on sub-shapes"
+        elif status == SMESH.HYP_BAD_SUBSHAPE :
+            reason = "shape is neither the main one, nor its subshape, nor a valid group"
+        else:
+            return
+        hypName = '"' + hypName + '"'
+        geomName= '"' + geomName+ '"'
+        if status < SMESH.HYP_UNKNOWN_FATAL:
+            print hypName, "was assigned to",    geomName,"but", reason
+        else:
+            print hypName, "was not assigned to",geomName,":", reason
+        pass
+
     def Create(self, mesh, geom, hypo, so="libStdMeshersEngine.so"):
         """
          Private method
         """
     def Create(self, mesh, geom, hypo, so="libStdMeshersEngine.so"):
         """
          Private method
         """
+        if geom is None:
+            raise RuntimeError, "Attemp to create " + hypo + " algoritm on None shape"
         self.mesh = mesh
         piece = mesh.geom
         if geom==0:
         self.mesh = mesh
         piece = mesh.geom
         if geom==0:
@@ -102,9 +144,10 @@ class Mesh_Algorithm:
                 geompy.addToStudyInFather(piece, geom, name)
             self.subm = mesh.mesh.GetSubMesh(geom, hypo)
 
                 geompy.addToStudyInFather(piece, geom, name)
             self.subm = mesh.mesh.GetSubMesh(geom, hypo)
 
-        algo = smesh.CreateHypothesis(hypo, so)
-        SetName(algo, name + "/" + hypo)
-        mesh.mesh.AddHypothesis(self.geom, algo)
+        self.algo = smesh.CreateHypothesis(hypo, so)
+        SetName(self.algo, name + "/" + hypo)
+        status = mesh.mesh.AddHypothesis(self.geom, self.algo)
+        self.TreatHypoStatus( status, hypo, name, 1 )
 
     def Hypothesis(self, hyp, args=[], so="libStdMeshersEngine.so"):
         """
 
     def Hypothesis(self, hyp, args=[], so="libStdMeshersEngine.so"):
         """
@@ -119,8 +162,10 @@ class Mesh_Algorithm:
             a = a + s + str(args[i])
             s = ","
             i = i + 1
             a = a + s + str(args[i])
             s = ","
             i = i + 1
-        SetName(hypo, GetName(self.geom) + "/" + hyp + a)
-        self.mesh.mesh.AddHypothesis(self.geom, hypo)
+        name = GetName(self.geom)
+        SetName(hypo, name + "/" + hyp + a)
+        status = self.mesh.mesh.AddHypothesis(self.geom, hypo)
+        self.TreatHypoStatus( status, hyp, name, 0 )
         return hypo
 
 # Public class: Mesh_Segment
         return hypo
 
 # Public class: Mesh_Segment
@@ -199,11 +244,26 @@ class Mesh_Segment(Mesh_Algorithm):
         """
         return self.Hypothesis("Propagation")
 
         """
         return self.Hypothesis("Propagation")
 
-    def AutomaticLength(self):
+    def AutomaticLength(self, fineness=0):
         """
          Define "AutomaticLength" hypothesis
         """
          Define "AutomaticLength" hypothesis
+         \param fineness for the fineness [0-1]
         """
         """
-        return self.Hypothesis("AutomaticLength")
+        hyp = self.Hypothesis("AutomaticLength")
+        hyp.SetFineness( fineness )
+        return hyp
+
+    def QuadraticMesh(self):
+        """
+         Define "QuadraticMesh" hypothesis, forcing construction of quadratic edges.
+         If the 2D mesher sees that all boundary edges are quadratic ones,
+         it generates quadratic faces, else it generates linear faces using
+         medium nodes as if they were vertex ones.
+         The 3D mesher generates quadratic volumes only if all boundary faces
+         are quadratic ones, else it fails.
+        """
+        hyp = self.Hypothesis("QuadraticMesh")
+        return hyp
 
 # Public class: Mesh_Segment_Python
 # ---------------------------------
 
 # Public class: Mesh_Segment_Python
 # ---------------------------------
@@ -274,6 +334,15 @@ class Mesh_Quadrangle(Mesh_Algorithm):
         """
         self.Create(mesh, geom, "Quadrangle_2D")
 
         """
         self.Create(mesh, geom, "Quadrangle_2D")
 
+    def QuadranglePreference(self):
+        """
+         Define "QuadranglePreference" hypothesis, forcing construction
+         of quadrangles if the number of nodes on opposite edges is not the same
+         in the case where the global number of nodes on edges is even
+        """
+        hyp = self.Hypothesis("QuadranglePreference")
+        return hyp
+
 # Public class: Mesh_Tetrahedron
 # ------------------------------
 
 # Public class: Mesh_Tetrahedron
 # ------------------------------
 
@@ -315,6 +384,37 @@ class Mesh_Hexahedron(Mesh_Algorithm):
         """
         self.Create(mesh, geom, "Hexa_3D")
 
         """
         self.Create(mesh, geom, "Hexa_3D")
 
+# Public class: Mesh_Netgen
+# ------------------------------
+
+class Mesh_Netgen(Mesh_Algorithm):
+    """
+    Class to define a NETGEN-based 2D or 3D algorithm
+    that need no discrete boundary (i.e. independent)
+    """
+
+    is3D = 0
+
+    def __init__(self, mesh, is3D, geom=0):
+        """
+         Private constructor
+        """
+        self.is3D = is3D
+        if is3D:
+            self.Create(mesh, geom, "NETGEN_2D3D", "libNETGENEngine.so")
+        else:
+            self.Create(mesh, geom, "NETGEN_2D", "libNETGENEngine.so")
+
+    def Parameters(self):
+        """
+         Define hypothesis containing parameters of the algorithm
+        """
+        if self.is3D:
+            hyp = self.Hypothesis("NETGEN_Parameters", [], "libNETGENEngine.so")
+        else:
+            hyp = self.Hypothesis("NETGEN_Parameters_2D", [], "libNETGENEngine.so")
+        return hyp
+
 # Public class: Mesh
 # ==================
 
 # Public class: Mesh
 # ==================
 
@@ -378,12 +478,16 @@ class Mesh:
          \param algo values are smesh.REGULAR or smesh.PYTHON for discretization via python function
          \param geom If defined, subshape to be meshed
         """
          \param algo values are smesh.REGULAR or smesh.PYTHON for discretization via python function
          \param geom If defined, subshape to be meshed
         """
+        ## if Segment(geom) is called by mistake
+        if ( isinstance( algo, geompy.GEOM._objref_GEOM_Object)):
+            algo, geom = geom, algo
+            pass
         if algo == REGULAR:
             return Mesh_Segment(self, geom)
         elif algo == PYTHON:
             return Mesh_Segment_Python(self, geom)
         else:
         if algo == REGULAR:
             return Mesh_Segment(self, geom)
         elif algo == PYTHON:
             return Mesh_Segment_Python(self, geom)
         else:
-            return Mesh_Segment(self, algo)
+            return Mesh_Segment(self, geom)
 
     def Triangle(self, geom=0):
         """
 
     def Triangle(self, geom=0):
         """
@@ -412,6 +516,10 @@ class Mesh:
          \param algo values are: smesh.NETGEN, smesh.GHS3D
          \param geom If defined, subshape to be meshed
         """
          \param algo values are: smesh.NETGEN, smesh.GHS3D
          \param geom If defined, subshape to be meshed
         """
+        ## if Tetrahedron(geom) is called by mistake
+        if ( isinstance( algo, geompy.GEOM._objref_GEOM_Object)):
+            algo, geom = geom, algo
+            pass
         return Mesh_Tetrahedron(self, algo, geom)
 
     def Hexahedron(self, geom=0):
         return Mesh_Tetrahedron(self, algo, geom)
 
     def Hexahedron(self, geom=0):
@@ -423,51 +531,91 @@ class Mesh:
         """
         return Mesh_Hexahedron(self, geom)
 
         """
         return Mesh_Hexahedron(self, geom)
 
-    def Compute(self):
+    def Netgen(self, is3D, geom=0):
+        """
+         Creates a NETGEN-based 2D or 3D independent algorithm (i.e. needs no
+         discrete boundary).
+         If the optional \a geom parameter is not sets, this algorithm is global.
+         Otherwise, this algorithm defines a submesh based on \a geom subshape.
+         \param is3D If 0 then algorithm is 2D, otherwise 3D
+         \param geom If defined, subshape to be meshed
         """
         """
-         Compute the mesh and return the status of the computation
+        return Mesh_Netgen(self, is3D, geom)
+
+    def Compute(self):
         """
         """
-        b = smesh.Compute(self.mesh, self.geom)
+        Compute the mesh and return the status of the computation
+        """
+        ok = smesh.Compute(self.mesh, self.geom)
+        if not ok:
+            errors = smesh.GetAlgoState( self.mesh, self.geom )
+            allReasons = ""
+            for err in errors:
+                if err.isGlobalAlgo:
+                    glob = " global "
+                else:
+                    glob = " local "
+                    pass
+                dim = str(err.algoDim)
+                if err.name == SMESH.MISSING_ALGO:
+                    reason = glob + dim + "D algorithm is missing"
+                elif err.name == SMESH.MISSING_HYPO:
+                    name = '"' + err.algoName + '"'
+                    reason = glob + dim + "D algorithm " + name + " misses " + dim + "D hypothesis"
+                else:
+                    reason = "Global \"Not Conform mesh allowed\" hypothesis is missing"
+                    pass
+                if allReasons != "":
+                    allReasons += "\n"
+                    pass
+                allReasons += reason
+                pass
+            if allReasons != "":
+                print '"' + GetName(self.mesh) + '"',"not computed:"
+                print allReasons
+                pass
+            pass
         if salome.sg.hasDesktop():
             smeshgui = salome.ImportComponentGUI("SMESH")
             smeshgui.Init(salome.myStudyId)
         if salome.sg.hasDesktop():
             smeshgui = salome.ImportComponentGUI("SMESH")
             smeshgui.Init(salome.myStudyId)
-            smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), b )
+            smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok )
             salome.sg.updateObjBrowser(1)
             salome.sg.updateObjBrowser(1)
-        return b
+            pass
+        return ok
 
 
-    def AutomaticTetrahedralization(self):
+    def AutomaticTetrahedralization(self, fineness=0):
         """
         Compute tetrahedral mesh using AutomaticLength + MEFISTO + NETGEN
         """
         Compute tetrahedral mesh using AutomaticLength + MEFISTO + NETGEN
+        The parameter \a fineness [0.-1.] defines mesh fineness
         """
         dim = self.MeshDimension()
         # assign hypotheses
         self.RemoveGlobalHypotheses()
         """
         dim = self.MeshDimension()
         # assign hypotheses
         self.RemoveGlobalHypotheses()
-        self.Segment().AutomaticLength()
+        self.Segment().AutomaticLength(fineness)
         if dim > 1 :
             self.Triangle().LengthFromEdges()
             pass
         if dim > 2 :
             self.Tetrahedron(NETGEN)
             pass
         if dim > 1 :
             self.Triangle().LengthFromEdges()
             pass
         if dim > 2 :
             self.Tetrahedron(NETGEN)
             pass
-        self.Compute()
-        pass
+        return self.Compute()
 
 
-    def AutomaticHexahedralization(self):
+    def AutomaticHexahedralization(self, fineness=0):
         """
         Compute hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
         """
         Compute hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
+        The parameter \a fineness [0.-1.] defines mesh fineness
         """
         dim = self.MeshDimension()
         # assign hypotheses
         self.RemoveGlobalHypotheses()
         """
         dim = self.MeshDimension()
         # assign hypotheses
         self.RemoveGlobalHypotheses()
-        self.Segment().AutomaticLength()
+        self.Segment().AutomaticLength(fineness)
         if dim > 1 :
             self.Quadrangle()
             pass
         if dim > 2 :
             self.Hexahedron()            
             pass
         if dim > 1 :
             self.Quadrangle()
             pass
         if dim > 2 :
             self.Hexahedron()            
             pass
-        self.Compute()
-        pass
+        return self.Compute()
 
     def RemoveGlobalHypotheses(self):
         """
 
     def RemoveGlobalHypotheses(self):
         """
@@ -503,6 +651,9 @@ class Mesh:
         elif tgeo == "SHELL":
             type = SMESH.VOLUME
         elif tgeo == "COMPOUND":
         elif tgeo == "SHELL":
             type = SMESH.VOLUME
         elif tgeo == "COMPOUND":
+            if len( geompy.GetObjectIDs( grp )) == 0:
+                print "Mesh.Group: empty geometric group", GetName( grp )
+                return 0
             tgeo = geompy.GetType(grp)
             if tgeo == geompy.ShapeType["VERTEX"]:
                 type = SMESH.NODE
             tgeo = geompy.GetType(grp)
             if tgeo == geompy.ShapeType["VERTEX"]:
                 type = SMESH.NODE
@@ -523,7 +674,7 @@ class Mesh:
         """
          Export the mesh in a file with the MED format and choice the \a version of MED format
          \param f is the file name
         """
          Export the mesh in a file with the MED format and choice the \a version of MED format
          \param f is the file name
-         \param version values are smesh.MED_V2_1, smesh.MED_V2_2
+         \param version values are SMESH.MED_V2_1, SMESH.MED_V2_2
         """
         self.mesh.ExportToMED(f, opt, version)
 
         """
         self.mesh.ExportToMED(f, opt, version)