X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH_SWIG%2FsmeshDC.py;h=70f259314e26ea8065719b1c2cdd1b8ac32b081f;hb=refs%2Ftags%2FdistribGeom_06Mar13;hp=18b741cba6941e3e0e65414c809f11edcf561d64;hpb=7ab128efcdd7781f4d344c9ca69868a5d6e37a26;p=modules%2Fsmesh.git diff --git a/src/SMESH_SWIG/smeshDC.py b/src/SMESH_SWIG/smeshDC.py index 18b741cba..70f259314 100644 --- a/src/SMESH_SWIG/smeshDC.py +++ b/src/SMESH_SWIG/smeshDC.py @@ -16,11 +16,11 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -# File : smesh.py +# File : smeshDC.py # Author : Francis KLOSS, OCC # Module : SMESH -## @package smesh +## @package smeshDC # Python API for SALOME %Mesh module ## @defgroup l1_auxiliary Auxiliary methods and structures @@ -91,6 +91,7 @@ from smesh_algorithm import Mesh_Algorithm import SALOME import SALOMEDS +import os ## @addtogroup l1_auxiliary ## @{ @@ -186,7 +187,10 @@ def GetName(obj): if isinstance(obj, SALOMEDS._objref_SObject): # study object return obj.GetName() - ior = salome.orb.object_to_string(obj) + try: + ior = salome.orb.object_to_string(obj) + except: + ior = None if ior: # CORBA object studies = salome.myStudyManager.GetOpenStudies() @@ -255,8 +259,7 @@ 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() and \ + if not geom.GetStudyEntry() and \ mesh.smeshpyD.GetCurrentStudy(): ## set the study studyID = mesh.smeshpyD.GetCurrentStudy()._get_StudyId() @@ -272,17 +275,16 @@ def AssureGeomPublished(mesh, geom, name=''): mesh.geompyD.addToStudyInFather( mesh.geom, geom, name ) return -## Return the first vertex of a geomertical edge by ignoring orienation +## Return the first vertex of a geometrical edge by ignoring orientation def FirstVertexOnCurve(edge): - from geompy import SubShapeAll, ShapeType, KindOfShape, PointCoordinates - vv = SubShapeAll( edge, ShapeType["VERTEX"]) + vv = geompyDC.SubShapeAll( edge, geompyDC.ShapeType["VERTEX"]) if not vv: raise TypeError, "Given object has no vertices" if len( vv ) == 1: return vv[0] - info = KindOfShape(edge) + info = geompyDC.KindOfShape(edge) xyz = info[1:4] # coords of the first vertex - xyz1 = PointCoordinates( vv[0] ) - xyz2 = PointCoordinates( vv[1] ) + xyz1 = geompyDC.PointCoordinates( vv[0] ) + xyz2 = geompyDC.PointCoordinates( vv[1] ) dist1, dist2 = 0,0 for i in range(3): dist1 += abs( xyz[i] - xyz1[i] ) @@ -295,8 +297,53 @@ def FirstVertexOnCurve(edge): # end of l1_auxiliary ## @} -# All methods of this class are accessible directly from the smesh.py package. -class smeshDC(SMESH._objref_SMESH_Gen): + +# Warning: smeshInst is a singleton +smeshInst = None +engine = None +doLcc = False + +class smeshDC(object, SMESH._objref_SMESH_Gen): + + def __new__(cls): + global engine + global smeshInst + global doLcc + print "__new__", engine, smeshInst, doLcc + + if smeshInst is None: + # smesh engine is either retrieved from engine, or created + smeshInst = engine + # Following test avoids a recursive loop + if doLcc: + if smeshInst is not None: + # smesh engine not created: existing engine found + doLcc = False + if doLcc: + doLcc = False + # FindOrLoadComponent called: + # 1. CORBA resolution of server + # 2. the __new__ method is called again + print "smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc + smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" ) + else: + # FindOrLoadComponent not called + if smeshInst is None: + # smeshDC instance is created from lcc.FindOrLoadComponent + print "smeshInst = super(smeshDC,cls).__new__(cls) ", engine, smeshInst, doLcc + smeshInst = super(smeshDC,cls).__new__(cls) + else: + # smesh engine not created: existing engine found + print "existing ", engine, smeshInst, doLcc + pass + + return smeshInst + + return smeshInst + + def __init__(self): + print "__init__" + SMESH._objref_SMESH_Gen.__init__(self) ## Dump component to the Python script # This method overrides IDL function to allow default values for the parameters. @@ -315,7 +362,8 @@ class smeshDC(SMESH._objref_SMESH_Gen): ## Sets the current study and Geometry component # @ingroup l1_auxiliary - def init_smesh(self,theStudy,geompyD): + def init_smesh(self,theStudy,geompyD = None): + print "init_smesh" self.SetCurrentStudy(theStudy,geompyD) ## Creates an empty Mesh. This mesh can have an underlying geometry. @@ -330,7 +378,6 @@ class smeshDC(SMESH._objref_SMESH_Gen): return Mesh(self,self.geompyD,obj,name) ## Returns a long value from enumeration - # Should be used for SMESH.FunctorType enumeration # @ingroup l1_controls def EnumToLong(self,theItem): return theItem._v @@ -438,8 +485,8 @@ class smeshDC(SMESH._objref_SMESH_Gen): def SetCurrentStudy( self, theStudy, geompyD = None ): #self.SetCurrentStudy(theStudy) if not geompyD: - import geompy - geompyD = geompy.geom + import geompyDC + geompyD = geompyDC.geom pass self.geompyD=geompyD self.SetGeomEngine(geompyD) @@ -505,6 +552,16 @@ class smeshDC(SMESH._objref_SMESH_Gen): aMeshes.append(aMesh) return aMeshes, aStatus + ## Creates a Mesh object importing data from the given GMF file + # @return [ an instance of Mesh class, SMESH::ComputeError ] + # @ingroup l2_impexp + def CreateMeshesFromGMF( self, theFileName ): + aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self, + theFileName, + True) + if error.comment: print "*** CreateMeshesFromGMF() errors:\n", error.comment + return Mesh(self, self.geompyD, aSmeshMesh), error + ## Concatenate the given meshes into one mesh. # @return an instance of Mesh class # @param meshes the meshes to combine into one mesh @@ -512,8 +569,10 @@ class smeshDC(SMESH._objref_SMESH_Gen): # @param mergeNodesAndElements if true, equal nodes and elements aremerged # @param mergeTolerance tolerance for merging nodes # @param allGroups forces creation of groups of all elements + # @param name name of a new mesh def Concatenate( self, meshes, uniteIdenticalGroups, - mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False): + mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False, + name = ""): if not meshes: return None for i,m in enumerate(meshes): if isinstance(m, Mesh): @@ -526,7 +585,7 @@ class smeshDC(SMESH._objref_SMESH_Gen): else: aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate( self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance) - aMesh = Mesh(self, self.geompyD, aSmeshMesh) + aMesh = Mesh(self, self.geompyD, aSmeshMesh, name=name) return aMesh ## Create a mesh by copying a part of another mesh. @@ -632,9 +691,13 @@ class smeshDC(SMESH._objref_SMESH_Gen): # Checks that Threshold is GEOM object if isinstance(aThreshold, geompyDC.GEOM._objref_GEOM_Object): aCriterion.ThresholdStr = GetName(aThreshold) - aCriterion.ThresholdID = aThreshold.GetStudyEntry() + aCriterion.ThresholdID = aThreshold.GetStudyEntry() if not aCriterion.ThresholdID: - raise RuntimeError, "Threshold shape must be published" + name = aCriterion.ThresholdStr + if not name: + name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000) + aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name ) + #raise RuntimeError, "Threshold shape must be published" else: print "Error: The Threshold should be a shape." return None @@ -674,6 +737,20 @@ class smeshDC(SMESH._objref_SMESH_Gen): return None pass pass + elif CritType == FT_EntityType: + # Checks the Threshold + try: + aCriterion.Threshold = self.EnumToLong(aThreshold) + assert( aThreshold in SMESH.EntityType._items ) + except: + if isinstance(aThreshold, int): + aCriterion.Threshold = aThreshold + else: + print "Error: The Threshold should be an integer or SMESH.EntityType." + return None + pass + pass + elif CritType == FT_GroupColor: # Checks the Threshold try: @@ -760,37 +837,42 @@ class smeshDC(SMESH._objref_SMESH_Gen): # @return SMESH_NumericalFunctor # @ingroup l1_controls def GetFunctor(self,theCriterion): + if isinstance( theCriterion, SMESH._objref_NumericalFunctor ): + return theCriterion aFilterMgr = self.CreateFilterManager() + functor = None if theCriterion == FT_AspectRatio: - return aFilterMgr.CreateAspectRatio() + functor = aFilterMgr.CreateAspectRatio() elif theCriterion == FT_AspectRatio3D: - return aFilterMgr.CreateAspectRatio3D() + functor = aFilterMgr.CreateAspectRatio3D() elif theCriterion == FT_Warping: - return aFilterMgr.CreateWarping() + functor = aFilterMgr.CreateWarping() elif theCriterion == FT_MinimumAngle: - return aFilterMgr.CreateMinimumAngle() + functor = aFilterMgr.CreateMinimumAngle() elif theCriterion == FT_Taper: - return aFilterMgr.CreateTaper() + functor = aFilterMgr.CreateTaper() elif theCriterion == FT_Skew: - return aFilterMgr.CreateSkew() + functor = aFilterMgr.CreateSkew() elif theCriterion == FT_Area: - return aFilterMgr.CreateArea() + functor = aFilterMgr.CreateArea() elif theCriterion == FT_Volume3D: - return aFilterMgr.CreateVolume3D() + functor = aFilterMgr.CreateVolume3D() elif theCriterion == FT_MaxElementLength2D: - return aFilterMgr.CreateMaxElementLength2D() + functor = aFilterMgr.CreateMaxElementLength2D() elif theCriterion == FT_MaxElementLength3D: - return aFilterMgr.CreateMaxElementLength3D() + functor = aFilterMgr.CreateMaxElementLength3D() elif theCriterion == FT_MultiConnection: - return aFilterMgr.CreateMultiConnection() + functor = aFilterMgr.CreateMultiConnection() elif theCriterion == FT_MultiConnection2D: - return aFilterMgr.CreateMultiConnection2D() + functor = aFilterMgr.CreateMultiConnection2D() elif theCriterion == FT_Length: - return aFilterMgr.CreateLength() + functor = aFilterMgr.CreateLength() elif theCriterion == FT_Length2D: - return aFilterMgr.CreateLength2D() + functor = aFilterMgr.CreateLength2D() else: print "Error: given parameter is not numerical functor type." + aFilterMgr.UnRegister() + return functor ## Creates hypothesis # @param theHType mesh hypothesis type (string) @@ -936,6 +1018,19 @@ import omniORB omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshDC) +def smeshInstance( study, instance=None): + global engine + global smeshInst + global doLcc + engine = instance + if engine is None: + doLcc = True + smeshInst = smeshDC() + assert isinstance(smeshInst,smeshDC), "Smesh engine class is %s but should be smeshDC.smeshDC. Import smeshmapi before creating the instance."%smeshInst.__class__ + smeshInst.init_smesh(study) + return smeshInst + + # Public class: Mesh # ================== @@ -964,10 +1059,11 @@ class Mesh: self.geompyD=geompyD if obj is None: obj = 0 + objHasName = False if obj != 0: - objHasName = True if isinstance(obj, geompyDC.GEOM._objref_GEOM_Object): self.geom = obj + objHasName = True # publish geom of mesh (issue 0021122) if not self.geom.GetStudyEntry() and smeshpyD.GetCurrentStudy(): objHasName = False @@ -975,7 +1071,10 @@ class Mesh: if studyID != geompyD.myStudyId: geompyD.init_geom( smeshpyD.GetCurrentStudy()) pass - geo_name = "%s_%s_for_meshing"%(self.geom.GetShapeType(), id(self.geom)%100) + if name: + geo_name = name + " shape" + else: + geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100) geompyD.addToStudy( self.geom, geo_name ) self.mesh = self.smeshpyD.CreateMesh(self.geom) @@ -983,28 +1082,33 @@ class Mesh: self.SetMesh(obj) else: self.mesh = self.smeshpyD.CreateEmptyMesh() - if name != 0: + if name: self.smeshpyD.SetName(self.mesh, name) - elif obj != 0 and objHasName: - self.smeshpyD.SetName(self.mesh, GetName(obj)) + elif objHasName: + self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh" if not self.geom: self.geom = self.mesh.GetShapeToMesh() - self.editor = self.mesh.GetMeshEditor() + self.editor = self.mesh.GetMeshEditor() + self.functors = [None] * SMESH.FT_Undefined._v # set self to algoCreator's for attrName in dir(self): attr = getattr( self, attrName ) if isinstance( attr, algoCreator ): + print "algoCreator ", attrName setattr( self, attrName, attr.copy( self )) ## Initializes the Mesh object from an instance of SMESH_Mesh interface # @param theMesh a SMESH_Mesh object # @ingroup l2_construct def SetMesh(self, theMesh): + if self.mesh: self.mesh.UnRegister() self.mesh = theMesh - self.geom = self.mesh.GetShapeToMesh() + if self.mesh: + self.mesh.Register() + self.geom = self.mesh.GetShapeToMesh() ## Returns the mesh, that is an instance of SMESH_Mesh interface # @return a SMESH_Mesh object @@ -1078,19 +1182,25 @@ class Mesh: return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName ) ## Returns the mesh dimension depending on the dimension of the underlying shape + # or, if the mesh is not based on any shape, basing on deimension of elements # @return mesh dimension as an integer value [0,3] # @ingroup l1_auxiliary def MeshDimension(self): - shells = self.geompyD.SubShapeAllIDs( self.geom, geompyDC.ShapeType["SHELL"] ) - if len( shells ) > 0 : - return 3 - elif self.geompyD.NumberOfFaces( self.geom ) > 0 : - return 2 - elif self.geompyD.NumberOfEdges( self.geom ) > 0 : - return 1 + if self.mesh.HasShapeToMesh(): + shells = self.geompyD.SubShapeAllIDs( self.geom, geompyDC.ShapeType["SOLID"] ) + if len( shells ) > 0 : + return 3 + elif self.geompyD.NumberOfFaces( self.geom ) > 0 : + return 2 + elif self.geompyD.NumberOfEdges( self.geom ) > 0 : + return 1 + else: + return 0; else: - return 0; - pass + if self.NbVolumes() > 0: return 3 + if self.NbFaces() > 0: return 2 + if self.NbEdges() > 0: return 1 + return 0 ## Evaluates size of prospective mesh on a shape # @return a list where i-th element is a number of elements of i-th SMESH.EntityType @@ -1168,15 +1278,18 @@ class Mesh: except: shapeText = " on subshape #%s" % (err.subShapeID) errText = "" - stdErrors = ["OK", #COMPERR_OK - "Invalid input mesh", #COMPERR_BAD_INPUT_MESH - "std::exception", #COMPERR_STD_EXCEPTION - "OCC exception", #COMPERR_OCC_EXCEPTION - "SALOME exception", #COMPERR_SLM_EXCEPTION - "Unknown exception", #COMPERR_EXCEPTION + stdErrors = ["OK", #COMPERR_OK + "Invalid input mesh", #COMPERR_BAD_INPUT_MESH + "std::exception", #COMPERR_STD_EXCEPTION + "OCC exception", #COMPERR_OCC_EXCEPTION + "..", #COMPERR_SLM_EXCEPTION + "Unknown exception", #COMPERR_EXCEPTION "Memory allocation problem", #COMPERR_MEMORY_PB - "Algorithm failed", #COMPERR_ALGO_FAILED - "Unexpected geometry"]#COMPERR_BAD_SHAPE + "Algorithm failed", #COMPERR_ALGO_FAILED + "Unexpected geometry", #COMPERR_BAD_SHAPE + "Warning", #COMPERR_WARNING + "Computation cancelled",#COMPERR_CANCELED + "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE if err.code > 0: if err.code < len(stdErrors): errText = stdErrors[err.code] else: @@ -1210,9 +1323,13 @@ class Mesh: elif err.state == HYP_BAD_GEOMETRY: reason = ('%s %sD algorithm "%s" is assigned to mismatching' 'geometry' % ( glob, dim, name )) + elif err.state == HYP_HIDDEN_ALGO: + reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s ' + 'algorithm of upper dimension generating %sD mesh' + % ( glob, dim, name, glob, dim )) else: - reason = "For unknown reason."+\ - " Revise Mesh.Compute() implementation in smeshDC.py!" + reason = ("For unknown reason. " + "Developer, revise Mesh.Compute() implementation in smeshDC.py!") pass if allReasons != "":allReasons += "\n" allReasons += "- " + reason @@ -1250,7 +1367,8 @@ class Mesh: # @ingroup l2_construct def Clear(self): self.mesh.Clear() - if salome.sg.hasDesktop(): + if ( salome.sg.hasDesktop() and + salome.myStudyManager.GetStudyByID( self.mesh.GetStudyId() )): smeshgui = salome.ImportComponentGUI("SMESH") smeshgui.Init(self.mesh.GetStudyId()) smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True ) @@ -1331,7 +1449,7 @@ class Mesh: # @return True of False # @ingroup l2_hypotheses def IsUsedHypothesis(self, hyp, geom): - if not hyp or not geom: + if not hyp: # or not geom return False if isinstance( hyp, Mesh_Algorithm ): hyp = hyp.GetAlgorithm() @@ -1351,11 +1469,16 @@ class Mesh: if isinstance( hyp, Mesh_Algorithm ): hyp = hyp.GetAlgorithm() pass - if not geom: - geom = self.geom + shape = geom + if not shape: + shape = self.geom pass - status = self.mesh.RemoveHypothesis(geom, hyp) - return status + if self.IsUsedHypothesis( hyp, shape ): + return self.mesh.RemoveHypothesis( shape, hyp ) + hypName = GetName( hyp ) + geoName = GetName( shape ) + print "WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ) + return None ## Gets the list of hypotheses added on a geometry # @param geom a sub-shape of mesh geometry @@ -1451,6 +1574,19 @@ class Mesh: meshPart = self.mesh self.mesh.ExportCGNS(meshPart, f, overwrite) + ## Exports the mesh in a file in GMF format + # @param f is the file name + # @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh + # @ingroup l2_impexp + def ExportGMF(self, f, meshPart=None): + if isinstance( meshPart, list ): + meshPart = self.GetIDSource( meshPart, SMESH.ALL ) + if isinstance( meshPart, Mesh ): + meshPart = meshPart.mesh + elif not meshPart: + meshPart = self.mesh + self.mesh.ExportGMF(meshPart, f, True) + ## 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 @@ -1758,14 +1894,14 @@ class Mesh: # @return an instance of SMESH_MeshEditor # @ingroup l1_modifying def GetMeshEditor(self): - return self.mesh.GetMeshEditor() + return self.editor ## Wrap a list of IDs of elements or nodes into SMESH_IDSource which # 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): - return self.GetMeshEditor().MakeIDSource(ids, elemType) + return self.editor.MakeIDSource(ids, elemType) ## Gets MED Mesh # @return an instance of SALOME_MED::MESH @@ -2071,6 +2207,12 @@ class Mesh: def GetNodePosition(self,NodeID): return self.mesh.GetNodePosition(NodeID) + ## @brief Returns the position of an element on the shape + # @return SMESH::ElementPosition + # @ingroup l1_meshinfo + def GetElementPosition(self,ElemID): + return self.mesh.GetElementPosition(ElemID) + ## If the given element is a node, returns the ID of shape # \n If there is no node for the given ID - returns -1 # @return an integer value @@ -2093,7 +2235,7 @@ class Mesh: def GetElemNbNodes(self, id): return self.mesh.GetElemNbNodes(id) - ## Returns the node ID the given index for the given element + ## Returns the node ID the given (zero based) index for the given element # \n If there is no element for the given ID - returns -1 # \n If there is no node for the given index - returns -2 # @return an integer value @@ -2307,6 +2449,24 @@ class Mesh: def Add0DElement(self, IDOfNode): return self.editor.Add0DElement(IDOfNode) + ## Create 0D elements on all nodes of the given elements except those + # nodes on which a 0D element already exists. + # @param theObject an object on whose nodes 0D elements will be created. + # It can be mesh, sub-mesh, group, list of element IDs or a holder + # of nodes IDs created by calling mesh.GetIDSource( nodes, SMESH.NODE ) + # @param theGroupName optional name of a group to add 0D elements created + # and/or found on nodes of \a theObject. + # @return an object (a new group or a temporary SMESH_IDSource) holding + # IDs of new and/or found 0D elements. IDs of 0D elements + # can be retrieved from the returned object by calling GetIDs() + # @ingroup l2_modif_add + def Add0DElementsToAllNodes(self, theObject, theGroupName=""): + if isinstance( theObject, Mesh ): + theObject = theObject.GetMesh() + if isinstance( theObject, list ): + theObject = self.GetIDSource( theObject, SMESH.ALL ) + return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName ) + ## 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. @@ -2600,30 +2760,25 @@ class Mesh: ## 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. + # @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to + # choose a neighbour to fuse with. # @param MaxAngle is the maximum angle between element normals at which the fusion # is still performed; theMaxAngle is mesured in radians. # Also it could be a name of variable which defines angle in degrees. # @return TRUE in case of success, FALSE otherwise. # @ingroup l2_modif_unitetri def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle): - flag = False - if isinstance(MaxAngle,str): - flag = True MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle) self.mesh.SetParameters(Parameters) if not IDsOfElements: IDsOfElements = self.GetElementsId() - Functor = 0 - if ( isinstance( theCriterion, SMESH._objref_NumericalFunctor ) ): - Functor = theCriterion - else: - Functor = self.smeshpyD.GetFunctor(theCriterion) + Functor = self.smeshpyD.GetFunctor(theCriterion) return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle) ## Fuses the neighbouring triangles of the object into quadrangles # @param theObject is mesh, submesh or group - # @param theCriterion is FT_...; used to choose a neighbour to fuse with. + # @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to + # choose a neighbour to fuse with. # @param MaxAngle a max angle between element normals at which the fusion # is still performed; theMaxAngle is mesured in radians. # @return TRUE in case of success, FALSE otherwise. @@ -2631,29 +2786,42 @@ class Mesh: def TriToQuadObject (self, theObject, theCriterion, MaxAngle): MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle) self.mesh.SetParameters(Parameters) - if ( isinstance( theObject, Mesh )): + if isinstance( theObject, Mesh ): theObject = theObject.GetMesh() - return self.editor.TriToQuadObject(theObject, self.smeshpyD.GetFunctor(theCriterion), MaxAngle) + Functor = self.smeshpyD.GetFunctor(theCriterion) + return self.editor.TriToQuadObject(theObject, Functor, MaxAngle) ## Splits quadrangles into triangles. + # # @param IDsOfElements the faces to be splitted. - # @param theCriterion FT_...; used to choose a diagonal for splitting. + # @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 + # value, then quadrangles will be split by the smallest diagonal. # @return TRUE in case of success, FALSE otherwise. # @ingroup l2_modif_cutquadr - def QuadToTri (self, IDsOfElements, theCriterion): + def QuadToTri (self, IDsOfElements, theCriterion = None): if IDsOfElements == []: IDsOfElements = self.GetElementsId() - return self.editor.QuadToTri(IDsOfElements, self.smeshpyD.GetFunctor(theCriterion)) + if theCriterion is None: + theCriterion = FT_MaxElementLength2D + Functor = self.smeshpyD.GetFunctor(theCriterion) + return self.editor.QuadToTri(IDsOfElements, Functor) ## Splits quadrangles into triangles. - # @param theObject the object from which the list of elements is taken, this is mesh, submesh or group - # @param theCriterion FT_...; used to choose a diagonal for splitting. + # @param theObject the object from which the list of elements is taken, + # this is mesh, submesh or group + # @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 + # value, then quadrangles will be split by the smallest diagonal. # @return TRUE in case of success, FALSE otherwise. # @ingroup l2_modif_cutquadr - def QuadToTriObject (self, theObject, theCriterion): + def QuadToTriObject (self, theObject, theCriterion = None): if ( isinstance( theObject, Mesh )): theObject = theObject.GetMesh() - return self.editor.QuadToTriObject(theObject, self.smeshpyD.GetFunctor(theCriterion)) + if theCriterion is None: + theCriterion = FT_MaxElementLength2D + Functor = self.smeshpyD.GetFunctor(theCriterion) + return self.editor.QuadToTriObject(theObject, Functor) ## Splits quadrangles into triangles. # @param IDsOfElements the faces to be splitted @@ -2666,7 +2834,8 @@ class Mesh: return self.editor.SplitQuad(IDsOfElements, Diag13) ## Splits quadrangles into triangles. - # @param theObject the object from which the list of elements is taken, this is mesh, submesh or group + # @param theObject the object from which the list of elements is taken, + # this is mesh, submesh or group # @param Diag13 is used to choose a diagonal for splitting. # @return TRUE in case of success, FALSE otherwise. # @ingroup l2_modif_cutquadr @@ -2677,7 +2846,8 @@ class Mesh: ## Finds a better splitting of the given quadrangle. # @param IDOfQuad the ID of the quadrangle to be splitted. - # @param theCriterion FT_...; a criterion to choose a diagonal for splitting. + # @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to + # choose a diagonal for splitting. # @return 1 if 1-3 diagonal is better, 2 if 2-4 # diagonal is better, 0 if error occurs. # @ingroup l2_modif_cutquadr @@ -2906,19 +3076,23 @@ class Mesh: return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method) - ## Converts the mesh to quadratic, deletes old elements, replacing + ## Converts the mesh to quadratic or bi-quadratic, deletes old elements, replacing # them with quadratic with the same id. # @param theForce3d new node creation method: # 0 - the medium node lies at the geometrical entity from which the mesh element is built # 1 - the medium node lies at the middle of the line segments connecting start and end node of a mesh element # @param theSubMesh a group or a sub-mesh to convert; WARNING: in this case the mesh can become not conformal + # @param theToBiQuad If True, converts the mesh to bi-quadratic # @ingroup l2_modif_tofromqu - def ConvertToQuadratic(self, theForce3d, theSubMesh=None): - if theSubMesh: - self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh) + def ConvertToQuadratic(self, theForce3d, theSubMesh=None, theToBiQuad=False): + if theToBiQuad: + self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh) else: - self.editor.ConvertToQuadratic(theForce3d) - + if theSubMesh: + self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh) + else: + self.editor.ConvertToQuadratic(theForce3d) + ## Converts the mesh from quadratic to ordinary, # deletes old quadratic elements, \n replacing # them with ordinary mesh elements with the same id. @@ -3120,7 +3294,9 @@ class Mesh: ## Generates new elements by extrusion of the elements with given ids # @param IDsOfElements the list of elements ids for extrusion - # @param StepVector vector or DirStruct, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||) + # @param StepVector vector or DirStruct or 3 vector components, defining + # the direction and value of extrusion for one step (the total extrusion + # length will be NbOfSteps * ||StepVector||) # @param NbOfSteps the number of steps # @param MakeGroups forces the generation of new groups from existing ones # @param IsNodes is True if elements with given ids are nodes @@ -3129,8 +3305,10 @@ class Mesh: def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False): if IDsOfElements == []: IDsOfElements = self.GetElementsId() - if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)): + if isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object): StepVector = self.smeshpyD.GetDirStruct(StepVector) + if isinstance( StepVector, list ): + StepVector = self.smeshpyD.MakeDirStruct(*StepVector) NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps) Parameters = StepVector.PS.parameters + var_separator + Parameters self.mesh.SetParameters(Parameters) @@ -3147,7 +3325,9 @@ class Mesh: ## Generates new elements by extrusion of the elements with given ids # @param IDsOfElements is ids of elements - # @param StepVector vector, defining the direction and value of extrusion + # @param StepVector vector or DirStruct or 3 vector components, defining + # the direction and value of extrusion for one step (the total extrusion + # length will be NbOfSteps * ||StepVector||) # @param NbOfSteps the number of steps # @param ExtrFlags sets flags for extrusion # @param SewTolerance uses for comparing locations of nodes if flag @@ -3159,6 +3339,8 @@ class Mesh: ExtrFlags, SewTolerance, MakeGroups=False): if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)): StepVector = self.smeshpyD.GetDirStruct(StepVector) + if isinstance( StepVector, list ): + StepVector = self.smeshpyD.MakeDirStruct(*StepVector) if MakeGroups: return self.editor.AdvancedExtrusionMakeGroups(IDsOfElements, StepVector, NbOfSteps, ExtrFlags, SewTolerance) @@ -3169,7 +3351,9 @@ class Mesh: ## Generates new elements by extrusion of the elements which belong to the object # @param theObject the object which elements should be processed. # It can be a mesh, a sub mesh or a group. - # @param StepVector vector, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||) + # @param StepVector vector or DirStruct or 3 vector components, defining + # the direction and value of extrusion for one step (the total extrusion + # length will be NbOfSteps * ||StepVector||) # @param NbOfSteps the number of steps # @param MakeGroups forces the generation of new groups from existing ones # @param IsNodes is True if elements which belong to the object are nodes @@ -3180,6 +3364,8 @@ class Mesh: theObject = theObject.GetMesh() if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)): StepVector = self.smeshpyD.GetDirStruct(StepVector) + if isinstance( StepVector, list ): + StepVector = self.smeshpyD.MakeDirStruct(*StepVector) NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps) Parameters = StepVector.PS.parameters + var_separator + Parameters self.mesh.SetParameters(Parameters) @@ -3197,7 +3383,9 @@ class Mesh: ## Generates new elements by extrusion of the elements which belong to the object # @param theObject object which elements should be processed. # It can be a mesh, a sub mesh or a group. - # @param StepVector vector, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||) + # @param StepVector vector or DirStruct or 3 vector components, defining + # the direction and value of extrusion for one step (the total extrusion + # length will be NbOfSteps * ||StepVector||) # @param NbOfSteps the number of steps # @param MakeGroups to generate new groups from existing ones # @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise @@ -3207,6 +3395,8 @@ class Mesh: theObject = theObject.GetMesh() if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)): StepVector = self.smeshpyD.GetDirStruct(StepVector) + if isinstance( StepVector, list ): + StepVector = self.smeshpyD.MakeDirStruct(*StepVector) NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps) Parameters = StepVector.PS.parameters + var_separator + Parameters self.mesh.SetParameters(Parameters) @@ -3218,7 +3408,9 @@ class Mesh: ## Generates new elements by extrusion of the elements which belong to the object # @param theObject object which elements should be processed. # It can be a mesh, a sub mesh or a group. - # @param StepVector vector, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||) + # @param StepVector vector or DirStruct or 3 vector components, defining + # the direction and value of extrusion for one step (the total extrusion + # length will be NbOfSteps * ||StepVector||) # @param NbOfSteps the number of steps # @param MakeGroups forces the generation of new groups from existing ones # @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise @@ -3228,6 +3420,8 @@ class Mesh: theObject = theObject.GetMesh() if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)): StepVector = self.smeshpyD.GetDirStruct(StepVector) + if isinstance( StepVector, list ): + StepVector = self.smeshpyD.MakeDirStruct(*StepVector) NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps) Parameters = StepVector.PS.parameters + var_separator + Parameters self.mesh.SetParameters(Parameters) @@ -3614,6 +3808,10 @@ class Mesh: theObject = theObject.GetMesh() if ( isinstance( theObject, list )): theObject = self.GetIDSource(theObject, SMESH.ALL) + if ( isinstance( theScaleFact, float )): + theScaleFact = [theScaleFact] + if ( isinstance( theScaleFact, int )): + theScaleFact = [ float(theScaleFact)] self.mesh.SetParameters(thePoint.parameters) @@ -3634,6 +3832,10 @@ class Mesh: theObject = theObject.GetMesh() if ( isinstance( theObject, list )): theObject = self.GetIDSource(theObject,SMESH.ALL) + if ( isinstance( theScaleFact, float )): + theScaleFact = [theScaleFact] + if ( isinstance( theScaleFact, int )): + theScaleFact = [ float(theScaleFact)] self.mesh.SetParameters(thePoint.parameters) mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact, @@ -3973,6 +4175,18 @@ class Mesh: def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape): return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape) + ## Identify the elements that will be affected by node duplication (actual duplication is not performed. + # This method is the first step of DoubleNodeElemGroupsInRegion. + # @param theElems - list of groups of elements (edges or faces) to be replicated + # @param theNodesNot - list of groups of nodes not to replicated + # @param theShape - shape to detect affected elements (element which geometric center + # located on or inside shape). + # The replicated nodes should be associated to affected elements. + # @return groups of affected elements + # @ingroup l2_modif_edit + def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape): + return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape) + ## Double nodes on shared faces between groups of volumes and create flat elements on demand. # The list of groups must describe a partition of the mesh volumes. # The nodes of the internal faces at the boundaries of the groups are doubled. @@ -3993,10 +4207,22 @@ class Mesh: # @return TRUE if operation has been completed successfully, FALSE otherwise def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ): return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces ) + + ## identify all the elements around a geom shape, get the faces delimiting the hole + # + def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords): + return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords ) + + def _getFunctor(self, funcType ): + fn = self.functors[ funcType._v ] + if not fn: + fn = self.smeshpyD.GetFunctor(funcType) + fn.SetMesh(self.mesh) + self.functors[ funcType._v ] = fn + return fn def _valueFromFunctor(self, funcType, elemId): - fn = self.smeshpyD.GetFunctor(funcType) - fn.SetMesh(self.mesh) + fn = self._getFunctor( funcType ) if fn.GetElementType() == self.GetElementType(elemId, True): val = fn.GetValue(elemId) else: @@ -4166,3 +4392,32 @@ class hypMethodWrapper: raise ValueError, detail # wrong variable name return result + +for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ): + # + print "pluginName: ", pluginName + pluginName += "DC" + try: + exec( "from %s import *" % pluginName ) + except Exception, e: + print "Exception while loading %s: %s" % ( pluginName, e ) + continue + exec( "import %s" % pluginName ) + plugin = eval( pluginName ) + print " plugin:" , str(plugin) + + # add methods creating algorithms to Mesh + for k in dir( plugin ): + if k[0] == '_': continue + algo = getattr( plugin, k ) + print " algo:", str(algo) + 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() ) + pass + getattr( Mesh, algo.meshMethod ).add( algo ) + pass + pass + pass +del pluginName