]> SALOME platform Git repositories - modules/smesh.git/blobdiff - src/SMESH_SWIG/smeshDC.py
Salome HOME
Another minor correction
[modules/smesh.git] / src / SMESH_SWIG / smeshDC.py
index 3c36b1be6721ceb0c135ebd36e2219e706a58b91..7b99c3519cef48b027250ccb4f5b8c83850a1763 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 #  Author : Francis KLOSS, OCC
 #  Module : SMESH
 
-"""
- \namespace smesh
- \brief Module smesh
-"""
+## @package smesh
+#  Python API for SALOME %Mesh module
 
 ## @defgroup l1_auxiliary Auxiliary methods and structures
 ## @defgroup l1_creating  Creating meshes
@@ -256,7 +254,9 @@ def TreatHypoStatus(status, hypName, geomName, isAlgo):
 def AssureGeomPublished(mesh, geom, name=''):
     if not isinstance( geom, geompyDC.GEOM._objref_GEOM_Object ):
         return
-    if not geom.IsSame( mesh.geom ) and not geom.GetStudyEntry():
+    if not geom.IsSame( mesh.geom ) and \
+           not geom.GetStudyEntry() and \
+           mesh.smeshpyD.GetCurrentStudy():
         ## set the study
         studyID = mesh.smeshpyD.GetCurrentStudy()._get_StudyId()
         if studyID != mesh.geompyD.myStudyId:
@@ -443,6 +443,11 @@ class smeshDC(SMESH._objref_SMESH_Gen):
         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() )
 
     ## Gets the current study
     #  @ingroup l1_auxiliary
@@ -623,10 +628,12 @@ class smeshDC(SMESH._objref_SMESH_Gen):
 
         if CritType in [FT_BelongToGeom,     FT_BelongToPlane, FT_BelongToGenSurface,
                         FT_BelongToCylinder, FT_LyingOnGeom]:
-            # Checks the Threshold
+            # Checks that Threshold is GEOM object
             if isinstance(aThreshold, geompyDC.GEOM._objref_GEOM_Object):
                 aCriterion.ThresholdStr = GetName(aThreshold)
-                aCriterion.ThresholdID = salome.ObjectToID(aThreshold)
+                aCriterion.ThresholdID = aThreshold.GetStudyEntry()
+                if not aCriterion.ThresholdID:
+                    raise RuntimeError, "Threshold shape must be published"
             else:
                 print "Error: The Threshold should be a shape."
                 return None
@@ -635,7 +642,7 @@ class smeshDC(SMESH._objref_SMESH_Gen):
                 UnaryOp = FT_Undefined
                 pass
         elif CritType == FT_RangeOfIds:
-            # Checks the Threshold
+            # Checks that Threshold is string
             if isinstance(aThreshold, str):
                 aCriterion.ThresholdStr = aThreshold
             else:
@@ -644,7 +651,7 @@ class smeshDC(SMESH._objref_SMESH_Gen):
         elif CritType == FT_CoplanarFaces:
             # Checks the Threshold
             if isinstance(aThreshold, int):
-                aCriterion.ThresholdID = "%s"%aThreshold
+                aCriterion.ThresholdID = str(aThreshold)
             elif isinstance(aThreshold, str):
                 ID = int(aThreshold)
                 if ID < 1:
@@ -957,15 +964,17 @@ class Mesh:
         if obj is None:
             obj = 0
         if obj != 0:
+            objHasName = True
             if isinstance(obj, geompyDC.GEOM._objref_GEOM_Object):
                 self.geom = obj
                 # publish geom of mesh (issue 0021122)
-                if not self.geom.GetStudyEntry():
+                if not self.geom.GetStudyEntry() and smeshpyD.GetCurrentStudy():
+                    objHasName = False
                     studyID = smeshpyD.GetCurrentStudy()._get_StudyId()
                     if studyID != geompyD.myStudyId:
                         geompyD.init_geom( smeshpyD.GetCurrentStudy())
                         pass
-                    geo_name = "%s_%s"%(self.geom.GetShapeType(), id(self.geom)%100)
+                    geo_name = "%s_%s_for_meshing"%(self.geom.GetShapeType(), id(self.geom)%100)
                     geompyD.addToStudy( self.geom, geo_name )
                 self.mesh = self.smeshpyD.CreateMesh(self.geom)
 
