Salome HOME
fix bug 12361. In SetName(): there may be no study
[modules/smesh.git] / src / SMESH_SWIG / smesh.py
index 92fefeda222c7358cbdbda9b314b3d295f345850..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)
-    attr = sobj.FindAttribute("AttributeName")[1]
-    attr.SetValue(name)
+    if not sobj is None:
+        attr = sobj.FindAttribute("AttributeName")[1]
+        attr.SetValue(name)
 
 # Algorithms and hypothesis
 # =========================
@@ -92,10 +93,44 @@ class Mesh_Algorithm:
         """
         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
         """
+        if geom is None:
+            raise RuntimeError, "Attemp to create " + hypo + " algoritm on None shape"
         self.mesh = mesh
         piece = mesh.geom
         if geom==0:
@@ -111,7 +146,8 @@ class Mesh_Algorithm:
 
         self.algo = smesh.CreateHypothesis(hypo, so)
         SetName(self.algo, name + "/" + hypo)
-        mesh.mesh.AddHypothesis(self.geom, self.algo)
+        status = mesh.mesh.AddHypothesis(self.geom, self.algo)
+        self.TreatHypoStatus( status, hypo, name, 1 )
 
     def Hypothesis(self, hyp, args=[], so="libStdMeshersEngine.so"):
         """
@@ -126,8 +162,10 @@ class Mesh_Algorithm:
             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
@@ -206,11 +244,26 @@ class Mesh_Segment(Mesh_Algorithm):
         """
         return self.Hypothesis("Propagation")
 
-    def AutomaticLength(self):
+    def AutomaticLength(self, fineness=0):
         """
          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
 # ---------------------------------
@@ -281,6 +334,15 @@ class Mesh_Quadrangle(Mesh_Algorithm):
         """
         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
 # ------------------------------
 
@@ -322,6 +384,37 @@ class Mesh_Hexahedron(Mesh_Algorithm):
         """
         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
 # ==================
 
@@ -438,26 +531,67 @@ class Mesh:
         """
         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)
-            smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), b )
+            smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok )
             salome.sg.updateObjBrowser(1)
-        return b
+            pass
+        return ok
 
-    def AutomaticTetrahedralization(self):
+    def AutomaticTetrahedralization(self, fineness=0):
         """
         Compute tetrahedral mesh using AutomaticLength + MEFISTO + NETGEN
+        The parameter \a fineness [0.-1.] defines mesh fineness
         """
         dim = self.MeshDimension()
         # assign hypotheses
         self.RemoveGlobalHypotheses()
-        self.Segment().AutomaticLength()
+        self.Segment().AutomaticLength(fineness)
         if dim > 1 :
             self.Triangle().LengthFromEdges()
             pass
@@ -466,14 +600,15 @@ class Mesh:
             pass
         return self.Compute()
 
-    def AutomaticHexahedralization(self):
+    def AutomaticHexahedralization(self, fineness=0):
         """
         Compute hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
+        The parameter \a fineness [0.-1.] defines mesh fineness
         """
         dim = self.MeshDimension()
         # assign hypotheses
         self.RemoveGlobalHypotheses()
-        self.Segment().AutomaticLength()
+        self.Segment().AutomaticLength(fineness)
         if dim > 1 :
             self.Quadrangle()
             pass
@@ -516,6 +651,9 @@ class Mesh:
         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
@@ -536,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
-         \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)