X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH_SWIG%2FsmeshBuilder.py;h=d1e2f3bb23584320f531ab0386672fb146f5d52f;hp=f2bbcaccc85618c7ab66d1124a8f8c405393f377;hb=refs%2Ftags%2FV9_0_0;hpb=51760fb76f57da9ab446585e6f87b101679c58cb diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index f2bbcaccc..d1e2f3bb2 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -84,12 +84,91 @@ import salome from salome.geom import geomBuilder import SMESH # This is necessary for back compatibility +import omniORB # back compatibility +SMESH.MED_V2_1 = omniORB.EnumItem("MED_V2_1", 0) # back compatibility +SMESH.MED_V2_2 = omniORB.EnumItem("MED_V2_2", 1) # back compatibility + from SMESH import * from salome.smesh.smesh_algorithm import Mesh_Algorithm import SALOME import SALOMEDS import os +import inspect + +# In case the omniORBpy EnumItem class does not fully support Python 3 +# (for instance in version 4.2.1-2), the comparison ordering methods must be +# defined +# +try: + SMESH.Entity_Triangle < SMESH.Entity_Quadrangle +except TypeError: + def enumitem_eq(self, other): + try: + if isinstance(other, omniORB.EnumItem): + if other._parent_id == self._parent_id: + return self._v == other._v + else: + return self._parent_id == other._parent_id + else: + return id(self) == id(other) + except: + return id(self) == id(other) + + def enumitem_lt(self, other): + try: + if isinstance(other, omniORB.EnumItem): + if other._parent_id == self._parent_id: + return self._v < other._v + else: + return self._parent_id < other._parent_id + else: + return id(self) < id(other) + except: + return id(self) < id(other) + + def enumitem_le(self, other): + try: + if isinstance(other, omniORB.EnumItem): + if other._parent_id == self._parent_id: + return self._v <= other._v + else: + return self._parent_id <= other._parent_id + else: + return id(self) <= id(other) + except: + return id(self) <= id(other) + + def enumitem_gt(self, other): + try: + if isinstance(other, omniORB.EnumItem): + if other._parent_id == self._parent_id: + return self._v > other._v + else: + return self._parent_id > other._parent_id + else: + return id(self) > id(other) + except: + return id(self) > id(other) + + def enumitem_ge(self, other): + try: + if isinstance(other, omniORB.EnumItem): + if other._parent_id == self._parent_id: + return self._v >= other._v + else: + return self._parent_id >= other._parent_id + else: + return id(self) >= id(other) + except: + return id(self) >= id(other) + + omniORB.EnumItem.__eq__ = enumitem_eq + omniORB.EnumItem.__lt__ = enumitem_lt + omniORB.EnumItem.__le__ = enumitem_le + omniORB.EnumItem.__gt__ = enumitem_gt + omniORB.EnumItem.__ge__ = enumitem_ge + ## Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False # @@ -123,7 +202,7 @@ def ParseParameters(*args): Parameters = "" hasVariables = False varModifFun=None - if args and callable( args[-1] ): + if args and callable(args[-1]): args, varModifFun = args[:-1], args[-1] for parameter in args: @@ -132,7 +211,7 @@ def ParseParameters(*args): if isinstance(parameter,str): # check if there is an inexistent variable name if not notebook.isVariable(parameter): - raise ValueError, "Variable with name '" + parameter + "' doesn't exist!!!" + raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!") parameter = notebook.get(parameter) hasVariables = True if varModifFun: @@ -162,8 +241,7 @@ SMESH.PointStruct.__init__ = __initPointStruct # Parameters are stored in AxisStruct.parameters attribute def __initAxisStruct(ax,*args): if len( args ) != 6: - raise RuntimeError,\ - "Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )) + raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args ))) ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args) pass SMESH.AxisStruct.__init__ = __initAxisStruct @@ -189,13 +267,8 @@ def GetName(obj): except: ior = None if ior: - # CORBA object - studies = salome.myStudyManager.GetOpenStudies() - for sname in studies: - s = salome.myStudyManager.GetStudyByName(sname) - if not s: continue - sobj = s.FindObjectIOR(ior) - if not sobj: continue + sobj = salome.myStudy.FindObjectIOR(ior) + if sobj: return sobj.GetName() if hasattr(obj, "GetName"): # unknown CORBA object, having GetName() method @@ -208,7 +281,7 @@ def GetName(obj): # unknown non-CORBA object, having GetName() method return obj.GetName() pass - raise RuntimeError, "Null or invalid object" + raise RuntimeError("Null or invalid object") ## Print error message if a hypothesis was not assigned. def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh): @@ -219,21 +292,21 @@ def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh): pass reason = "" if hasattr( status, "__getitem__" ): - status,reason = status[0],status[1] - if status == HYP_UNKNOWN_FATAL : + status, reason = status[0], status[1] + if status == HYP_UNKNOWN_FATAL: reason = "for unknown reason" - elif status == HYP_INCOMPATIBLE : + elif status == HYP_INCOMPATIBLE: reason = "this hypothesis mismatches the algorithm" - elif status == HYP_NOTCONFORM : + elif status == HYP_NOTCONFORM: reason = "a non-conform mesh would be built" - elif status == HYP_ALREADY_EXIST : + elif status == HYP_ALREADY_EXIST: if isAlgo: return # it does not influence anything reason = hypType + " of the same dimension is already assigned to this shape" - elif status == HYP_BAD_DIM : + elif status == HYP_BAD_DIM: reason = hypType + " mismatches the shape" - elif status == HYP_CONCURENT : + elif status == HYP_CONCURENT: reason = "there are concurrent hypotheses on sub-shapes" - elif status == HYP_BAD_SUBSHAPE : + elif status == HYP_BAD_SUBSHAPE: reason = "the shape is neither the main one, nor its sub-shape, nor a valid group" elif status == HYP_BAD_GEOMETRY: reason = "the algorithm is not applicable to this geometry" @@ -255,23 +328,18 @@ def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh): if meshName and meshName != NO_NAME: where = '"%s" shape in "%s" mesh ' % ( geomName, meshName ) if status < HYP_UNKNOWN_FATAL and where: - print '"%s" was assigned to %s but %s' %( hypName, where, reason ) + print('"%s" was assigned to %s but %s' %( hypName, where, reason )) elif where: - print '"%s" was not assigned to %s : %s' %( hypName, where, reason ) + print('"%s" was not assigned to %s : %s' %( hypName, where, reason )) else: - print '"%s" was not assigned : %s' %( hypName, reason ) + print('"%s" was not assigned : %s' %( hypName, reason )) pass ## Private method. Add geom (sub-shape of the main shape) into the study if not yet there def AssureGeomPublished(mesh, geom, name=''): if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ): return - if not geom.GetStudyEntry() and \ - mesh.smeshpyD.GetCurrentStudy(): - ## set the study - studyID = mesh.smeshpyD.GetCurrentStudy()._get_StudyId() - if studyID != mesh.geompyD.myStudyId: - mesh.geompyD.init_geom( mesh.smeshpyD.GetCurrentStudy()) + if not geom.GetStudyEntry(): ## get a name if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND: # for all groups SubShapeName() return "Compound_-1" @@ -286,7 +354,7 @@ def AssureGeomPublished(mesh, geom, name=''): def FirstVertexOnCurve(mesh, edge): vv = mesh.geompyD.SubShapeAll( edge, geomBuilder.geomBuilder.ShapeType["VERTEX"]) if not vv: - raise TypeError, "Given object has no vertices" + raise TypeError("Given object has no vertices") if len( vv ) == 1: return vv[0] v0 = mesh.geompyD.MakeVertexOnCurve(edge,0.) xyz = mesh.geompyD.PointCoordinates( v0 ) # coords of the first vertex @@ -301,6 +369,10 @@ def FirstVertexOnCurve(mesh, edge): else: return vv[1] +## Return a long value from enumeration +def EnumToLong(theItem): + return theItem._v + # end of l1_auxiliary ## @} @@ -314,7 +386,7 @@ created = False ## This class allows to create, load or manipulate meshes. # It has a set of methods to create, load or copy meshes, to combine several meshes, etc. # It also has methods to get infos and measure meshes. -class smeshBuilder(object, SMESH._objref_SMESH_Gen): +class smeshBuilder(SMESH._objref_SMESH_Gen): # MirrorType enumeration POINT = SMESH_MeshEditor.POINT @@ -328,12 +400,12 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): PrecisionConfusion = smeshPrecisionConfusion # TopAbs_State enumeration - [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = range(4) + [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4)) # Methods of splitting a hexahedron into tetrahedra Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2 - def __new__(cls): + def __new__(cls, *args): global engine global smeshInst global doLcc @@ -370,18 +442,18 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): #print "====2 ", smeshInst return smeshInst - def __init__(self): + def __init__(self, *args): global created #print "--------------- smeshbuilder __init__ ---", created if not created: - created = True - SMESH._objref_SMESH_Gen.__init__(self) + created = True + SMESH._objref_SMESH_Gen.__init__(self, *args) ## Dump component to the Python script # This method overrides IDL function to allow default values for the parameters. # @ingroup l1_auxiliary - def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True): - return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile) + def DumpPython(self, theIsPublished=True, theIsMultiFile=True): + return SMESH._objref_SMESH_Gen.DumpPython(self, theIsPublished, theIsMultiFile) ## Set mode of DumpPython(), \a historical or \a snapshot. # In the \a historical mode, the Python Dump script includes all commands @@ -394,14 +466,14 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): else: val = "false" SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val) - ## Set the current study and Geometry component + ## Set Geometry component # @ingroup l1_auxiliary - def init_smesh(self,theStudy,geompyD = None): + def init_smesh(self,isPublished = True,geompyD = None): #print "init_smesh" - self.SetCurrentStudy(theStudy,geompyD) - if theStudy: + self.UpdateStudy(geompyD) + if isPublished: global notebook - notebook.myStudy = theStudy + notebook.myStudy = salome.myStudy ## Create a mesh. This can be either an empty mesh, possibly having an underlying geometry, # or a mesh wrapping a CORBA mesh given as a parameter. @@ -417,11 +489,6 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): obj,name = name,obj return Mesh(self,self.geompyD,obj,name) - ## Return a long value from enumeration - # @ingroup l1_auxiliary - def EnumToLong(self,theItem): - return theItem._v - ## Return a string representation of the color. # To be used with filters. # @param c color value (SALOMEDS.Color) @@ -433,7 +500,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): elif isinstance(c, str): val = c else: - raise ValueError, "Color value should be of string or SALOMEDS.Color type" + raise ValueError("Color value should be of string or SALOMEDS.Color type") return val ## Get PointStruct from vertex @@ -451,7 +518,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): def GetDirStruct(self,theVector): vertices = self.geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] ) if(len(vertices) != 2): - print "Error: vector object is incorrect." + print("Error: vector object is incorrect.") return None p1 = self.geompyD.PointCoordinates(vertices[0]) p2 = self.geompyD.PointCoordinates(vertices[1]) @@ -523,34 +590,32 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): # @ingroup l1_auxiliary def IsEmbeddedMode(self): return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self) - - ## Set the current study. Calling SetCurrentStudy( None ) allows to - # switch OFF automatic pubilishing in the Study of mesh objects. + + ## Update the current study. Calling UpdateStudy() allows to + # update meshes at switching GEOM->SMESH # @ingroup l1_auxiliary - def SetCurrentStudy( self, theStudy, geompyD = None ): + def UpdateStudy( self, geompyD = None ): + #self.UpdateStudy() if not geompyD: from salome.geom import geomBuilder geompyD = geomBuilder.geom pass 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() ) - if theStudy: - sb = theStudy.NewBuilder() - sc = theStudy.FindComponent("SMESH") - if sc: sb.LoadWith(sc, self) - pass + SMESH._objref_SMESH_Gen.UpdateStudy(self) + sb = salome.myStudy.NewBuilder() + sc = salome.myStudy.FindComponent("SMESH") + if sc: sb.LoadWith(sc, self) pass - - ## Get the current study + + ## Sets enable publishing in the study. Calling SetEnablePublish( false ) allows to + # switch OFF publishing in the Study of mesh objects. # @ingroup l1_auxiliary - def GetCurrentStudy(self): - return SMESH._objref_SMESH_Gen.GetCurrentStudy(self) + def SetEnablePublish( self, theIsEnablePublish ): + #self.SetEnablePublish(theIsEnablePublish) + SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish) + global notebook + notebook = salome_notebook.NoteBook( theIsEnablePublish ) ## Create a Mesh object importing data from the given UNV file # @return an instance of Mesh class @@ -601,7 +666,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self, theFileName, True) - if error.comment: print "*** CreateMeshesFromGMF() errors:\n", error.comment + if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment) return Mesh(self, self.geompyD, aSmeshMesh), error ## Concatenate the given meshes into one mesh. All groups of input meshes will be @@ -653,7 +718,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): def GetSubShapesId( self, theMainObject, theListOfSubObjects ): return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects) - ## Create a pattern mapper. + ## Create a pattern mapper. # @return an instance of SMESH_Pattern # # Example of Patterns usage @@ -675,13 +740,13 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): # @return SMESH.Filter.Criterion # @ingroup l1_controls def GetEmptyCriterion(self): - Type = self.EnumToLong(FT_Undefined) - Compare = self.EnumToLong(FT_Undefined) + Type = EnumToLong(FT_Undefined) + Compare = EnumToLong(FT_Undefined) Threshold = 0 ThresholdStr = "" ThresholdID = "" - UnaryOp = self.EnumToLong(FT_Undefined) - BinaryOp = self.EnumToLong(FT_Undefined) + UnaryOp = EnumToLong(FT_Undefined) + BinaryOp = EnumToLong(FT_Undefined) Tolerance = 1e-07 TypeOfElement = ALL Precision = -1 ##@1e-07 @@ -713,24 +778,24 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): BinaryOp=FT_Undefined, Tolerance=1e-07): if not CritType in SMESH.FunctorType._items: - raise TypeError, "CritType should be of SMESH.FunctorType" + raise TypeError("CritType should be of SMESH.FunctorType") aCriterion = self.GetEmptyCriterion() aCriterion.TypeOfElement = elementType - aCriterion.Type = self.EnumToLong(CritType) + aCriterion.Type = EnumToLong(CritType) aCriterion.Tolerance = Tolerance aThreshold = Threshold if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]: - aCriterion.Compare = self.EnumToLong(Compare) + aCriterion.Compare = EnumToLong(Compare) elif Compare == "=" or Compare == "==": - aCriterion.Compare = self.EnumToLong(FT_EqualTo) + aCriterion.Compare = EnumToLong(FT_EqualTo) elif Compare == "<": - aCriterion.Compare = self.EnumToLong(FT_LessThan) + aCriterion.Compare = EnumToLong(FT_LessThan) elif Compare == ">": - aCriterion.Compare = self.EnumToLong(FT_MoreThan) + aCriterion.Compare = EnumToLong(FT_MoreThan) elif Compare != FT_Undefined: - aCriterion.Compare = self.EnumToLong(FT_EqualTo) + aCriterion.Compare = EnumToLong(FT_EqualTo) aThreshold = Compare if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface, @@ -748,7 +813,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): elif isinstance( aThreshold, str ): aCriterion.ThresholdStr = aThreshold else: - raise TypeError, "The Threshold should be a shape." + raise TypeError("The Threshold should be a shape.") if isinstance(UnaryOp,float): aCriterion.Tolerance = UnaryOp UnaryOp = FT_Undefined @@ -757,10 +822,10 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): # Check that Threshold is a group if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase): if aThreshold.GetType() != elementType: - raise ValueError, "Group type mismatches Element type" + raise ValueError("Group type mismatches Element type") aCriterion.ThresholdStr = aThreshold.GetName() aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold ) - study = self.GetCurrentStudy() + study = salome.myStudy if study: so = study.FindObjectIOR( aCriterion.ThresholdID ) if so: @@ -768,13 +833,13 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): if entry: aCriterion.ThresholdID = entry else: - raise TypeError, "The Threshold should be a Mesh Group" + raise TypeError("The Threshold should be a Mesh Group") elif CritType == FT_RangeOfIds: # Check that Threshold is string if isinstance(aThreshold, str): aCriterion.ThresholdStr = aThreshold else: - raise TypeError, "The Threshold should be a string." + raise TypeError("The Threshold should be a string.") elif CritType == FT_CoplanarFaces: # Check the Threshold if isinstance(aThreshold, int): @@ -782,11 +847,10 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): elif isinstance(aThreshold, str): ID = int(aThreshold) if ID < 1: - raise ValueError, "Invalid ID of mesh face: '%s'"%aThreshold + raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold) aCriterion.ThresholdID = aThreshold else: - raise TypeError,\ - "The Threshold should be an ID of mesh face and not '%s'"%aThreshold + raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold) elif CritType == FT_ConnectedElements: # Check the Threshold if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape @@ -800,7 +864,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): aCriterion.Threshold = aThreshold elif isinstance(aThreshold, list): # 3 point coordinates if len( aThreshold ) < 3: - raise ValueError, "too few point coordinates, must be 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(): @@ -808,40 +872,39 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): else: aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates else: - raise TypeError,\ - "The Threshold should either a VERTEX, or a node ID, "\ - "or a list of point coordinates and not '%s'"%aThreshold + raise TypeError("The Threshold should either a VERTEX, or a node ID, "\ + "or a list of point coordinates and not '%s'"%aThreshold) elif CritType == FT_ElemGeomType: # Check the Threshold try: - aCriterion.Threshold = self.EnumToLong(aThreshold) + aCriterion.Threshold = EnumToLong(aThreshold) assert( aThreshold in SMESH.GeometryType._items ) except: if isinstance(aThreshold, int): aCriterion.Threshold = aThreshold else: - raise TypeError, "The Threshold should be an integer or SMESH.GeometryType." + raise TypeError("The Threshold should be an integer or SMESH.GeometryType.") pass pass elif CritType == FT_EntityType: # Check the Threshold try: - aCriterion.Threshold = self.EnumToLong(aThreshold) + aCriterion.Threshold = EnumToLong(aThreshold) assert( aThreshold in SMESH.EntityType._items ) except: if isinstance(aThreshold, int): aCriterion.Threshold = aThreshold else: - raise TypeError, "The Threshold should be an integer or SMESH.EntityType." + raise TypeError("The Threshold should be an integer or SMESH.EntityType.") pass pass - + elif CritType == FT_GroupColor: # Check the Threshold try: aCriterion.ThresholdStr = self.ColorToString(aThreshold) except: - raise TypeError, "The threshold value should be of SALOMEDS.Color type" + raise TypeError("The threshold value should be of SALOMEDS.Color type") pass elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces, FT_LinearOrQuadratic, FT_BadOrientedVolume, @@ -850,7 +913,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]: # At this point the Threshold is unnecessary if aThreshold == FT_LogicalNOT: - aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT) + aCriterion.UnaryOp = EnumToLong(FT_LogicalNOT) elif aThreshold in [FT_LogicalAND, FT_LogicalOR]: aCriterion.BinaryOp = aThreshold else: @@ -859,20 +922,20 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): aThreshold = float(aThreshold) aCriterion.Threshold = aThreshold except: - raise TypeError, "The Threshold should be a number." + raise TypeError("The Threshold should be a number.") return None if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT: - aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT) + aCriterion.UnaryOp = EnumToLong(FT_LogicalNOT) if Threshold in [FT_LogicalAND, FT_LogicalOR]: - aCriterion.BinaryOp = self.EnumToLong(Threshold) + aCriterion.BinaryOp = EnumToLong(Threshold) if UnaryOp in [FT_LogicalAND, FT_LogicalOR]: - aCriterion.BinaryOp = self.EnumToLong(UnaryOp) + aCriterion.BinaryOp = EnumToLong(UnaryOp) if BinaryOp in [FT_LogicalAND, FT_LogicalOR]: - aCriterion.BinaryOp = self.EnumToLong(BinaryOp) + aCriterion.BinaryOp = EnumToLong(BinaryOp) return aCriterion @@ -919,8 +982,8 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): # @ingroup l1_controls def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND): for i in range( len( criteria ) - 1 ): - if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ): - criteria[i].BinaryOp = self.EnumToLong( binOp ) + if criteria[i].BinaryOp == EnumToLong( SMESH.FT_Undefined ): + criteria[i].BinaryOp = EnumToLong( binOp ) aFilterMgr = self.CreateFilterManager() aFilter = aFilterMgr.CreateFilter() aFilter.SetCriteria(criteria) @@ -966,12 +1029,14 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): functor = aFilterMgr.CreateLength() elif theCriterion == FT_Length2D: functor = aFilterMgr.CreateLength2D() + elif theCriterion == FT_Deflection2D: + functor = aFilterMgr.CreateDeflection2D() elif theCriterion == FT_NodeConnectivityNumber: functor = aFilterMgr.CreateNodeConnectivityNumber() elif theCriterion == FT_BallDiameter: functor = aFilterMgr.CreateBallDiameter() else: - print "Error: given parameter is not numerical functor type." + print("Error: given parameter is not numerical functor type.") aFilterMgr.UnRegister() return functor @@ -1005,7 +1070,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): d = {} if hasattr(obj, "GetMeshInfo"): values = obj.GetMeshInfo() - for i in range(SMESH.Entity_Last._v): + for i in range(EnumToLong(SMESH.Entity_Last)): if i < len(values): d[SMESH.EntityType._item(i)]=values[i] pass return d @@ -1153,6 +1218,18 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): aMeasurements.UnRegister() return value + ## Get gravity center of all nodes of the mesh object. + # @param obj mesh, submesh or group + # @return three components of the gravity center: x,y,z + # @ingroup l1_measurements + def GetGravityCenter(self, obj): + if isinstance(obj, Mesh): obj = obj.mesh + if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh() + aMeasurements = self.CreateMeasurements() + pointStruct = aMeasurements.GravityCenter(obj) + aMeasurements.UnRegister() + return pointStruct.x, pointStruct.y, pointStruct.z + pass # end of class smeshBuilder import omniORB @@ -1167,13 +1244,13 @@ omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder) # import salome # salome.salome_init() # from salome.smesh import smeshBuilder -# smesh = smeshBuilder.New(salome.myStudy) +# smesh = smeshBuilder.New() # \endcode -# @param study SALOME study, generally obtained by salome.myStudy. +# @param isPublished If False, the notebool will not be used. # @param instance CORBA proxy of SMESH Engine. If None, the default Engine is used. # @return smeshBuilder instance -def New( study, instance=None): +def New( isPublished = True, instance=None): """ Create a new smeshBuilder instance.The smeshBuilder class provides the Python interface to create or load meshes. @@ -1182,10 +1259,10 @@ def New( study, instance=None): import salome salome.salome_init() from salome.smesh import smeshBuilder - smesh = smeshBuilder.New(salome.myStudy) + smesh = smeshBuilder.New() Parameters: - study SALOME study, generally obtained by salome.myStudy. + isPublished If False, the notebool will not be used. instance CORBA proxy of SMESH Engine. If None, the default Engine is used. Returns: smeshBuilder instance @@ -1195,10 +1272,10 @@ def New( study, instance=None): global doLcc engine = instance if engine is None: - doLcc = True + doLcc = True smeshInst = smeshBuilder() assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__ - smeshInst.init_smesh(study) + smeshInst.init_smesh(isPublished) return smeshInst @@ -1210,9 +1287,7 @@ def New( study, instance=None): # It also has methods to define groups of mesh elements, to modify a mesh (by addition of # new nodes and elements and by changing the existing entities), to get information # about a mesh and to export a mesh in different formats. -class Mesh: - __metaclass__ = MeshMeta - +class Mesh(metaclass=MeshMeta): geom = 0 mesh = 0 editor = 0 @@ -1227,8 +1302,8 @@ class Mesh: # @param name Study name of the mesh # @ingroup l2_construct def __init__(self, smeshpyD, geompyD, obj=0, name=0): - self.smeshpyD=smeshpyD - self.geompyD=geompyD + self.smeshpyD = smeshpyD + self.geompyD = geompyD if obj is None: obj = 0 objHasName = False @@ -1237,12 +1312,9 @@ class Mesh: self.geom = obj objHasName = True # publish geom of mesh (issue 0021122) - if not self.geom.GetStudyEntry() and smeshpyD.GetCurrentStudy(): + if not self.geom.GetStudyEntry(): objHasName = False - studyID = smeshpyD.GetCurrentStudy()._get_StudyId() - if studyID != geompyD.myStudyId: - geompyD.init_geom( smeshpyD.GetCurrentStudy()) - pass + geompyD.init_geom() if name: geo_name = name + " shape" else: @@ -1263,7 +1335,7 @@ class Mesh: self.geom = self.mesh.GetShapeToMesh() self.editor = self.mesh.GetMeshEditor() - self.functors = [None] * SMESH.FT_Undefined._v + self.functors = [None] * EnumToLong(SMESH.FT_Undefined) # set self to algoCreator's for attrName in dir(self): @@ -1280,7 +1352,7 @@ class Mesh: #self.mesh.UnRegister() pass pass - + ## Initialize the Mesh object from an instance of SMESH_Mesh interface # @param theMesh a SMESH_Mesh object # @ingroup l2_construct @@ -1434,12 +1506,12 @@ class Mesh: if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693 self.mesh.Clear() ok = self.smeshpyD.Compute(self.mesh, geom) - except SALOME.SALOME_Exception, ex: - print "Mesh computation failed, exception caught:" - print " ", ex.details.text + except SALOME.SALOME_Exception as ex: + print("Mesh computation failed, exception caught:") + print(" ", ex.details.text) except: import traceback - print "Mesh computation failed, exception caught:" + print("Mesh computation failed, exception caught:") traceback.print_exc() if True:#not ok: allReasons = "" @@ -1516,15 +1588,15 @@ class Mesh: else: msg += " has not been computed" if allReasons != "": msg += ":" else: msg += "." - print msg - print allReasons + print(msg) + print(allReasons) pass - if salome.sg.hasDesktop() and self.mesh.GetStudyId() >= 0: + if salome.sg.hasDesktop(): if not isinstance( refresh, list): # not a call from subMesh.Compute() smeshgui = salome.ImportComponentGUI("SMESH") - smeshgui.Init(self.mesh.GetStudyId()) + smeshgui.Init() smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok, (self.NbNodes()==0) ) - if refresh: salome.sg.updateObjBrowser(True) + if refresh: salome.sg.updateObjBrowser() return ok @@ -1549,11 +1621,9 @@ class Mesh: try: shapeText = "" mainIOR = salome.orb.object_to_string( self.GetShape() ) - for sname in salome.myStudyManager.GetOpenStudies(): - s = salome.myStudyManager.GetStudyByName(sname) - if not s: continue - mainSO = s.FindObjectIOR(mainIOR) - if not mainSO: continue + s = salome.myStudy + mainSO = s.FindObjectIOR(mainIOR) + if mainSO: if subShapeID == 1: shapeText = '"%s"' % mainSO.GetName() subIt = s.NewChildIterator(mainSO) @@ -1570,7 +1640,6 @@ class Mesh: continue if ids == subShapeID: shapeText = '"%s"' % subSO.GetName() - break if not shapeText: shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID]) if shape: @@ -1600,9 +1669,9 @@ class Mesh: pass groups = [] - for algoName, shapes in algo2shapes.items(): + for algoName, shapes in list(algo2shapes.items()): while shapes: - groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() ) + groupType = EnumToLong( shapes[0].GetShapeType() ) otherTypeShapes = [] sameTypeShapes = [] group = self.geompyD.CreateGroup( self.geom, groupType ) @@ -1641,12 +1710,11 @@ class Mesh: # @ingroup l2_construct def Clear(self, refresh=False): self.mesh.Clear() - if ( salome.sg.hasDesktop() and - salome.myStudyManager.GetStudyByID( self.mesh.GetStudyId() ) ): + if ( salome.sg.hasDesktop() ): smeshgui = salome.ImportComponentGUI("SMESH") - smeshgui.Init(self.mesh.GetStudyId()) + smeshgui.Init() smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True ) - if refresh: salome.sg.updateObjBrowser(True) + if refresh: salome.sg.updateObjBrowser() ## Remove all nodes and elements of indicated shape # @param refresh if @c True, Object browser is automatically updated (when running in GUI) @@ -1656,9 +1724,9 @@ class Mesh: self.mesh.ClearSubMesh(geomId) if salome.sg.hasDesktop(): smeshgui = salome.ImportComponentGUI("SMESH") - smeshgui.Init(self.mesh.GetStudyId()) + smeshgui.Init() smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True ) - if refresh: salome.sg.updateObjBrowser(True) + if refresh: salome.sg.updateObjBrowser() ## Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron # @param fineness [0.0,1.0] defines mesh fineness @@ -1723,7 +1791,7 @@ class Mesh: AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName()) status = self.mesh.AddHypothesis(geom, hyp) else: - status = HYP_BAD_GEOMETRY,"" + status = HYP_BAD_GEOMETRY, "" hyp_name = GetName( hyp ) geom_name = "" if geom: @@ -1768,7 +1836,7 @@ class Mesh: 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 ) + print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName )) return None ## Get the list of hypotheses added on a geometry @@ -1789,18 +1857,10 @@ class Mesh: ## Export the mesh in a file in 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 fileName is the file name # @param auto_groups boolean parameter for creating/not creating # the groups Group_On_All_Nodes, Group_On_All_Faces, ... ; # the typical use is auto_groups=False. - # @param version MED format version - # - MED_V2_1 is obsolete. - # - MED_V2_2 means current version (kept for compatibility reasons) - # - MED_LATEST means current version. - # - MED_MINOR_x where x from 0 to 9 indicates the minor version of MED - # to use for writing MED files, for backward compatibility : - # for instance, with SALOME 8.4 use MED 3.2 (minor=2) instead of 3.3, - # to allow the file to be read with SALOME 8.3. # @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 @@ -1809,24 +1869,40 @@ class Mesh: # - 3D in the rest cases.
# If @a autoDimension is @c False, the space dimension is always 3. # @param fields list of GEOM fields defined on the shape to mesh. - # @param geomAssocFields each character of this string means a need to export a + # @param geomAssocFields each character of this string means a need to export a # corresponding field; correspondence between fields and characters is following: # - 'v' stands for "_vertices _" field; # - 'e' stands for "_edges _" field; # - 'f' stands for "_faces _" field; # - 's' stands for "_solids _" field. # @ingroup l2_impexp - def ExportMED(self, f, auto_groups=0, version=MED_LATEST, - overwrite=1, meshPart=None, autoDimension=True, fields=[], geomAssocFields=''): + def ExportMED(self, *args, **kwargs): + # process positional arguments + args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility + fileName = args[0] + auto_groups = args[1] if len(args) > 1 else False + overwrite = args[2] if len(args) > 2 else True + meshPart = args[3] if len(args) > 3 else None + autoDimension = args[4] if len(args) > 4 else True + fields = args[5] if len(args) > 5 else [] + geomAssocFields = args[6] if len(args) > 6 else '' + # process keywords arguments + auto_groups = kwargs.get("auto_groups", auto_groups) + overwrite = kwargs.get("overwrite", overwrite) + meshPart = kwargs.get("meshPart", meshPart) + autoDimension = kwargs.get("autoDimension", autoDimension) + fields = kwargs.get("fields", fields) + geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields) + # invoke engine's function if meshPart or fields or geomAssocFields: unRegister = genObjUnRegister() if isinstance( meshPart, list ): meshPart = self.GetIDSource( meshPart, SMESH.ALL ) unRegister.set( meshPart ) - self.mesh.ExportPartToMED( meshPart, f, auto_groups, version, overwrite, autoDimension, + self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, overwrite, autoDimension, fields, geomAssocFields) else: - self.mesh.ExportToMEDX(f, auto_groups, version, overwrite, autoDimension) + self.mesh.ExportMED(fileName, auto_groups, overwrite, autoDimension) ## Export the mesh in a file in SAUV format # @param f is the file name @@ -1919,15 +1995,36 @@ class Mesh: ## Deprecated, used only for compatibility! Please, use ExportMED() method instead. # Export the mesh in a file in 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 MED format version: - # - MED_V2_1 is obsolete. - # - MED_V2_2 means current version (kept for compatibility reasons) - # - MED_LATEST means current version. - # - MED_MINOR_x where x from 0 to 9 indicates the minor version of MED - # to use for writing MED files, for backward compatibility : - # for instance, with SALOME 8.4 use MED 3.2 (minor=2) instead of 3.3, - # to allow the file to be read with SALOME 8.3. + # @param fileName the file name + # @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 + # @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 ExportToMED(self, *args, **kwargs): + print("WARNING: ExportToMED() is deprecated, use ExportMED() instead") + # process positional arguments + args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility + fileName = args[0] + auto_groups = args[1] if len(args) > 1 else False + overwrite = args[2] if len(args) > 2 else True + autoDimension = args[3] if len(args) > 3 else True + # process keywords arguments + auto_groups = kwargs.get("opt", auto_groups) # old keyword name + auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name + overwrite = kwargs.get("overwrite", overwrite) + autoDimension = kwargs.get("autoDimension", autoDimension) + # invoke engine's function + self.mesh.ExportMED(fileName, auto_groups, overwrite, autoDimension) + + ## Deprecated, used only for compatibility! Please, use ExportMED() method instead. + # Export the mesh in a file in MED format + # allowing to overwrite the file if it exists or add the exported data to its contents + # @param fileName the file name # @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 @@ -1937,14 +2034,26 @@ class Mesh: # - 3D in the rest cases.
# If @a autoDimension is @c False, the space dimension is always 3. # @ingroup l2_impexp - def ExportToMED(self, f, version=MED_LATEST, opt=0, overwrite=1, autoDimension=True): - self.mesh.ExportToMEDX(f, opt, version, overwrite, autoDimension) + def ExportToMEDX(self, *args, **kwargs): + print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead") + # process positional arguments + args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility + fileName = args[0] + auto_groups = args[1] if len(args) > 1 else False + overwrite = args[2] if len(args) > 2 else True + autoDimension = args[3] if len(args) > 3 else True + # process keywords arguments + auto_groups = kwargs.get("auto_groups", auto_groups) + overwrite = kwargs.get("overwrite", overwrite) + autoDimension = kwargs.get("autoDimension", autoDimension) + # invoke engine's function + self.mesh.ExportMED(fileName, auto_groups, overwrite, autoDimension) # Operations with groups: # ---------------------- ## Create an empty mesh group - # @param elementType the type of elements in the group; either of + # @param elementType the type of elements in the group; either of # (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME) # @param name the name of the mesh group # @return SMESH_Group @@ -1968,7 +2077,7 @@ class Mesh: # the name is the same as the geometrical group name # @param grp a geometrical group, a vertex, an edge, a face or a solid # @param name the name of the mesh group - # @param typ the type of elements in the group; either of + # @param typ the type of elements in the group; either of # (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is # automatically detected by the type of the geometry # @return SMESH_GroupOnGeom @@ -1995,17 +2104,16 @@ class Mesh: elif tgeo == "COMPOUND": sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"]) if not sub: - raise ValueError,"_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape) + raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape)) return self._groupTypeFromShape( sub[0] ) else: - raise ValueError, \ - "_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape) + raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape)) return typ ## Create a mesh group with given \a name based on the \a filter which ## is a special type of group dynamically updating it's contents during ## mesh modification - # @param typ the type of elements in the group; either of + # @param typ the type of elements in the group; either of # (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). # @param name the name of the mesh group # @param filter the filter defining group contents @@ -2016,7 +2124,7 @@ class Mesh: ## Create a mesh group by the given ids of elements # @param groupName the name of the mesh group - # @param elementType the type of elements in the group; either of + # @param elementType the type of elements in the group; either of # (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). # @param elemIDs either the list of ids, group, sub-mesh, or filter # @return SMESH_Group @@ -2101,7 +2209,7 @@ class Mesh: ## Get the list of groups existing in the mesh in the order # of creation (starting from the oldest one) - # @param elemType type of elements the groups contain; either of + # @param elemType type of elements the groups contain; either of # (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME); # by default groups of elements of all types are returned # @return a sequence of SMESH_GroupBase @@ -2136,7 +2244,7 @@ class Mesh: ## Find groups by name and type # @param name name of the group of interest - # @param elemType type of elements the groups contain; either of + # @param elemType type of elements the groups contain; either of # (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME); # by default one group of any type of elements is returned # if elemType == SMESH.ALL then all groups of any type are returned @@ -2148,7 +2256,7 @@ class Mesh: if group.GetName() == name: if elemType is None: return [group] - if ( elemType == SMESH.ALL or + if ( elemType == SMESH.ALL or group.GetType() == elemType ): groups.append( group ) return groups @@ -2167,7 +2275,7 @@ class Mesh: # @return an instance of SMESH_Group # @ingroup l2_grps_operon def UnionListOfGroups(self, groups, name): - return self.mesh.UnionListOfGroups(groups, name) + return self.mesh.UnionListOfGroups(groups, name) ## Prodice an intersection of two groups. # A new group is created. All mesh elements that are common @@ -2183,7 +2291,7 @@ class Mesh: # @return an instance of SMESH_Group # @ingroup l2_grps_operon def IntersectListOfGroups(self, groups, name): - return self.mesh.IntersectListOfGroups(groups, name) + return self.mesh.IntersectListOfGroups(groups, name) ## Produce a cut of two groups. # A new group is created. All mesh elements that are present in @@ -2204,7 +2312,7 @@ class Mesh: ## # Create a standalone group of entities basing on nodes of other groups. # \param groups - list of reference groups, sub-meshes or filters, of any type. - # \param elemType - a type of elements to include to the new group; either of + # \param elemType - a type of elements to include to the new group; either of # (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). # \param name - a name of the new group. # \param nbCommonNodes - a criterion of inclusion of an element to the new group @@ -2274,12 +2382,6 @@ class Mesh: def GetId(self): return self.mesh.GetId() - ## Get the study Id - # @return integer value, which is the study Id of the mesh - # @ingroup l1_auxiliary - def GetStudyId(self): - return self.mesh.GetStudyId() - ## Check the group names for duplications. # Consider the maximum group name length stored in MED file. # @return True or False @@ -2311,10 +2413,10 @@ class Mesh: return self.editor.MakeIDSource(ids, elemType) - # Get informations about mesh contents: + # Get information about mesh contents: # ------------------------------------ - ## Get the mesh stattistic + ## Get the mesh statistic # @return dictionary type element - count of elements # @ingroup l1_meshinfo def GetMeshInfo(self, obj = None): @@ -2886,7 +2988,7 @@ class Mesh: def Add0DElement( self, IDOfNode, DuplicateElements=True ): return self.editor.Add0DElement( IDOfNode, DuplicateElements ) - ## Create 0D elements on all nodes of the given elements except those + ## 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 @@ -2895,7 +2997,7 @@ class Mesh: # and/or found on nodes of \a theObject. # @param DuplicateElements to add one more 0D element to a node or not # @return an object (a new group or a temporary SMESH_IDSource) holding - # IDs of new and/or found 0D elements. IDs of 0D elements + # 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="", DuplicateElements=False): @@ -2995,8 +3097,8 @@ class Mesh: VertexID = Vertex try: self.editor.SetNodeOnVertex(NodeID, VertexID) - except SALOME.SALOME_Exception, inst: - raise ValueError, inst.details.text + except SALOME.SALOME_Exception as inst: + raise ValueError(inst.details.text) return True @@ -3013,8 +3115,8 @@ class Mesh: EdgeID = Edge try: self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge) - except SALOME.SALOME_Exception, inst: - raise ValueError, inst.details.text + except SALOME.SALOME_Exception as inst: + raise ValueError(inst.details.text) return True ## @brief Stores node position on a face @@ -3031,8 +3133,8 @@ class Mesh: FaceID = Face try: self.editor.SetNodeOnFace(NodeID, FaceID, u, v) - except SALOME.SALOME_Exception, inst: - raise ValueError, inst.details.text + except SALOME.SALOME_Exception as inst: + raise ValueError(inst.details.text) return True ## @brief Binds a node to a solid @@ -3047,8 +3149,8 @@ class Mesh: SolidID = Solid try: self.editor.SetNodeInVolume(NodeID, SolidID) - except SALOME.SALOME_Exception, inst: - raise ValueError, inst.details.text + except SALOME.SALOME_Exception as inst: + raise ValueError(inst.details.text) return True ## @brief Bind an element to a shape @@ -3063,8 +3165,8 @@ class Mesh: ShapeID = Shape try: self.editor.SetMeshElementOnShape(ElementID, ShapeID) - except SALOME.SALOME_Exception, inst: - raise ValueError, inst.details.text + except SALOME.SALOME_Exception as inst: + raise ValueError(inst.details.text) return True @@ -3108,7 +3210,7 @@ class Mesh: # @param x the X coordinate of a point # @param y the Y coordinate of a point # @param z the Z coordinate of a point - # @param elementType type of elements to find; either of + # @param elementType type of elements to find; either of # (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME); SMESH.ALL type # means elements of any type excluding nodes, discrete and 0D elements. # @param meshPart a part of mesh (group, sub-mesh) to search within @@ -3127,6 +3229,16 @@ class Mesh: def GetPointState(self, x, y, z): return self.editor.GetPointState(x, y, z) + ## Check if a 2D mesh is manifold + # @ingroup l1_controls + def IsManifold(self): + return self.editor.IsManifold() + + ## Check if orientation of 2D elements is coherent + # @ingroup l1_controls + def IsCoherentOrientation2D(self): + return self.editor.IsCoherentOrientation2D() + ## Find the node closest to a point and moves it to a point location # @param x the X coordinate of a point # @param y the Y coordinate of a point @@ -3247,7 +3359,7 @@ class Mesh: # Type SMESH.FunctorType._items in the Python Console to see all items. # Note that not all items correspond to numerical functors. # @param MaxAngle is the maximum angle between element normals at which the fusion - # is still performed; theMaxAngle is mesured in radians. + # is still performed; theMaxAngle is measured 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 @@ -3266,7 +3378,7 @@ class Mesh: # Type SMESH.FunctorType._items in the Python Console to see all items. # Note that not all items correspond to numerical functors. # @param MaxAngle a max angle between element normals at which the fusion - # is still performed; theMaxAngle is mesured in radians. + # is still performed; theMaxAngle is measured in radians. # @return TRUE in case of success, FALSE otherwise. # @ingroup l2_modif_unitetri def TriToQuadObject (self, theObject, theCriterion, MaxAngle): @@ -3278,7 +3390,7 @@ class Mesh: return self.editor.TriToQuadObject(theObject, Functor, MaxAngle) ## Split quadrangles into triangles. - # @param IDsOfElements the faces to be splitted. + # @param IDsOfElements the faces to be split. # @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. @@ -3314,7 +3426,7 @@ class Mesh: ## Split 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, + # @param theElements the faces to be split. 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=[]): @@ -3329,7 +3441,7 @@ class Mesh: return self.editor.QuadTo4Tri( theElements ) ## Split quadrangles into triangles. - # @param IDsOfElements the faces to be splitted + # @param IDsOfElements the faces to be split # @param Diag13 is used to choose a diagonal for splitting. # @return TRUE in case of success, FALSE otherwise. # @ingroup l2_modif_cutquadr @@ -3350,7 +3462,7 @@ class Mesh: return self.editor.SplitQuadObject(theObject, Diag13) ## Find a better splitting of the given quadrangle. - # @param IDOfQuad the ID of the quadrangle to be splitted. + # @param IDOfQuad the ID of the quadrangle to be split. # @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to # choose a diagonal for splitting. # Type SMESH.FunctorType._items in the Python Console to see all items. @@ -3516,12 +3628,12 @@ class Mesh: pattern = self.smeshpyD.GetPattern() isDone = pattern.LoadFromFile(pattern_tetra) if not isDone: - print 'Pattern.LoadFromFile :', pattern.GetErrorCode() + print('Pattern.LoadFromFile :', pattern.GetErrorCode()) return isDone pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001) isDone = pattern.MakeMesh(self.mesh, False, False) - if not isDone: print 'Pattern.MakeMesh :', pattern.GetErrorCode() + if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode()) # split quafrangle faces near triangular facets of volumes self.SplitQuadsNearTriangularFacets() @@ -3570,12 +3682,12 @@ class Mesh: pattern = self.smeshpyD.GetPattern() isDone = pattern.LoadFromFile(pattern_prism) if not isDone: - print 'Pattern.LoadFromFile :', pattern.GetErrorCode() + print('Pattern.LoadFromFile :', pattern.GetErrorCode()) return isDone pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001) isDone = pattern.MakeMesh(self.mesh, False, False) - if not isDone: print 'Pattern.MakeMesh :', pattern.GetErrorCode() + if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode()) # Split quafrangle faces near triangular facets of volumes self.SplitQuadsNearTriangularFacets() @@ -3675,9 +3787,9 @@ class Mesh: self.editor.ConvertToQuadratic(theForce3d) error = self.editor.GetLastError() if error and error.comment: - print error.comment + print(error.comment) return error - + ## Convert the mesh from quadratic to ordinary, # deletes old quadratic elements, \n replacing # them with ordinary mesh elements with the same id. @@ -3728,13 +3840,13 @@ class Mesh: return mesh, group ## - # @brief Create missing boundary elements around either the whole mesh or + # @brief Create missing boundary elements around either the whole mesh or # groups of elements # @param dimension - defines type of boundary elements to create, either of # { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D } # @param groupName - a name of group to store all boundary elements in, # "" means not to create the group - # @param meshName - a name of a new mesh, which is a copy of the initial + # @param meshName - a name of a new mesh, which is a copy of the initial # mesh + created boundary elements; "" means not to create the new mesh # @param toCopyAll - if true, the whole initial mesh will be copied into # the new mesh else only boundary elements will be copied into the new mesh @@ -3918,7 +4030,7 @@ class Mesh: if isinstance( basePoint, int): xyz = self.GetNodeXYZ( basePoint ) if not xyz: - raise RuntimeError, "Invalid node ID: %s" % basePoint + raise RuntimeError("Invalid node ID: %s" % basePoint) basePoint = xyz if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ): basePoint = self.geompyD.PointCoordinates( basePoint ) @@ -3978,7 +4090,7 @@ class Mesh: Elements = [ Elements.GetMesh() ] if isinstance( Elements, list ): if not Elements: - raise RuntimeError, "Elements empty!" + raise RuntimeError("Elements empty!") if isinstance( Elements[0], int ): Elements = self.GetIDSource( Elements, SMESH.ALL ) unRegister.set( Elements ) @@ -4438,9 +4550,9 @@ class Mesh: if ( isinstance( thePoint, list )): thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] ) if ( isinstance( theScaleFact, float )): - theScaleFact = [theScaleFact] + theScaleFact = [theScaleFact] if ( isinstance( theScaleFact, int )): - theScaleFact = [ float(theScaleFact)] + theScaleFact = [ float(theScaleFact)] self.mesh.SetParameters(thePoint.parameters) @@ -4466,9 +4578,9 @@ class Mesh: if ( isinstance( thePoint, list )): thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] ) if ( isinstance( theScaleFact, float )): - theScaleFact = [theScaleFact] + theScaleFact = [theScaleFact] if ( isinstance( theScaleFact, int )): - theScaleFact = [ float(theScaleFact)] + theScaleFact = [ float(theScaleFact)] self.mesh.SetParameters(thePoint.parameters) mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact, @@ -4629,6 +4741,24 @@ class Mesh: def MergeEqualElements(self): self.editor.MergeEqualElements() + ## Returns all or only closed free borders + # @return list of SMESH.FreeBorder's + # @ingroup l2_modif_trsf + def FindFreeBorders(self, ClosedOnly=True): + return self.editor.FindFreeBorders( ClosedOnly ) + + ## Fill with 2D elements a hole defined by a SMESH.FreeBorder. + # @param FreeBorder either a SMESH.FreeBorder or a list on node IDs. These nodes + # must describe all sequential nodes of the hole border. The first and the last + # nodes must be the same. Use FindFreeBorders() to get nodes of holes. + # @ingroup l2_modif_trsf + def FillHole(self, holeNodes): + if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ): + holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes) + if not isinstance( holeNodes, SMESH.FreeBorder ): + raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes) + self.editor.FillHole( holeNodes ) + ## Return groups of FreeBorder's coincident within the given tolerance. # @param tolerance the tolerance. If the tolerance <= 0.0 then one tenth of an average # size of elements adjacent to free borders being compared is used. @@ -4636,7 +4766,7 @@ class Mesh: # @ingroup l2_modif_trsf def FindCoincidentFreeBorders (self, tolerance=0.): return self.editor.FindCoincidentFreeBorders( tolerance ) - + ## Sew FreeBorder's of each group # @param freeBorders either a SMESH.CoincidentFreeBorders structure or a list of lists # where each enclosed list contains node IDs of a group of coincident free @@ -4662,7 +4792,7 @@ class Mesh: coincidentGroups = [] for nodeList in freeBorders: if not nodeList or len( nodeList ) % 3: - raise ValueError, "Wrong number of nodes in this group: %s" % nodeList + raise ValueError("Wrong number of nodes in this group: %s" % nodeList) group = [] while nodeList: group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 )) @@ -4745,7 +4875,7 @@ class Mesh: def ClearLastCreated(self): self.editor.ClearLastCreated() - ## Create duplicates of given elements, i.e. create new elements based on the + ## Create duplicates of given elements, i.e. create 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. If \a theElements is @@ -4753,7 +4883,7 @@ class Mesh: # @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 + # 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_duplicat @@ -4904,12 +5034,12 @@ class Mesh: ## 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 theElems - list of groups of nodes or 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 + # @return groups of affected elements in order: volumes, faces, edges # @ingroup l2_modif_duplicat def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape): return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape) @@ -4926,11 +5056,11 @@ class Mesh: # @return TRUE if operation has been completed successfully, FALSE otherwise # @ingroup l2_modif_duplicat def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ): - return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries ) + return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries ) ## Double nodes on some external faces and create flat elements. # Flat elements are mainly used by some types of mechanic calculations. - # + # # Each group of the list must be constituted of faces. # Triangles are transformed in prisms, and quadrangles in hexahedrons. # @param theGroupsOfFaces - list of groups of faces @@ -4938,18 +5068,51 @@ class Mesh: # @ingroup l2_modif_duplicat 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 ): + ## Create a polyline consisting of 1D mesh elements each lying on a 2D element of + # the initial mesh. Positions of new nodes are found by cutting the mesh by the + # plane passing through pairs of points specified by each PolySegment structure. + # If there are several paths connecting a pair of points, the shortest path is + # selected by the module. Position of the cutting plane is defined by the two + # points and an optional vector lying on the plane specified by a PolySegment. + # By default the vector is defined by Mesh module as following. A middle point + # of the two given points is computed. The middle point is projected to the mesh. + # The vector goes from the middle point to the projection point. In case of planar + # mesh, the vector is normal to the mesh. + # @param segments - PolySegment's defining positions of cutting planes. + # Return the used vector which goes from the middle point to its projection. + # @param groupName - optional name of a group where created mesh segments will + # be added. + # @ingroup l2_modif_duplicat + def MakePolyLine(self, segments, groupName='', isPreview=False ): + editor = self.editor + if isPreview: + editor = self.mesh.GetMeshEditPreviewer() + segmentsRes = editor.MakePolyLine( segments, groupName ) + for i, seg in enumerate( segmentsRes ): + segments[i].vector = seg.vector + if isPreview: + return editor.GetPreviewData() + return None + + ## Return a cached numerical functor by its type. + # @param theCriterion functor type - an item of SMESH.FunctorType enumeration. + # Type SMESH.FunctorType._items in the Python Console to see all items. + # Note that not all items correspond to numerical functors. + # @return SMESH_NumericalFunctor. The functor is already initialized + # with a mesh + # @ingroup l1_measurements + 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 + self.functors[ EnumToLong(funcType) ] = fn return fn ## Return value of a functor for a given element @@ -4960,7 +5123,7 @@ class Mesh: # @return the functor value or zero in case of invalid arguments # @ingroup l1_measurements def FunctorValue(self, funcType, elemId, isElem=True): - fn = self._getFunctor( funcType ) + fn = self.GetFunctor( funcType ) if fn.GetElementType() == self.GetElementType(elemId, isElem): val = fn.GetValue(elemId) else: @@ -5066,7 +5229,7 @@ class Mesh: unRegister.set( meshPart ) if isinstance( meshPart, Mesh ): meshPart = meshPart.mesh - fun = self._getFunctor( funType ) + fun = self.GetFunctor( funType ) if fun: if meshPart: if hasattr( meshPart, "SetMesh" ): @@ -5085,15 +5248,33 @@ class Mesh: # with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh # class meshProxy(SMESH._objref_SMESH_Mesh): - def __init__(self): - SMESH._objref_SMESH_Mesh.__init__(self) + def __init__(self, *args): + SMESH._objref_SMESH_Mesh.__init__(self, *args) def __deepcopy__(self, memo=None): - new = self.__class__() + new = self.__class__(self) return new def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly if len( args ) == 3: args += SMESH.ALL_NODES, True - return SMESH._objref_SMESH_Mesh.CreateDimGroup( self, *args ) + return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args) + def ExportToMEDX(self, *args): # function removed + print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead") + args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] + SMESH._objref_SMESH_Mesh.ExportMED(self, *args) + def ExportToMED(self, *args): # function removed + print("WARNING: ExportToMED() is deprecated, use ExportMED() instead") + args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] + while len(args) < 4: # !!!! nb of parameters for ExportToMED IDL's method + args.append(True) + SMESH._objref_SMESH_Mesh.ExportMED(self, *args) + def ExportPartToMED(self, *args): # 'version' parameter removed + args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] + SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args) + def ExportMED(self, *args): # signature of method changed + args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] + while len(args) < 4: # !!!! nb of parameters for ExportToMED IDL's method + args.append(True) + SMESH._objref_SMESH_Mesh.ExportMED(self, *args) pass omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy) @@ -5101,11 +5282,11 @@ omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy) ## Private class wrapping SMESH.SMESH_SubMesh in order to add Compute() # class submeshProxy(SMESH._objref_SMESH_subMesh): - def __init__(self): - SMESH._objref_SMESH_subMesh.__init__(self) + def __init__(self, *args): + SMESH._objref_SMESH_subMesh.__init__(self, *args) self.mesh = None def __deepcopy__(self, memo=None): - new = self.__class__() + new = self.__class__(self) return new ## Compute the sub-mesh and return the status of the computation @@ -5121,11 +5302,11 @@ class submeshProxy(SMESH._objref_SMESH_subMesh): ok = self.mesh.Compute( self.GetSubShape(),refresh=[] ) - if salome.sg.hasDesktop() and self.mesh.GetStudyId() >= 0: + if salome.sg.hasDesktop(): smeshgui = salome.ImportComponentGUI("SMESH") - smeshgui.Init(self.mesh.GetStudyId()) + smeshgui.Init() smeshgui.SetMeshIcon( salome.ObjectToID( self ), ok, (self.GetNumberOfElements()==0) ) - if refresh: salome.sg.updateObjBrowser(True) + if refresh: salome.sg.updateObjBrowser() pass return ok @@ -5138,8 +5319,8 @@ omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProx # smeshBuilder.Mesh # class meshEditor(SMESH._objref_SMESH_MeshEditor): - def __init__(self): - SMESH._objref_SMESH_MeshEditor.__init__(self) + def __init__(self, *args): + SMESH._objref_SMESH_MeshEditor.__init__(self, *args) self.mesh = None def __getattr__(self, name ): # method called if an attribute not found if not self.mesh: # look for name() method in Mesh class @@ -5148,10 +5329,10 @@ class meshEditor(SMESH._objref_SMESH_MeshEditor): return getattr( self.mesh, name ) if name == "ExtrusionAlongPathObjX": return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name - print "meshEditor: attribute '%s' NOT FOUND" % name + print("meshEditor: attribute '%s' NOT FOUND" % name) return None def __deepcopy__(self, memo=None): - new = self.__class__() + new = self.__class__(self) return new def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes) if len( args ) == 1: args += False, @@ -5217,8 +5398,8 @@ class algoCreator: # Store a python class of algorithm def add(self, algoClass): - if type( algoClass ).__name__ == 'classobj' and \ - hasattr( algoClass, "algoType"): + if inspect.isclass(algoClass) and \ + hasattr(algoClass, "algoType"): self.algoTypeToClass[ algoClass.algoType ] = algoClass if not self.defaultAlgoType and \ hasattr( algoClass, "isDefault") and algoClass.isDefault: @@ -5265,11 +5446,12 @@ class algoCreator: if not algoType: algoType = self.defaultAlgoType if not algoType and self.algoTypeToClass: - algoType = self.algoTypeToClass.keys()[0] - if self.algoTypeToClass.has_key( algoType ): + algoType = sorted( self.algoTypeToClass.keys() )[0] + if algoType in self.algoTypeToClass: #print "Create algo",algoType + return self.algoTypeToClass[ algoType ]( self.mesh, shape ) - raise RuntimeError, "No class found for algo type %s" % algoType + raise RuntimeError( "No class found for algo type %s" % algoType) return None ## Private class used to substitute and store variable parameters of hypotheses. @@ -5294,11 +5476,11 @@ class hypMethodWrapper: except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call # maybe there is a replaced string arg which is not variable result = self.method( self.hyp, *args ) - except ValueError, detail: # raised by ParseParameters() + except ValueError as detail: # raised by ParseParameters() try: result = self.method( self.hyp, *args ) except omniORB.CORBA.BAD_PARAM: - raise ValueError, detail # wrong variable name + raise ValueError(detail) # wrong variable name return result pass @@ -5334,9 +5516,9 @@ for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ): pluginBuilderName = pluginName + "Builder" try: exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName)) - except Exception, e: - from salome_utils import verbose - if verbose(): print "Exception while loading %s: %s" % ( pluginBuilderName, e ) + except Exception as e: + from salome_utils import verbose + if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e )) continue exec( "from salome.%s import %s" % (pluginName, pluginBuilderName)) plugin = eval( pluginBuilderName ) @@ -5347,7 +5529,7 @@ for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ): if k[0] == '_': continue algo = getattr( plugin, k ) #print " algo:", str(algo) - if type( algo ).__name__ == 'classobj' and hasattr( algo, "meshMethod" ): + if inspect.isclass(algo) and hasattr(algo, "meshMethod"): #print " meshMethod:" , str(algo.meshMethod) if not hasattr( Mesh, algo.meshMethod ): setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))