@@ -975,7 +984,7 @@ class Mesh:
             self.mesh = self.smeshpyD.CreateEmptyMesh()
         if name != 0:
             self.smeshpyD.SetName(self.mesh, name)
-        elif obj != 0:
+        elif obj != 0 and objHasName:
             self.smeshpyD.SetName(self.mesh, GetName(obj))
 
         if not self.geom:
@@ -1174,7 +1183,7 @@ class Mesh:
                 if errText: errText += ". "
                 errText += err.comment
                 if allReasons != "":allReasons += "\n"
-                allReasons += '"%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
+                allReasons += '-  "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
                 pass
 
             # Treat hyp errors
@@ -1205,17 +1214,18 @@ class Mesh:
                              " Revise Mesh.Compute() implementation in smeshDC.py!"
                     pass
                 if allReasons != "":allReasons += "\n"
-                allReasons += reason
+                allReasons += "-  " + reason
                 pass
-            if allReasons != "":
-                print '"' + GetName(self.mesh) + '"',"has not been computed:"
+            if not ok or allReasons != "":
+                msg = '"' + GetName(self.mesh) + '"'
+                if ok: msg += " has been computed with warnings"
+                else:  msg += " has not been computed"
+                if allReasons != "": msg += ":"
+                else:                msg += "."
+                print msg
                 print allReasons
-                ok = False
-            elif not ok:
-                print '"' + GetName(self.mesh) + '"',"has not been computed."
-                pass
             pass
-        if salome.sg.hasDesktop():
+        if salome.sg.hasDesktop() and self.mesh.GetStudyId() >= 0:
             smeshgui = salome.ImportComponentGUI("SMESH")
             smeshgui.Init(self.mesh.GetStudyId())
             smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok, (self.NbNodes()==0) )
@@ -1304,6 +1314,7 @@ class Mesh:
             if not geom:
                 geom = self.mesh.GetShapeToMesh()
             pass
+        AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
         status = self.mesh.AddHypothesis(geom, hyp)
         isAlgo = hyp._narrow( SMESH_Algo )
         hyp_name = GetName( hyp )
@@ -1361,19 +1372,7 @@ class Mesh:
             pass
         pass
 
-    ## Deprecated, used only for compatibility! Please, use ExportToMEDX() method instead.
-    #  Exports 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
-    #  @param f the file name
-    #  @param version values are SMESH.MED_V2_1, SMESH.MED_V2_2
-    #  @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
-    #  @ingroup l2_impexp
-    def ExportToMED(self, f, version, opt=0, overwrite=1):
-        self.mesh.ExportToMEDX(f, opt, version, overwrite)
-
-    ## Exports the mesh in a file in MED format and chooses the \a version of MED format
+   ## Exports 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
     #  @param f is the file name
     #  @param auto_groups boolean parameter for creating/not creating
@@ -1451,6 +1450,18 @@ class Mesh:
             meshPart = self.mesh
         self.mesh.ExportCGNS(meshPart, f, overwrite)
 
+    ## Deprecated, used only for compatibility! Please, use ExportToMEDX() method instead.
+    #  Exports 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
+    #  @param f the file name
+    #  @param version values are SMESH.MED_V2_1, SMESH.MED_V2_2
+    #  @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
+    #  @ingroup l2_impexp
+    def ExportToMED(self, f, version, opt=0, overwrite=1):
+        self.mesh.ExportToMEDX(f, opt, version, overwrite)
+
     # Operations with groups:
     # ----------------------
 
@@ -1595,26 +1606,6 @@ class Mesh:
         group.AddFrom( theFilter )
         return group
 
-    ## Passes mesh elements through the given filter and return IDs of fitting elements
-    #  @param theFilter SMESH_Filter
-    #  @return a list of ids
-    #  @ingroup l1_controls
-    def GetIdsFromFilter(self, theFilter):
-        theFilter.SetMesh( self.mesh )
-        return theFilter.GetIDs()
-
-    ## Verifies whether a 2D mesh element has free edges (edges connected to one face only)\n
-    #  Returns a list of special structures (borders).
-    #  @return a list of SMESH.FreeEdges.Border structure: edge id and ids of two its nodes.
-    #  @ingroup l1_controls
-    def GetFreeBorders(self):
-        aFilterMgr = self.smeshpyD.CreateFilterManager()
-        aPredicate = aFilterMgr.CreateFreeEdges()
-        aPredicate.SetMesh(self.mesh)
-        aBorders = aPredicate.GetBorders()
-        aFilterMgr.UnRegister()
-        return aBorders
-
     ## Removes a group
     #  @ingroup l2_grps_delete
     def RemoveGroup(self, group):
