-# Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2021 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
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
"""
if not mesh.smeshpyD.IsEnablePublish():
return
- if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
+ if not hasattr( geom, "GetShapeType" ):
return
if not geom.GetStudyEntry():
## get a name
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
return hyp
+ def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
+ """
+ Create hypothesis initialized according to parameters
+
+ Parameters:
+ hypType (string): hypothesis type
+ libName (string): plug-in library name
+ mesh: optional mesh by which a hypotheses can initialize self
+ shape: optional geometry by size of which a hypotheses can initialize self
+ initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
+
+ Returns:
+ created hypothesis instance
+ """
+ if isinstance( mesh, Mesh ):
+ mesh = mesh.GetMesh()
+ if isinstance( initParams, (bool,int)):
+ initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
+ return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
+ mesh, shape, initParams )
+
def GetMeshInfo(self, obj):
"""
Get the mesh statistic.
#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):
"""
"""
if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
- if self.geom == 0:
- geom = self.mesh.GetShapeToMesh()
- else:
- geom = self.geom
+ geom = self.mesh.GetShapeToMesh()
ok = False
try:
if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
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
Parameters:
submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
+
+ Warning: the method is for setting the order for all sub-meshes at once:
+ SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
"""
return self.mesh.SetMeshOrder(submeshes)
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 <SMESH.SMESH_IDSource>`)
+ 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
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 <SMESH.SMESH_IDSource>`) to export instead of the mesh
+ meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
+ 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
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 )
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)
+ self.mesh.ExportMED(fileName, auto_groups, version, 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)
-
- 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 <SMESH.SMESH_IDSource>`) 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 <SMESH.SMESH_IDSource>`) 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):
"""
tgeo = str(shape.GetShapeType())
if tgeo == "VERTEX":
typ = NODE
- elif tgeo == "EDGE":
+ elif tgeo == "EDGE" or tgeo == "WIRE":
typ = EDGE
elif tgeo == "FACE" or tgeo == "SHELL":
typ = FACE
elif tgeo == "SOLID" or tgeo == "COMPSOLID":
typ = VOLUME
elif tgeo == "COMPOUND":
- sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
+ try:
+ sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
+ except:
+ # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
+ # simplification of access in geomBuilder: omniORB.registerObjref
+ from SHAPERSTUDY_utils import getEngine
+ gen = getEngine()
+ if gen:
+ sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
if not sub:
raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
return self._groupTypeFromShape( sub[0] )
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
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.
"""
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
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 <SMESH.SMESH_IDSource>` holding faces to reorient.
+ referenceFaces: list of :class:`sub-mesh, group, filter <SMESH.SMESH_IDSource>` 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.
theValue,Parameters,hasVars = ParseParameters(Value)
mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
self.mesh.SetParameters(Parameters)
- # if mesh_groups[0]:
- # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
+ if mesh_groups[0]:
+ return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
return mesh_groups
def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
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)
if genObj and hasattr( genObj, "UnRegister" ):
genObj.UnRegister()
-for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
+for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
"""
Bind methods creating mesher plug-ins to the Mesh class
"""