-# Copyright (C) 2007-2019 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
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
def GetName(obj):
"""
Return a name of an object
-
+
Returns:
object name
"""
"""
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
mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
return
-def FirstVertexOnCurve(mesh, edge):
- """
- Returns:
- the first vertex of a geometrical edge by ignoring orientation
- """
- vv = mesh.geompyD.SubShapeAll( edge, geomBuilder.geomBuilder.ShapeType["VERTEX"])
- if not vv:
- 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
- xyz1 = mesh.geompyD.PointCoordinates( vv[0] )
- xyz2 = mesh.geompyD.PointCoordinates( vv[1] )
- dist1, dist2 = 0,0
- for i in range(3):
- dist1 += abs( xyz[i] - xyz1[i] )
- dist2 += abs( xyz[i] - xyz2[i] )
- if dist1 < dist2:
- return vv[0]
- else:
- return vv[1]
+# def FirstVertexOnCurve(mesh, edge):
+# """
+# Returns:
+# the first vertex of a geometrical edge by ignoring orientation
+# """
+# return mesh.geompyD.GetVertexByIndex( edge, 0, False )
+
smeshInst = None
"""
def init_smesh(self,geompyD = None):
"""
Set Geometry component
- """
+ """
#print("init_smesh")
self.UpdateStudy(geompyD)
notebook.myStudy = salome.myStudy
def Mesh(self, obj=0, name=0):
"""
- Create a mesh. This mesh can be either
+ Create a mesh. This mesh can be either
* an empty mesh not bound to geometry, if *obj* == 0
* an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
* a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
Parameters:
- obj: either
+ obj: either
1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
::
- salome.myStudy.FindObjectID("0:1:2:3").GetObject()
+ salome.myStudy.FindObjectID("0:1:2:3").GetObject()
2. a geometrical object for meshing
3. none.
obj,name = name,obj
return Mesh(self, self.geompyD, obj, name)
+ def ParallelMesh(self, obj, param, nbThreads, name=0):
+ """
+ Create a parallel mesh.
+
+ Parameters:
+ obj: geometrical object for meshing
+ name: the name for the new mesh.
+ param: full mesh parameters
+ nbThreads: Number of threads for parallelisation.
+
+ Returns:
+ an instance of class :class:`ParallelMesh`.
+ """
+ return ParallelMesh(self, self.geompyD, obj, param, nbThreads, name)
+
+ def RemoveMesh( self, mesh ):
+ """
+ Delete a mesh
+ """
+ if isinstance( mesh, Mesh ):
+ mesh = mesh.GetMesh()
+ pass
+ if not isinstance( mesh, SMESH._objref_SMESH_Mesh ):
+ raise TypeError("%s is not a mesh" % mesh )
+ so = salome.ObjectToSObject( mesh )
+ if so:
+ sb = salome.myStudy.NewBuilder()
+ sb.RemoveObjectWithChildren( so )
+ else:
+ mesh.UnRegister()
+ pass
+ return
+
def EnumToLong(self,theItem):
"""
Return a long value from enumeration
Returns:
:class:`SMESH.PointStruct`
"""
-
- [x, y, z] = self.geompyD.PointCoordinates(theVertex)
+ geompyD = theVertex.GetGen()
+ [x, y, z] = geompyD.PointCoordinates(theVertex)
return PointStruct(x,y,z)
def GetDirStruct(self,theVector):
Returns:
:class:`SMESH.DirStruct`
"""
-
- vertices = self.geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
+ geompyD = theVector.GetGen()
+ vertices = geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
if(len(vertices) != 2):
print("Error: vector object is incorrect.")
return None
- p1 = self.geompyD.PointCoordinates(vertices[0])
- p2 = self.geompyD.PointCoordinates(vertices[1])
+ p1 = geompyD.PointCoordinates(vertices[0])
+ p2 = geompyD.PointCoordinates(vertices[1])
pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
dirst = DirStruct(pnt)
return dirst
:class:`SMESH.AxisStruct`
"""
import GEOM
- edges = self.geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
+ geompyD = theObj.GetGen()
+ edges = geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
axis = None
if len(edges) > 1:
- vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
- vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
- vertex1 = self.geompyD.PointCoordinates(vertex1)
- vertex2 = self.geompyD.PointCoordinates(vertex2)
- vertex3 = self.geompyD.PointCoordinates(vertex3)
- vertex4 = self.geompyD.PointCoordinates(vertex4)
+ vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
+ vertex3, vertex4 = geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
+ vertex1 = geompyD.PointCoordinates(vertex1)
+ vertex2 = geompyD.PointCoordinates(vertex2)
+ vertex3 = geompyD.PointCoordinates(vertex3)
+ vertex4 = geompyD.PointCoordinates(vertex4)
v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
normal = [ v1[1]*v2[2]-v2[1]*v1[2], v1[2]*v2[0]-v2[2]*v1[0], v1[0]*v2[1]-v2[0]*v1[1] ]
axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
elif len(edges) == 1:
- vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
- p1 = self.geompyD.PointCoordinates( vertex1 )
- p2 = self.geompyD.PointCoordinates( vertex2 )
+ vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
+ p1 = geompyD.PointCoordinates( vertex1 )
+ p2 = geompyD.PointCoordinates( vertex2 )
axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
elif theObj.GetShapeType() == GEOM.VERTEX:
- x,y,z = self.geompyD.PointCoordinates( theObj )
+ x,y,z = geompyD.PointCoordinates( theObj )
axis = AxisStruct( x,y,z, 1,0,0,)
axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
return axis
if sc:
sb.LoadWith(sc, self)
pass
-
+
def SetEnablePublish( self, theIsEnablePublish ):
"""
Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
Create a Mesh object(s) importing data from the given MED file
Returns:
- a tuple ( list of class :class:`Mesh` instances,
+ a tuple ( list of class :class:`Mesh` instances,
:class:`SMESH.DriverMED_ReadStatus` )
"""
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
Returns:
an instance of class :class:`Mesh`
- See also:
+ See also:
:meth:`Mesh.Append`
"""
aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
return aMesh
+ def CreateDualMesh( self, mesh, meshName, adaptToShape):
+ """
+ Create a dual of a mesh.
+
+ Parameters:
+ mesh: Tetrahedron mesh
+ :class:`mesh, <SMESH.SMESH_IDSource>`.
+
+ meshName: a name of the new mesh
+ adpatToShape: if true project boundary points on shape
+
+ Returns:
+ an instance of class :class:`Mesh`
+ """
+ if isinstance( mesh, Mesh ):
+ mesh = mesh.GetMesh()
+ dualMesh = SMESH._objref_SMESH_Gen.CreateDualMesh(self, mesh, meshName, adaptToShape)
+ return Mesh(self, self.geompyD, dualMesh)
+
+
def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
"""
Create a mesh by copying a part of another mesh.
Parameters:
- meshPart: a part of mesh to copy, either
+ meshPart: a part of mesh to copy, either
:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
To copy nodes or elements not forming any mesh object,
pass result of :meth:`Mesh.GetIDSource` as *meshPart*
Parameters:
sourceMesh: the mesh to copy definition of.
- newGeom: the new geomtry.
+ newGeom: the new geometry.
meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
toCopyGroups: to create groups in the new mesh.
toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
- toCopyElements: to copy mesh elements present on non-modified sub-shapes of
+ toCopyElements: to copy mesh elements present on non-modified sub-shapes of
*sourceMesh*.
Returns:
tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
*invalidEntries* are study entries of objects whose
counterparts are not found in the *newGeom*, followed by entries
of mesh sub-objects that are invalid because they depend on a not found
- preceeding sub-shape
+ preceding sub-shape
"""
if isinstance( sourceMesh, Mesh ):
sourceMesh = sourceMesh.GetMesh()
name = aCriterion.ThresholdStr
if not name:
name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
- aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
+ geompyD = aThreshold.GetGen()
+ aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
# or a name of GEOM object
elif isinstance( aThreshold, str ):
aCriterion.ThresholdStr = aThreshold
name = aThreshold.GetName()
if not name:
name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
- aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
+ geompyD = aThreshold.GetGen()
+ aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
elif isinstance(aThreshold, int): # node id
aCriterion.Threshold = aThreshold
elif isinstance(aThreshold, list): # 3 point coordinates
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.
- Use :meth:`smeshBuilder.EnumToLong` to get an integer from
- an item of :class:`SMESH.EntityType`.
Returns:
dictionary { :class:`SMESH.EntityType` - "count of elements" }
Returns:
minimum distance value
- See also:
+ See also:
:meth:`GetMinDistance`
"""
Returns:
:class:`SMESH.Measure` structure or None if input data is invalid
- See also:
+ See also:
:meth:`MinDistance`
"""
Returns:
tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
- See also:
+ See also:
:meth:`GetBoundingBox`
"""
Returns:
:class:`SMESH.Measure` structure
- See also:
+ See also:
:meth:`BoundingBox`
"""
def GetGravityCenter(self, obj):
"""
Get gravity center of all nodes of a mesh object.
-
- Parameters:
+
+ Parameters:
obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
- Returns:
+ Returns:
Three components of the gravity center (x,y,z)
- See also:
+ See also:
:meth:`Mesh.BaryCenter`
"""
if isinstance(obj, Mesh): obj = obj.mesh
"""
Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
- Parameters:
- p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
+ Parameters:
+ p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
or list [x,y,z]
- Returns:
+ Returns:
Angle in radians
"""
if isinstance( p1, list ): p1 = PointStruct(*p1)
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.
- """
+ """
geom = 0
mesh = 0
Parameters:
theMesh: a :class:`SMESH.SMESH_Mesh` object
"""
-
-
# do not call Register() as this prevents mesh servant deletion at closing study
#if self.mesh: self.mesh.UnRegister()
self.mesh = theMesh
if self.mesh:
#self.mesh.Register()
self.geom = self.mesh.GetShapeToMesh()
- pass
+ if self.geom:
+ 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
def GetMesh(self):
"""
geom = self.geom
return self.smeshpyD.Evaluate(self.mesh, geom)
-
def Compute(self, geom=0, discardModifs=False, refresh=False):
"""
Compute the mesh and return the status of the computation
"""
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
def SetMeshOrder(self, submeshes):
"""
- Set order in which concurrent sub-meshes should be meshed
+ Set priority of sub-meshes. It works in two ways:
+
+ * For sub-meshes with assigned algorithms of same dimension generating mesh of
+ *several dimensions*, it sets the order in which the sub-meshes are computed.
+ * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
+ when looking for meshing parameters to apply to a sub-shape. To impose the
+ order in which sub-meshes with uni-dimensional algorithms are computed,
+ call **submesh.Compute()** in a desired order.
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)
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
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
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
+ 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;
- 'f' stands for "_faces_" field;
- 's' stands for "_solids_" field.
- zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
+ 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)
-
- def ExportSAUV(self, f, auto_groups=0):
- """
- Export the mesh in a file in SAUV format
-
+ self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
- 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):
"""
If **autoDimension** is *False*, the space dimension is always 3.
"""
-
+
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
Create an empty standalone mesh group
Parameters:
- elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
+ elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
name: the name of the mesh group
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] )
Parameters:
group (SMESH.SMESH_GroupBase): group to remove
+
+ Note:
+ This operation can create gaps in numeration of nodes or elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
self.mesh.RemoveGroupWithContents(group)
def GetGroups(self, elemType = SMESH.ALL):
"""
- Get the list of groups existing in the mesh in the order of creation
+ Get the list of groups existing in the mesh in the order of creation
(starting from the oldest one)
Parameters:
def GetMeshInfo(self, obj = None):
"""
Get the mesh statistic.
- Use :meth:`smeshBuilder.EnumToLong` to get an integer from
- an item of :class:`SMESH.EntityType`.
Returns:
dictionary { :class:`SMESH.EntityType` - "count of elements" }
Return the type of mesh element or node
Returns:
- the value from :class:`SMESH.ElementType` enumeration.
+ the value from :class:`SMESH.ElementType` enumeration.
Return SMESH.ALL if element or node with the given ID does not exist
"""
Returns:
a list of three double values
- See also:
+ See also:
:meth:`smeshBuilder.GetGravityCenter`
"""
Returns:
tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
- See Also:
+ See Also:
:meth:`GetBoundingBox()`
"""
Returns:
:class:`SMESH.Measure` structure
- See Also:
+ See Also:
:meth:`BoundingBox()`
"""
Returns:
True or False
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
return self.editor.RemoveElements(IDsOfElements)
Returns:
True or False
+
+ Note:
+ This operation can create gaps in numeration of nodes.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
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:
number of the removed nodes
+
+ Note:
+ This operation can create gaps in numeration of nodes.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
return self.editor.RemoveOrphanNodes()
Returns:
an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
IDs of new and/or found 0D elements. IDs of 0D elements
- can be retrieved from the returned object by
+ can be retrieved from the returned object by
calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
"""
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.
+ 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.
"""
if isinstance( edges, Mesh ):
edges = self.GetIDSource( edges, SMESH.EDGE )
unRegister.set( edges )
return self.editor.Get1DBranches( edges, startNode )
-
+
def FindSharpEdges( self, angle, addExisting=False ):
"""
Return sharp edges of faces and non-manifold ones.
Returns:
False if proper faces were not found
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
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
Reorient faces contained in *the2DObject*.
Parameters:
- the2DObject: is a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
- theDirection: is a desired direction of normal of *theFace*.
+ the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
+ theDirection: a desired direction of normal of *theFace*.
It can be either a GEOM vector or a list of coordinates [x,y,z].
theFaceOrPoint: defines a face of *the2DObject* whose normal will be
compared with theDirection. It can be either ID of face or a point
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.
Returns:
True in case of success, False otherwise.
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
Returns:
True in case of success, False otherwise.
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
Returns:
True in case of success, False otherwise.
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
if IDsOfElements == []:
IDsOfElements = self.GetElementsId()
Returns:
True in case of success, False otherwise.
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
if ( isinstance( theObject, Mesh )):
theObject = theObject.GetMesh()
a quadrangle.
Parameters:
- theElements: the faces to be splitted. This can be either
+ theElements: the faces to be splitted. This can be either
:class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
or a list of face IDs. By default all quadrangles are split
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
unRegister = genObjUnRegister()
if isinstance( theElements, Mesh ):
Returns:
True in case of success, False otherwise.
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
if IDsOfElements == []:
IDsOfElements = self.GetElementsId()
Returns:
True in case of success, False otherwise.
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
if ( isinstance( theObject, Mesh )):
theObject = theObject.GetMesh()
to numerical functors.
Returns:
- * 1 if 1-3 diagonal is better,
- * 2 if 2-4 diagonal is better,
+ * 1 if 1-3 diagonal is better,
+ * 2 if 2-4 diagonal is better,
* 0 if error occurs.
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
method: flags passing splitting method:
smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
unRegister = genObjUnRegister()
if isinstance( elems, Mesh ):
Parameters:
elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
if None (default), all bi-quadratic elements will be split
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
unRegister = genObjUnRegister()
if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
allDomains: if :code:`False`, only hexahedra adjacent to one closest
to *startHexPoint* are split, else *startHexPoint*
is used to find the facet to split in all domains present in *elems*.
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
# IDSource
unRegister = genObjUnRegister()
def SplitQuadsNearTriangularFacets(self):
"""
Split quadrangle faces near triangular facets of volumes
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
faces_array = self.GetElementsByType(SMESH.FACE)
for face_id in faces_array:
This operation uses :doc:`pattern_mapping` functionality for splitting.
Parameters:
- theObject: the object from which the list of hexahedrons is taken;
+ theObject: the object from which the list of hexahedrons is taken;
this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
theNode000,theNode001: within the range [0,7]; gives the orientation of the
pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
Returns:
True in case of success, False otherwise.
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
# Pattern:
# 5.---------.6
Returns:
True in case of success, False otherwise.
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
# Pattern: 5.---------.6
# /|# /|
Warning:
If *theSubMesh* is provided, the mesh can become non-conformal
+
+ Note:
+ This operation can create gaps in numeration of nodes or elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
if isinstance( theSubMesh, Mesh ):
Warning:
If *theSubMesh* is provided, the mesh can become non-conformal
+
+ Note:
+ This operation can create gaps in numeration of nodes or elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
if theSubMesh:
of all steps, else - size of each step
Returns:
- the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
+ the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
empty list otherwise
"""
- a list of tree components of the point or
- a node ID or
- a GEOM point
- angles: list of angles in radians. Nodes at each extrusion step are rotated
+ angles: list of angles in radians. Nodes at each extrusion step are rotated
around *basePoint*, additionally to previous steps.
anglesVariation: forces the computation of rotation angles as linear
variation of the given *angles* along path steps
if isinstance( Elements, list ):
if not Elements:
raise RuntimeError("Elements empty!")
+ if isinstance( Elements[0], Mesh ):
+ Elements = [ Elements[0].GetMesh() ]
if isinstance( Elements[0], int ):
Elements = self.GetIDSource( Elements, SMESH.ALL )
unRegister.set( Elements )
PathShape: optional shape (edge or wire) which defines the sub-mesh of the mesh defined by *PathObject* if the mesh contains not only path segments, else it can be None
NodeStart: the first or the last node on the path. Defines the direction of extrusion
HasAngles: not used obsolete
- Angles: list of angles in radians. Nodes at each extrusion step are rotated
+ Angles: list of angles in radians. Nodes at each extrusion step are rotated
around *basePoint*, additionally to previous steps.
LinearVariation: forces the computation of rotation angles as linear
variation of the given Angles along path steps
HasRefPoint: allows using the reference point
RefPoint: optional scaling and rotation center (mass center of the extruded
- elements by default). The User can specify any point as the Reference Point.
+ elements by default). The User can specify any point as the Reference Point.
*RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
MakeGroups: forces the generation of new groups from existing ones
ScaleFactors: optional scale factors to apply during extrusion
else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
Returns:
- list of created :class:`groups <SMESH.SMESH_GroupBase>` and
+ list of created :class:`groups <SMESH.SMESH_GroupBase>` and
:class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
Example: :ref:`tui_extrusion_along_path`
"""
Angles,AnglesParameters,hasVars = ParseAngles(Angles)
ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
Parameters = AnglesParameters + var_separator + \
- RefPoint.parameters + var_separator + ScalesParameters
+ RefPoint.parameters + var_separator + ScalesParameters
self.mesh.SetParameters(Parameters)
return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
PathObject, PathShape, NodeStart,
Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
NodeStart: the start node from Path. Defines the direction of extrusion
HasAngles: not used obsolete
- Angles: list of angles in radians. Nodes at each extrusion step are rotated
+ Angles: list of angles in radians. Nodes at each extrusion step are rotated
around *basePoint*, additionally to previous steps.
LinearVariation: forces the computation of rotation angles as linear
variation of the given Angles along path steps
PathShape: shape (edge) defines the sub-mesh for the path
NodeStart: the first or the last node on the edge. Defines the direction of extrusion
HasAngles: not used obsolete
- Angles: list of angles in radians. Nodes at each extrusion step are rotated
+ Angles: list of angles in radians. Nodes at each extrusion step are rotated
around *basePoint*, additionally to previous steps.
HasRefPoint: allows using the reference point
RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
PathShape: shape (edge) defines the sub-mesh for the path
NodeStart: the first or the last node on the edge. Defines the direction of extrusion
HasAngles: not used obsolete
- Angles: list of angles in radians. Nodes at each extrusion step are rotated
+ Angles: list of angles in radians. Nodes at each extrusion step are rotated
around *basePoint*, additionally to previous steps.
HasRefPoint: allows using the reference point
RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
variation of the given Angles along path steps
Returns:
- list of created :class:`groups <SMESH.SMESH_GroupBase>` and
+ list of created :class:`groups <SMESH.SMESH_GroupBase>` and
:class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
Example: :ref:`tui_extrusion_along_path`
PathShape: shape (edge) defines the sub-mesh for the path
NodeStart: the first or the last node on the edge. Defines the direction of extrusion
HasAngles: not used obsolete
- Angles: list of angles in radians. Nodes at each extrusion step are rotated
+ Angles: list of angles in radians. Nodes at each extrusion step are rotated
around *basePoint*, additionally to previous steps.
HasRefPoint: allows using the reference point
RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
variation of the given Angles along path steps
Returns:
- list of created :class:`groups <SMESH.SMESH_GroupBase>` and
+ list of created :class:`groups <SMESH.SMESH_GroupBase>` and
:class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
Example: :ref:`tui_extrusion_along_path`
PathShape: shape (edge) defines the sub-mesh for the path
NodeStart: the first or the last node on the edge. Defines the direction of extrusion
HasAngles: not used obsolete
- Angles: list of angles in radians. Nodes at each extrusion step are rotated
+ Angles: list of angles in radians. Nodes at each extrusion step are rotated
around *basePoint*, additionally to previous steps.
HasRefPoint: allows using the reference point
RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
variation of the given Angles along path steps
Returns:
- list of created :class:`groups <SMESH.SMESH_GroupBase>` and
+ list of created :class:`groups <SMESH.SMESH_GroupBase>` and
:class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
Example: :ref:`tui_extrusion_along_path`
theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
theValue (float): signed offset size
MakeGroups (boolean): forces the generation of new groups from existing ones
- CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
+ CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
False means to remove original elements.
NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
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):
SubMeshOrGroup = [ obj.GetMesh() ]
break
if isinstance( obj, int ):
- SubMeshOrGroup = self.GetIDSource( SubMeshOrGroup, SMESH.NODE )
+ SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
unRegister.set( SubMeshOrGroup )
break
then the first node in the group is kept.
AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
invalid
+
+ Note:
+ This operation can create gaps in numeration of nodes or elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
If *ElementsToKeep* does not include an element to keep for some group to merge,
then the first element in the group is kept.
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
unRegister = genObjUnRegister()
def MergeEqualElements(self):
"""
Leave one element and remove all other elements built on the same nodes.
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
self.editor.MergeEqualElements()
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, groupName )
+ return self.editor.FillHole( holeNodes, groupName )
def FindCoincidentFreeBorders (self, tolerance=0.):
"""
Returns:
a number of successfully sewed groups
+
+ Note:
+ This operation can create gaps in numeration of nodes or elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
if freeBorders and isinstance( freeBorders, list ):
Returns:
:class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
+
+ Note:
+ This operation can create gaps in numeration of nodes or elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
Returns:
:class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
Returns:
:class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
+
+ Note:
+ This operation can create gaps in numeration of elements.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
Returns:
:class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
+
+ Note:
+ This operation can create gaps in numeration of nodes.
+ Call :meth:`RenumberElements` to remove the gaps.
"""
return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
def ChangeElemNodes(self, ide, newIDs):
"""
- Set new nodes for the given element.
+ Set new nodes for the given element. Number of nodes should be kept.
Parameters:
ide: the element ID
Parameters:
theElements: container of elements to duplicate. It can be a
- :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
+ :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
or a list of element IDs. If *theElements* is
a :class:`Mesh`, elements of highest dimension are duplicated
theGroupName: a name of group to contain the generated elements.
in any group.
Returns:
- a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
+ a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
None if *theGroupName* == "".
"""
return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
def MakePolyLine(self, segments, groupName='', isPreview=False ):
- """
+ """
Create a polyline consisting of 1D mesh elements each lying on a 2D element of
the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
groupName: optional name of a group where created mesh segments will be added.
- """
+ """
editor = self.editor
if isPreview:
editor = self.mesh.GetMeshEditPreviewer()
def MakeSlot(self, segmentGroup, width ):
"""
Create a slot of given width around given 1D elements lying on a triangle mesh.
- The slot is consrtucted by cutting faces by cylindrical surfaces made
+ The slot is constructed by cutting faces by cylindrical surfaces made
around each segment. Segments are expected to be created by MakePolyLine().
Returns:
def GetLength(self, elemId=None):
"""
- Get length of 1D element or sum of lengths of all 1D mesh elements
+ Get length of given 1D elements or of all 1D mesh elements
Parameters:
- elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
+ elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum length of all 1D elements will be calculated.
Returns:
- element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise
+ Sum of lengths of given elements
"""
length = 0
if elemId == None:
length = self.smeshpyD.GetLength(self)
+ elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
+ length = self.smeshpyD.GetLength(elemId)
+ elif elemId == []:
+ length = 0
+ elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
+ for obj in elemId:
+ length += self.smeshpyD.GetLength(obj)
+ elif isinstance(elemId, list) and isinstance(elemId[0], int):
+ unRegister = genObjUnRegister()
+ obj = self.GetIDSource( elemId )
+ unRegister.set( obj )
+ length = self.smeshpyD.GetLength( obj )
else:
length = self.FunctorValue(SMESH.FT_Length, elemId)
return length
def GetArea(self, elemId=None):
"""
- Get area of 2D element or sum of areas of all 2D mesh elements
- elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
+ Get area of given 2D elements or of all 2D mesh elements
+
+ Parameters:
+ elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum area of all 2D elements will be calculated.
Returns:
- element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
+ Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
"""
area = 0
if elemId == None:
area = self.smeshpyD.GetArea(self)
+ elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
+ area = self.smeshpyD.GetArea(elemId)
+ elif elemId == []:
+ area = 0
+ elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
+ for obj in elemId:
+ area += self.smeshpyD.GetArea(obj)
+ elif isinstance(elemId, list) and isinstance(elemId[0], int):
+ unRegister = genObjUnRegister()
+ obj = self.GetIDSource( elemId )
+ unRegister.set( obj )
+ area = self.smeshpyD.GetArea( obj )
else:
area = self.FunctorValue(SMESH.FT_Area, elemId)
return area
def GetVolume(self, elemId=None):
"""
- Get volume of 3D element or sum of volumes of all 3D mesh elements
+ Get volume of given 3D elements or of all 3D mesh elements
Parameters:
- elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
+ elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum volume of all 3D elements will be calculated.
Returns:
- element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
+ Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
"""
volume = 0
if elemId == None:
- volume = self.smeshpyD.GetVolume(self)
+ volume= self.smeshpyD.GetVolume(self)
+ elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
+ volume= self.smeshpyD.GetVolume(elemId)
+ elif elemId == []:
+ volume = 0
+ elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
+ for obj in elemId:
+ volume+= self.smeshpyD.GetVolume(obj)
+ elif isinstance(elemId, list) and isinstance(elemId[0], int):
+ unRegister = genObjUnRegister()
+ obj = self.GetIDSource( elemId )
+ unRegister.set( obj )
+ volume= self.smeshpyD.GetVolume( obj )
else:
volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
return volume
"""
Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
- Parameters:
+ Parameters:
node1,node2,node3: IDs of the three nodes
- Returns:
+ Returns:
Angle in radians [0,PI]. -1 if failure case.
"""
p1 = self.GetNodeXYZ( node1 )
pass # end of Mesh class
+def _copy_netgen_param(dim, local_param, global_param):
+ if dim==1:
+ #TODO: Try to identify why we need to substract 1
+ local_param.NumberOfSegments(int(global_param.GetNbSegPerEdge())-1)
+ elif dim==2:
+ local_param.SetMaxSize(global_param.GetMaxSize())
+ local_param.SetMinSize(global_param.GetMinSize())
+ local_param.SetOptimize(global_param.GetOptimize())
+ local_param.SetFineness(global_param.GetFineness())
+ local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
+ local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
+ local_param.SetGrowthRate(global_param.GetGrowthRate()*0.9)
+ local_param.SetChordalError(global_param.GetChordalError())
+ local_param.SetChordalErrorEnabled(global_param.GetChordalErrorEnabled())
+ local_param.SetUseSurfaceCurvature(global_param.GetUseSurfaceCurvature())
+ local_param.SetUseDelauney(global_param.GetUseDelauney())
+ local_param.SetQuadAllowed(global_param.GetQuadAllowed())
+ local_param.SetWorstElemMeasure(global_param.GetWorstElemMeasure())
+ local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary())
+ local_param.SetNbThreads(global_param.GetNbThreads())
+ else:
+ local_param.SetMaxSize(global_param.GetMaxSize())
+ local_param.SetMinSize(global_param.GetMinSize())
+ local_param.SetOptimize(global_param.GetOptimize())
+ local_param.SetCheckOverlapping(global_param.GetCheckOverlapping())
+ local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary())
+ local_param.SetFineness(global_param.GetFineness())
+ local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
+ local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
+ local_param.SetGrowthRate(global_param.GetGrowthRate())
+ local_param.SetNbThreads(global_param.GetNbThreads())
+
+class ParallelMesh(Mesh):
+ """
+ Surcharge on Mesh for parallel computation of a mesh
+ """
+
+ def __init__(self, smeshpyD, geompyD, geom, param, nbThreads, name=0):
+ """
+ Create a parallel mesh.
+
+ Parameters:
+ geom: geometrical object for meshing
+ param: full mesh parameters
+ nbThreads: Number of threads for parallelisation.
+ name: the name for the new mesh.
+
+ Returns:
+ an instance of class :class:`ParallelMesh`.
+ """
+
+ if not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
+ raise ValueError("geom argument must be a geometry")
+
+ if not isinstance(param, NETGENPlugin._objref_NETGENPlugin_Hypothesis):
+ raise ValueError("param must come from NETGENPlugin")
+
+ if nbThreads < 1:
+ raise ValueError("Number of threads must be stricly greater than 1")
+
+ # Splitting geometry into 3D elements and all the 2D/1D into one compound
+ object_solids = geompyD.ExtractShapes(geom, geompyD.ShapeType["SOLID"],
+ True)
+
+ solids = []
+ isolid = 0
+ for solid in object_solids:
+ isolid += 1
+ geompyD.addToStudyInFather( geom, solid, 'Solid_{}'.format(isolid) )
+ solids.append(solid)
+
+ faces = []
+ iface = 0
+ for isolid, solid in enumerate(solids):
+ solid_faces = geompyD.ExtractShapes(solid, geompyD.ShapeType["FACE"],
+ True)
+ for face in solid_faces:
+ faces.append(face)
+ iface += 1
+ geompyD.addToStudyInFather(solid, face,
+ 'Face_{}'.format(iface))
+
+ # Creating submesh for edges 1D/2D part
+
+ all_faces = geompyD.MakeCompound(faces)
+ geompyD.addToStudy(all_faces, 'Compound_1')
+ all_faces = geompyD.MakeGlueEdges(all_faces, 1e-07)
+ all_faces = geompyD.MakeGlueFaces(all_faces, 1e-07)
+ geompyD.addToStudy(all_faces, 'global2D')
+
+ super(ParallelMesh, self).__init__(smeshpyD, geompyD, geom, name)
+
+ self.mesh.SetNbThreads(nbThreads)
+
+ self.UseExistingSegments()
+ self.UseExistingFaces()
+
+ algo2d = self.Triangle(geom=all_faces, algo="NETGEN_2D")
+ param2d = algo2d.Parameters()
+
+ _copy_netgen_param(2, param2d, param)
+
+ for solid_id, solid in enumerate(solids):
+ name = "Solid_{}".format(solid_id)
+ self.UseExistingSegments(geom=solid)
+ self.UseExistingFaces(geom=solid)
+ algo3d = self.Tetrahedron(geom=solid, algo="NETGEN_3D_Remote")
+
+ param3d = algo3d.Parameters()
+
+ _copy_netgen_param(3, param3d, param)
+
+ pass # End of ParallelMesh
+
+
class meshProxy(SMESH._objref_SMESH_Mesh):
"""
Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
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
"""