@@ -1769,7 +1760,7 @@ class Mesh:
         return self.mesh.GetMeshEditor()
 
     ## Wrap a list of IDs of elements or nodes into SMESH_IDSource which
-    #  can be passed as argument to accepting mesh, group or sub-mesh
+    #  can be passed as argument to a method accepting mesh, group or sub-mesh
     #  @return an instance of SMESH_IDSource
     #  @ingroup l1_auxiliary
     def GetIDSource(self, ids, elemType):
@@ -1810,6 +1801,12 @@ class Mesh:
     def Nb0DElements(self):
         return self.mesh.Nb0DElements()
 
+    ## Returns the number of ball discrete elements in the mesh
+    #  @return an integer value
+    #  @ingroup l1_meshinfo
+    def NbBalls(self):
+        return self.mesh.NbBalls()
+
     ## Returns the number of edges in the mesh
     #  @return an integer value
     #  @ingroup l1_meshinfo
@@ -2026,7 +2023,7 @@ class Mesh:
     #  @ingroup l1_meshinfo
     def GetSubMeshNodesId(self, Shape, all):
         if ( isinstance( Shape, geompyDC.GEOM._objref_GEOM_Object)):
-            ShapeID = Shape.GetSubShapeIndices()[0]
+            ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
         else:
             ShapeID = Shape
         return self.mesh.GetSubMeshNodesId(ShapeID, all)
@@ -2149,6 +2146,11 @@ class Mesh:
     def IsQuadratic(self, id):
         return self.mesh.IsQuadratic(id)
 
+    ## Returns diameter of a ball discrete element or zero in case of an invalid \a id
+    #  @ingroup l1_meshinfo
+    def GetBallDiameter(self, id):
+        return self.mesh.GetBallDiameter(id)
+
     ## Returns XYZ coordinates of the barycenter of the given element
     #  \n If there is no element for the given ID - returns an empty list
     #  @return a list of three double values
@@ -2156,6 +2158,26 @@ class Mesh:
     def BaryCenter(self, id):
         return self.mesh.BaryCenter(id)
 
+    ## Passes mesh elements through the given filter and return IDs of fitting elements
+    #  @param theFilter SMESH_Filter
+    #  @return a list of ids
+    #  @ingroup l1_controls
+    def GetIdsFromFilter(self, theFilter):
+        theFilter.SetMesh( self.mesh )
+        return theFilter.GetIDs()
+
+    ## Verifies whether a 2D mesh element has free edges (edges connected to one face only)\n
+    #  Returns a list of special structures (borders).
+    #  @return a list of SMESH.FreeEdges.Border structure: edge id and ids of two its nodes.
+    #  @ingroup l1_controls
+    def GetFreeBorders(self):
+        aFilterMgr = self.smeshpyD.CreateFilterManager()
+        aPredicate = aFilterMgr.CreateFreeEdges()
+        aPredicate.SetMesh(self.mesh)
+        aBorders = aPredicate.GetBorders()
+        aFilterMgr.UnRegister()
+        return aBorders
+
 
     # Get mesh measurements information:
     # ------------------------------------
@@ -2284,6 +2306,14 @@ class Mesh:
     def Add0DElement(self, IDOfNode):
         return self.editor.Add0DElement(IDOfNode)
 
+    ## Creates a ball element on a node with given ID.
+    #  @param IDOfNode the ID of node for creation of the element.
+    #  @param diameter the bal diameter.
+    #  @return the Id of the new ball element
+    #  @ingroup l2_modif_add
+    def AddBall(self, IDOfNode, diameter):
+        return self.editor.AddBall( IDOfNode, diameter )
+
     ## Creates a linear or quadratic edge (this is determined
     #  by the number of given nodes).
     #  @param IDsOfNodes the list of node IDs for creation of the element.
@@ -2470,7 +2500,7 @@ class Mesh:
     #  @param y  the Y coordinate of a point
     #  @param z  the Z coordinate of a point
     #  @param elementType type of elements to find (SMESH.ALL type
