X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH_SWIG%2FsmeshBuilder.py;h=d0fa9a291d358503d4df1af5eac9cda0ad4db575;hb=9d7121c884b58f35182dab517602612c1606a6bf;hp=3cb09bd0e35067f639becf200640454f8271589b;hpb=b1ea58215737bb5dd03e12f98a73ba6edd354e93;p=modules%2Fsmesh.git diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index 3cb09bd0e..d0fa9a291 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -38,8 +38,9 @@ SMESH.MED_MINOR_7 = 27 # back compatibility SMESH.MED_MINOR_8 = 28 # back compatibility SMESH.MED_MINOR_9 = 29 # back compatibility -from SMESH import * -from salome.smesh.smesh_algorithm import Mesh_Algorithm +from SMESH import * +from salome.smesh.smesh_algorithm import Mesh_Algorithm +from StdMeshers import BlockCS import SALOME import SALOMEDS @@ -684,18 +685,6 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ] return aMeshes, aStatus - def CreateMeshesFromSAUV( self,theFileName ): - """ - Create a Mesh object(s) importing data from the given SAUV file - - Returns: - a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` ) - """ - - aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName) - aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ] - return aMeshes, aStatus - def CreateMeshesFromSTL( self, theFileName ): """ Create a Mesh object importing data from the given STL file @@ -1650,9 +1639,19 @@ class Mesh(metaclass = MeshMeta): #self.mesh.Register() self.geom = self.mesh.GetShapeToMesh() if self.geom: - self.geompyD = self.geom.GetGen() + self.geompyD = None + try: + if salome.sg.hasDesktop(): + so = salome.ObjectToSObject( self.geom ) + comp = so.GetFatherComponent() + if comp.ComponentDataType() == "SHAPERSTUDY": + import shaperBuilder + self.geompyD = shaperBuilder.New() + except: + pass + if not self.geompyD: + self.geompyD = self.geom.GetGen() pass - pass def GetMesh(self): """ @@ -1951,9 +1950,10 @@ class Mesh(metaclass = MeshMeta): print(msg) print(allReasons) pass - if salome.sg.hasDesktop(): - if not isinstance( refresh, list): # not a call from subMesh.Compute() - if refresh: salome.sg.updateObjBrowser() + if salome.sg: + if salome.sg.hasDesktop(): + if not isinstance( refresh, list): # not a call from subMesh.Compute() + if refresh: salome.sg.updateObjBrowser() return ok @@ -2125,7 +2125,7 @@ class Mesh(metaclass = MeshMeta): def AutomaticTetrahedralization(self, fineness=0): """ - Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron + Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron Parameters: fineness: [0.0,1.0] defines mesh fineness @@ -2287,6 +2287,78 @@ class Mesh(metaclass = MeshMeta): self.mesh.RemoveHypothesis( self.geom, hyp ) pass pass + + def ExportMEDCoupling(self, *args, **kwargs): + """ + Export the mesh in a memory representation. + + Parameters: + 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. + overwrite (boolean): parameter for overwriting/not overwriting the file + meshPart: a part of mesh (:class:`sub-mesh, group or filter `) + to export instead of the mesh + autoDimension: if *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 *autoDimension* is *False*, the space dimension is always 3. + fields: list of GEOM fields defined on the shape to mesh. + 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. + + zTolerance (float): tolerance in Z direction. If Z coordinate of a node is + close to zero within a given tolerance, the coordinate is set to zero. + If *ZTolerance* is negative (default), the node coordinates are kept as is. + saveNumbers(boolean) : enable saving numbers of nodes and cells. + """ + auto_groups = args[0] if len(args) > 0 else False + meshPart = args[1] if len(args) > 1 else None + autoDimension = args[2] if len(args) > 2 else True + fields = args[3] if len(args) > 3 else [] + geomAssocFields = args[4] if len(args) > 4 else '' + z_tolerance = args[5] if len(args) > 5 else -1. + saveNumbers = args[6] if len(args) > 6 else True + # process keywords arguments + auto_groups = kwargs.get("auto_groups", auto_groups) + meshPart = kwargs.get("meshPart", meshPart) + autoDimension = kwargs.get("autoDimension", autoDimension) + fields = kwargs.get("fields", fields) + geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields) + z_tolerance = kwargs.get("zTolerance", z_tolerance) + saveNumbers = kwargs.get("saveNumbers", saveNumbers) + + # invoke engine's function + if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers: + unRegister = genObjUnRegister() + if isinstance( meshPart, list ): + meshPart = self.GetIDSource( meshPart, SMESH.ALL ) + unRegister.set( meshPart ) + + z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance) + self.mesh.SetParameters(Parameters) + + intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension, + fields, geomAssocFields, z_tolerance, + saveNumbers ) + import medcoupling + dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr) + return medcoupling.MEDFileData.New(dab) + else: + intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension) + import medcoupling + dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr) + return medcoupling.MEDFileMesh.New(dab) + def ExportMED(self, *args, **kwargs): """ Export the mesh in a file in MED format @@ -2297,12 +2369,16 @@ class Mesh(metaclass = MeshMeta): 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. - minor (int): define the minor version (y, where version is x.y.z) of MED file format. - The minor must be between 0 and the current minor version of MED file library. - If minor is equal to -1, the minor version is not changed (default). - The major version (x, where version is x.y.z) cannot be changed. + version (int): define the version (xy, where version is x.y.z) of MED file format. + For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40. + The rules of compatibility to write a mesh in an older version than + the current version depend on the current version. For instance, + with med 4.0 it is possible to write/append med files in 4.0.0 (default) + or 3.2.1 or 3.3.1 formats. + If the version is equal to -1, the version is not changed (default). overwrite (boolean): parameter for overwriting/not overwriting the file - meshPart: a part of mesh (:class:`sub-mesh, group or filter `) to export instead of the mesh + meshPart: a part of mesh (:class:`sub-mesh, group or filter `) + to export instead of the mesh autoDimension: if *True* (default), a space dimension of a MED mesh can be either - 1D if all mesh nodes lie on OX coordinate axis, or @@ -2323,30 +2399,37 @@ class Mesh(metaclass = MeshMeta): zTolerance (float): tolerance in Z direction. If Z coordinate of a node is close to zero within a given tolerance, the coordinate is set to zero. If *ZTolerance* is negative (default), the node coordinates are kept as is. + saveNumbers (boolean) : enable saving numbers of nodes and cells. """ # 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 - minor = args[2] if len(args) > 2 else -1 + version = args[2] if len(args) > 2 else -1 overwrite = args[3] if len(args) > 3 else True meshPart = args[4] if len(args) > 4 else None autoDimension = args[5] if len(args) > 5 else True fields = args[6] if len(args) > 6 else [] geomAssocFields = args[7] if len(args) > 7 else '' z_tolerance = args[8] if len(args) > 8 else -1. + saveNumbers = args[9] if len(args) > 9 else True # process keywords arguments auto_groups = kwargs.get("auto_groups", auto_groups) - minor = kwargs.get("minor", minor) + version = kwargs.get("version", version) + version = kwargs.get("minor", version) 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) z_tolerance = kwargs.get("zTolerance", z_tolerance) + saveNumbers = kwargs.get("saveNumbers", saveNumbers) + + if isinstance( meshPart, Mesh): + meshPart = meshPart.GetMesh() # invoke engine's function - if meshPart or fields or geomAssocFields or z_tolerance > 0: + if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers: unRegister = genObjUnRegister() if isinstance( meshPart, list ): meshPart = self.GetIDSource( meshPart, SMESH.ALL ) @@ -2355,60 +2438,49 @@ class Mesh(metaclass = MeshMeta): z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance) self.mesh.SetParameters(Parameters) - self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension, - fields, geomAssocFields, z_tolerance) + self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, + version, overwrite, autoDimension, + fields, geomAssocFields, z_tolerance, saveNumbers ) else: - self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension) - - def ExportSAUV(self, f, auto_groups=0): - """ - Export the mesh in a file in SAUV format - - - Parameters: - f: is the file name - 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. - """ - - self.mesh.ExportSAUV(f, auto_groups) + self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension) - def ExportDAT(self, f, meshPart=None): + def ExportDAT(self, f, meshPart=None, renumber=True): """ Export the mesh in a file in DAT format Parameters: f: the file name meshPart: a part of mesh (:class:`sub-mesh, group or filter `) to export instead of the mesh + renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering """ - if meshPart: + if meshPart or not renumber: unRegister = genObjUnRegister() if isinstance( meshPart, list ): meshPart = self.GetIDSource( meshPart, SMESH.ALL ) unRegister.set( meshPart ) - self.mesh.ExportPartToDAT( meshPart, f ) + self.mesh.ExportPartToDAT( meshPart, f, renumber ) else: - self.mesh.ExportDAT(f) + self.mesh.ExportDAT( f, renumber ) - def ExportUNV(self, f, meshPart=None): + def ExportUNV(self, f, meshPart=None, renumber=True): """ Export the mesh in a file in UNV format Parameters: f: the file name meshPart: a part of mesh (:class:`sub-mesh, group or filter `) to export instead of the mesh + renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering """ - if meshPart: + if meshPart or not renumber: unRegister = genObjUnRegister() if isinstance( meshPart, list ): meshPart = self.GetIDSource( meshPart, SMESH.ALL ) unRegister.set( meshPart ) - self.mesh.ExportPartToUNV( meshPart, f ) + self.mesh.ExportPartToUNV( meshPart, f, renumber ) else: - self.mesh.ExportUNV(f) + self.mesh.ExportUNV( f, renumber ) def ExportSTL(self, f, ascii=1, meshPart=None): """ @@ -4026,6 +4098,16 @@ class Mesh(metaclass = MeshMeta): return self.editor.RemoveNodes(IDsOfNodes) + def RemoveNodeWithReconnection(self, nodeID ): + """ + Remove a node along with changing surrounding faces to cover a hole. + + Parameters: + nodeID: ID of node to remove + """ + + return self.editor.RemoveNodeWithReconnection( nodeID ) + def RemoveOrphanNodes(self): """ Remove all orphan (free) nodes from mesh @@ -4444,7 +4526,7 @@ class Mesh(metaclass = MeshMeta): Returns: A list of edge groups and a list of corresponding node groups, - where the group is a list of IDs of edges or elements, like follows + where the group is a list of IDs of edges or nodes, like follows [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]]. If a group is closed, the first and last nodes of the group are same. """ @@ -4519,6 +4601,30 @@ class Mesh(metaclass = MeshMeta): return self.editor.DeleteDiag(NodeID1, NodeID2) + def AddNodeOnSegment(self, Node1, Node2, position = 0.5): + """ + Replace each triangle bound by Node1-Node2 segment with + two triangles by connecting a node made on the link with a node + opposite to the link. + + Parameters: + Node1: ID of the first node + Node2: ID of the second node + position: location [0,1] of the new node on the segment + """ + return self.editor.AddNodeOnSegment(Node1, Node2, position) + + def AddNodeOnFace(self, face, x, y, z): + """ + Split a face into triangles by adding a new node onto the face + and connecting the new node with face nodes + + Parameters: + face: ID of the face + x,y,z: coordinates of the new node + """ + return self.editor.AddNodeOnFace(face, x, y, z) + def Reorient(self, IDsOfElements=None): """ Reorient elements by ids @@ -4592,6 +4698,29 @@ class Mesh(metaclass = MeshMeta): theFace = -1 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint ) + def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]): + """ + Reorient faces contained in a list of *objectFaces* + equally to faces contained in a list of *referenceFaces*. + + Parameters: + objectFaces: list of :class:`mesh, sub-mesh, group, filter ` holding faces to reorient. + referenceFaces: list of :class:`sub-mesh, group, filter ` holding reference faces. It can be empty, then any face in *objectFaces* is used as the reference. + + Returns: + number of reoriented faces. + """ + if not isinstance( objectFaces, list ): + objectFaces = [ objectFaces ] + for i,obj2D in enumerate( objectFaces ): + if isinstance( obj2D, Mesh ): + objectFaces[i] = obj2D.GetMesh() + if not isinstance( referenceFaces, list ): + referenceFaces = [ referenceFaces ] + + return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces ) + + def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ): """ Reorient faces according to adjacent volumes. @@ -7371,6 +7500,14 @@ class meshProxy(SMESH._objref_SMESH_Mesh): while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method args2.append(True) SMESH._objref_SMESH_Mesh.ExportMED(self, *args2) + def ExportUNV(self, *args): # renumber arg added + if len( args ) == 1: + args += True, + return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args) + def ExportDAT(self, *args): # renumber arg added + if len( args ) == 1: + args += True, + return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args) pass omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)