-    #         means elements of any type excluding nodes and 0D elements)
+    #         means elements of any type excluding nodes, discrete and 0D elements)
     #  @param meshPart a part of mesh (group, sub-mesh) to search within
     #  @return list of IDs of found elements
     #  @ingroup l2_modif_throughp
@@ -2480,7 +2510,8 @@ class Mesh:
         else:
             return self.editor.FindElementsByPoint(x, y, z, elementType)
 
-    # Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
+    # Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
+    # 0-IN, 1-OUT, 2-ON, 3-UNKNOWN
     # TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
 
     def GetPointState(self, x, y, z):
@@ -2531,6 +2562,41 @@ class Mesh:
             theObject = theObject.GetMesh()
         return self.editor.ReorientObject(theObject)
 
+    ## Reorient faces contained in \a the2DObject.
+    #  @param the2DObject is a mesh, sub-mesh, group or list of IDs of 2D elements
+    #  @param theDirection is a desired direction of normal of \a theFace.
+    #         It can be either a GEOM vector or a list of coordinates [x,y,z].
+    #  @param theFaceOrPoint defines a face of \a the2DObject whose normal will be
+    #         compared with theDirection. It can be either ID of face or a point
+    #         by which the face will be found. The point can be given as either
+    #         a GEOM vertex or a list of point coordinates.
+    #  @return number of reoriented faces
+    #  @ingroup l2_modif_changori
+    def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
+        # check the2DObject
+        if isinstance( the2DObject, Mesh ):
+            the2DObject = the2DObject.GetMesh()
+        if isinstance( the2DObject, list ):
+            the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
+        # check theDirection
+        if isinstance( theDirection, geompyDC.GEOM._objref_GEOM_Object):
+            theDirection = self.smeshpyD.GetDirStruct( theDirection )
+        if isinstance( theDirection, list ):
+            theDirection = self.smeshpyD.MakeDirStruct( *theDirection  )
+        # prepare theFace and thePoint
+        theFace = theFaceOrPoint
+        thePoint = PointStruct(0,0,0)
+        if isinstance( theFaceOrPoint, geompyDC.GEOM._objref_GEOM_Object):
+            thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
+            theFace = -1
+        if isinstance( theFaceOrPoint, list ):
+            thePoint = PointStruct( *theFaceOrPoint )
+            theFace = -1
+        if isinstance( theFaceOrPoint, PointStruct ):
+            thePoint = theFaceOrPoint
+            theFace = -1
+        return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
+
     ## Fuses the neighbouring triangles into quadrangles.
     #  @param IDsOfElements The triangles to be fused,
     #  @param theCriterion  is FT_...; used to choose a neighbour to fuse with.
@@ -3844,12 +3910,20 @@ class Mesh:
     #  @param theAffectedElems - group of elements to which the replicated nodes
     #         should be associated to.
     #  @param theMakeGroup forces the generation of a group containing new elements.
-    #  @return TRUE or a created group if operation has been completed successfully,
+    #  @param theMakeNodeGroup forces the generation of a group containing new nodes.
+    #  @return TRUE or created groups (one or two) if operation has been completed successfully,
     #          FALSE or None otherwise
     #  @ingroup l2_modif_edit
-    def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems, theMakeGroup=False):
-        if theMakeGroup:
-            return self.editor.DoubleNodeElemGroupNew(theElems, theNodesNot, theAffectedElems)
+    def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
+                             theMakeGroup=False, theMakeNodeGroup=False):
+        if theMakeGroup or theMakeNodeGroup:
+            twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
+                                                            theAffectedElems,
+                                                            theMakeGroup, theMakeNodeGroup)
+            if theMakeGroup and theMakeNodeGroup:
+                return twoGroups
+            else:
+                return twoGroups[ int(theMakeNodeGroup) ]
         return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
 
     ## Creates a hole in a mesh by doubling the nodes of some particular elements
@@ -3870,12 +3944,20 @@ class Mesh:
     #  @param theAffectedElems - group of elements to which the replicated nodes
     #         should be associated to.
     #  @param theMakeGroup forces the generation of a group containing new elements.
-    #  @return TRUE or a created group if operation has been completed successfully,
+    #  @param theMakeNodeGroup forces the generation of a group containing new nodes.
+    #  @return TRUE or created groups (one or two) if operation has been completed successfully,
     #          FALSE or None otherwise
     #  @ingroup l2_modif_edit
-    def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems, theMakeGroup=False):
-        if theMakeGroup:
-            return self.editor.DoubleNodeElemGroupsNew(theElems, theNodesNot, theAffectedElems)
+    def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
+                             theMakeGroup=False, theMakeNodeGroup=False):
+        if theMakeGroup or theMakeNodeGroup:
+            twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
+                                                             theAffectedElems,
+                                                             theMakeGroup, theMakeNodeGroup)
+            if theMakeGroup and theMakeNodeGroup:
+                return twoGroups
+            else:
+                return twoGroups[ int(theMakeNodeGroup) ]
         return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
 
     ## Creates a hole in a mesh by doubling the nodes of some particular elements
@@ -4064,6 +4146,7 @@ class Mesh_Algorithm:
     #  @return SMESH.SMESH_Algo
     def FindAlgorithm (self, algoname, smeshpyD):
         study = smeshpyD.GetCurrentStudy()
+        if not study: return None
         #to do: find component by smeshpyD object, not by its data type
         scomp = study.FindComponent(smeshpyD.ComponentDataType())
         if scomp is not None:
@@ -4202,15 +4285,10 @@ class Mesh_Algorithm:
 
     ## Returns entry of the shape to mesh in the study
     def MainShapeEntry(self):
-        entry = ""
-        if not self.mesh or not self.mesh.GetMesh(): return entry
-        if not self.mesh.GetMesh().HasShapeToMesh(): return entry
-        study = self.mesh.smeshpyD.GetCurrentStudy()
-        ior  = salome.orb.object_to_string( self.mesh.GetShape() )
-        sobj = study.FindObjectIOR(ior)
-        if sobj: entry = sobj.GetID()
-        if not entry: return ""
-        return entry
+        if not self.mesh or not self.mesh.GetMesh(): return ""
+        if not self.mesh.GetMesh().HasShapeToMesh(): return ""
+        shape = self.mesh.GetShape()
+        return shape.GetStudyEntry()
 
     ## Defines "ViscousLayers" hypothesis to give parameters of layers of prisms to build
     #  near mesh boundary. This hypothesis can be used by several 3D algorithms:
@@ -4235,7 +4313,7 @@ class Mesh_Algorithm:
         hyp.SetIgnoreFaces(ignoreFaces)
         return hyp
 
-    ## Transform a list of ether edges or tuples (edge 1st_vertex_of_edge)
+    ## Transform a list of ether edges or tuples (edge, 1st_vertex_of_edge)
     #  into a list acceptable to SetReversedEdges() of some 1D hypotheses
     #  @ingroup l3_hypos_1dhyps
     def ReversedEdgeIndices(self, reverseList):
@@ -4256,19 +4334,19 @@ class Mesh_Algorithm:
                 v = i[1]
                 if not isinstance( e, geompyDC.GEOM._objref_GEOM_Object ) or \
                    not isinstance( v, geompyDC.GEOM._objref_GEOM_Object ):
-                    raise TypeError, "A list item must be a tuple (edge 1st_vertex_of_edge)"
+                    raise TypeError, "A list item must be a tuple (edge, 1st_vertex_of_edge)"
                 if v.GetShapeType() == geompyDC.GEOM.EDGE and \
                    e.GetShapeType() == geompyDC.GEOM.VERTEX:
                     v,e = e,v
                 if e.GetShapeType() != geompyDC.GEOM.EDGE or \
                    v.GetShapeType() != geompyDC.GEOM.VERTEX:
-                    raise TypeError, "A list item must be a tuple (edge 1st_vertex_of_edge)"
+                    raise TypeError, "A list item must be a tuple (edge, 1st_vertex_of_edge)"
                 vFirst = FirstVertexOnCurve( e )
                 tol    = geompy.Tolerance( vFirst )[-1]
                 if geompy.MinDistance( v, vFirst ) > 1.5*tol:
                     resList.append( geompy.GetSubShapeID(self.mesh.geom, e ))
             else:
-                raise TypeError, "Item must be either an edge or tuple (edge 1st_vertex_of_edge)"
+                raise TypeError, "Item must be either an edge or tuple (edge, 1st_vertex_of_edge)"
         return resList