1 # Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 # File : smeshBuilder.py
20 # Author : Francis KLOSS, OCC
24 from salome.geom import geomBuilder
26 import SMESH # This is necessary for back compatibility
27 import omniORB # back compatibility
28 SMESH.MED_V2_1 = 11 #omniORB.EnumItem("MED_V2_1", 11) # back compatibility: use number > MED minor version
29 SMESH.MED_V2_2 = 12 #omniORB.EnumItem("MED_V2_2", 12) # back compatibility: latest minor will be used
30 SMESH.MED_MINOR_0 = 20 # back compatibility
31 SMESH.MED_MINOR_1 = 21 # back compatibility
32 SMESH.MED_MINOR_2 = 22 # back compatibility
33 SMESH.MED_MINOR_3 = 23 # back compatibility
34 SMESH.MED_MINOR_4 = 24 # back compatibility
35 SMESH.MED_MINOR_5 = 25 # back compatibility
36 SMESH.MED_MINOR_6 = 26 # back compatibility
37 SMESH.MED_MINOR_7 = 27 # back compatibility
38 SMESH.MED_MINOR_8 = 28 # back compatibility
39 SMESH.MED_MINOR_9 = 29 # back compatibility
42 from salome.smesh.smesh_algorithm import Mesh_Algorithm
49 # In case the omniORBpy EnumItem class does not fully support Python 3
50 # (for instance in version 4.2.1-2), the comparison ordering methods must be
54 SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
56 def enumitem_eq(self, other):
58 if isinstance(other, omniORB.EnumItem):
59 if other._parent_id == self._parent_id:
60 return self._v == other._v
62 return self._parent_id == other._parent_id
64 return id(self) == id(other)
66 return id(self) == id(other)
68 def enumitem_lt(self, other):
70 if isinstance(other, omniORB.EnumItem):
71 if other._parent_id == self._parent_id:
72 return self._v < other._v
74 return self._parent_id < other._parent_id
76 return id(self) < id(other)
78 return id(self) < id(other)
80 def enumitem_le(self, other):
82 if isinstance(other, omniORB.EnumItem):
83 if other._parent_id == self._parent_id:
84 return self._v <= other._v
86 return self._parent_id <= other._parent_id
88 return id(self) <= id(other)
90 return id(self) <= id(other)
92 def enumitem_gt(self, other):
94 if isinstance(other, omniORB.EnumItem):
95 if other._parent_id == self._parent_id:
96 return self._v > other._v
98 return self._parent_id > other._parent_id
100 return id(self) > id(other)
102 return id(self) > id(other)
104 def enumitem_ge(self, other):
106 if isinstance(other, omniORB.EnumItem):
107 if other._parent_id == self._parent_id:
108 return self._v >= other._v
110 return self._parent_id >= other._parent_id
112 return id(self) >= id(other)
114 return id(self) >= id(other)
116 omniORB.EnumItem.__eq__ = enumitem_eq
117 omniORB.EnumItem.__lt__ = enumitem_lt
118 omniORB.EnumItem.__le__ = enumitem_le
119 omniORB.EnumItem.__gt__ = enumitem_gt
120 omniORB.EnumItem.__ge__ = enumitem_ge
123 class MeshMeta(type):
124 """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
126 def __instancecheck__(cls, inst):
127 """Implement isinstance(inst, cls)."""
128 return any(cls.__subclasscheck__(c)
129 for c in {type(inst), inst.__class__})
131 def __subclasscheck__(cls, sub):
132 """Implement issubclass(sub, cls)."""
133 return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
135 def DegreesToRadians(AngleInDegrees):
136 """Convert an angle from degrees to radians
139 return AngleInDegrees * pi / 180.0
141 import salome_notebook
142 notebook = salome_notebook.notebook
143 # Salome notebook variable separator
146 def ParseParameters(*args):
148 Return list of variable values from salome notebook.
149 The last argument, if is callable, is used to modify values got from notebook
155 if args and callable(args[-1]):
156 args, varModifFun = args[:-1], args[-1]
157 for parameter in args:
159 Parameters += str(parameter) + var_separator
161 if isinstance(parameter,str):
162 # check if there is an inexistent variable name
163 if not notebook.isVariable(parameter):
164 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
165 parameter = notebook.get(parameter)
168 parameter = varModifFun(parameter)
171 Result.append(parameter)
174 Parameters = Parameters[:-1]
175 Result.append( Parameters )
176 Result.append( hasVariables )
179 def ParseAngles(*args):
181 Parse parameters while converting variables to radians
183 return ParseParameters( *( args + (DegreesToRadians, )))
185 def __initPointStruct(point,*args):
187 Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
188 Parameters are stored in PointStruct.parameters attribute
190 point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
192 SMESH.PointStruct.__init__ = __initPointStruct
194 def __initAxisStruct(ax,*args):
196 Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
197 Parameters are stored in AxisStruct.parameters attribute
200 raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
201 ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
203 SMESH.AxisStruct.__init__ = __initAxisStruct
205 smeshPrecisionConfusion = 1.e-07
206 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
207 """Compare real values using smeshPrecisionConfusion as tolerance
209 if abs(val1 - val2) < tol:
217 Return a name of an object
224 if isinstance(obj, SALOMEDS._objref_SObject):
228 ior = salome.orb.object_to_string(obj)
232 sobj = salome.myStudy.FindObjectIOR(ior)
234 return sobj.GetName()
235 if hasattr(obj, "GetName"):
236 # unknown CORBA object, having GetName() method
239 # unknown CORBA object, no GetName() method
242 if hasattr(obj, "GetName"):
243 # unknown non-CORBA object, having GetName() method
246 raise RuntimeError("Null or invalid object")
248 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
250 Print error message if a hypothesis was not assigned.
253 hypType = "algorithm"
255 hypType = "hypothesis"
258 if hasattr( status, "__getitem__" ):
259 status, reason = status[0], status[1]
260 if status == HYP_UNKNOWN_FATAL:
261 reason = "for unknown reason"
262 elif status == HYP_INCOMPATIBLE:
263 reason = "this hypothesis mismatches the algorithm"
264 elif status == HYP_NOTCONFORM:
265 reason = "a non-conform mesh would be built"
266 elif status == HYP_ALREADY_EXIST:
267 if isAlgo: return # it does not influence anything
268 reason = hypType + " of the same dimension is already assigned to this shape"
269 elif status == HYP_BAD_DIM:
270 reason = hypType + " mismatches the shape"
271 elif status == HYP_CONCURRENT :
272 reason = "there are concurrent hypotheses on sub-shapes"
273 elif status == HYP_BAD_SUBSHAPE:
274 reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
275 elif status == HYP_BAD_GEOMETRY:
276 reason = "the algorithm is not applicable to this geometry"
277 elif status == HYP_HIDDEN_ALGO:
278 reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
279 elif status == HYP_HIDING_ALGO:
280 reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
281 elif status == HYP_NEED_SHAPE:
282 reason = "algorithm can't work without shape"
283 elif status == HYP_INCOMPAT_HYPS:
289 where = '"%s"' % geomName
291 meshName = GetName( mesh )
292 if meshName and meshName != NO_NAME:
293 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
294 if status < HYP_UNKNOWN_FATAL and where:
295 print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
297 print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
299 print('"%s" was not assigned : %s' %( hypName, reason ))
302 def AssureGeomPublished(mesh, geom, name=''):
304 Private method. Add geom (sub-shape of the main shape) into the study if not yet there
306 if not mesh.smeshpyD.IsEnablePublish():
308 if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
310 if not geom.GetStudyEntry():
312 if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
313 # for all groups SubShapeName() return "Compound_-1"
314 name = mesh.geompyD.SubShapeName(geom, mesh.geom)
316 name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
318 mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
321 def FirstVertexOnCurve(mesh, edge):
324 the first vertex of a geometrical edge by ignoring orientation
326 vv = mesh.geompyD.SubShapeAll( edge, geomBuilder.geomBuilder.ShapeType["VERTEX"])
328 raise TypeError("Given object has no vertices")
329 if len( vv ) == 1: return vv[0]
330 v0 = mesh.geompyD.MakeVertexOnCurve(edge,0.)
331 xyz = mesh.geompyD.PointCoordinates( v0 ) # coords of the first vertex
332 xyz1 = mesh.geompyD.PointCoordinates( vv[0] )
333 xyz2 = mesh.geompyD.PointCoordinates( vv[1] )
336 dist1 += abs( xyz[i] - xyz1[i] )
337 dist2 += abs( xyz[i] - xyz2[i] )
346 smeshInst is a singleton
352 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
354 This class allows to create, load or manipulate meshes.
355 It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
356 It also has methods to get infos and measure meshes.
359 # MirrorType enumeration
360 POINT = SMESH_MeshEditor.POINT
361 AXIS = SMESH_MeshEditor.AXIS
362 PLANE = SMESH_MeshEditor.PLANE
364 # Smooth_Method enumeration
365 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
366 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
368 PrecisionConfusion = smeshPrecisionConfusion
370 # TopAbs_State enumeration
371 [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
373 # Methods of splitting a hexahedron into tetrahedra
374 Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
376 def __new__(cls, *args):
380 #print("==== __new__", engine, smeshInst, doLcc)
382 if smeshInst is None:
383 # smesh engine is either retrieved from engine, or created
385 # Following test avoids a recursive loop
387 if smeshInst is not None:
388 # smesh engine not created: existing engine found
392 # FindOrLoadComponent called:
393 # 1. CORBA resolution of server
394 # 2. the __new__ method is called again
395 #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
396 smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
398 # FindOrLoadComponent not called
399 if smeshInst is None:
400 # smeshBuilder instance is created from lcc.FindOrLoadComponent
401 #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
402 smeshInst = super(smeshBuilder,cls).__new__(cls)
404 # smesh engine not created: existing engine found
405 #print("==== existing ", engine, smeshInst, doLcc)
407 #print("====1 ", smeshInst)
410 #print("====2 ", smeshInst)
413 def __init__(self, *args):
415 #print("--------------- smeshbuilder __init__ ---", created)
418 SMESH._objref_SMESH_Gen.__init__(self, *args)
421 def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
423 Dump component to the Python script.
424 This method overrides IDL function to allow default values for the parameters.
427 return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
429 def SetDumpPythonHistorical(self, isHistorical):
431 Set mode of DumpPython(), *historical* or *snapshot*.
432 In the *historical* mode, the Python Dump script includes all commands
433 performed by SMESH engine. In the *snapshot* mode, commands
434 relating to objects removed from the Study are excluded from the script
435 as well as commands not influencing the current state of meshes
438 if isHistorical: val = "true"
440 SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
442 def init_smesh(self,geompyD = None):
444 Set Geometry component
447 self.UpdateStudy(geompyD)
448 notebook.myStudy = salome.myStudy
450 def Mesh(self, obj=0, name=0):
452 Create a mesh. This mesh can be either
454 * an empty mesh not bound to geometry, if *obj* == 0
455 * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
456 * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
461 1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
464 salome.myStudy.FindObjectID("0:1:2:3").GetObject()
466 2. a geometrical object for meshing
468 name: the name for the new mesh.
471 an instance of class :class:`Mesh`.
474 if isinstance(obj,str):
476 return Mesh(self, self.geompyD, obj, name)
478 def EnumToLong(self,theItem):
480 Return a long value from enumeration
485 def ColorToString(self,c):
487 Convert SALOMEDS.Color to string.
488 To be used with filters.
491 c: color value (SALOMEDS.Color)
494 a string representation of the color.
498 if isinstance(c, SALOMEDS.Color):
499 val = "%s;%s;%s" % (c.R, c.G, c.B)
500 elif isinstance(c, str):
503 raise ValueError("Color value should be of string or SALOMEDS.Color type")
506 def GetPointStruct(self,theVertex):
508 Get :class:`SMESH.PointStruct` from vertex
511 theVertex (GEOM.GEOM_Object): vertex
514 :class:`SMESH.PointStruct`
517 [x, y, z] = self.geompyD.PointCoordinates(theVertex)
518 return PointStruct(x,y,z)
520 def GetDirStruct(self,theVector):
522 Get :class:`SMESH.DirStruct` from vector
525 theVector (GEOM.GEOM_Object): vector
528 :class:`SMESH.DirStruct`
531 vertices = self.geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
532 if(len(vertices) != 2):
533 print("Error: vector object is incorrect.")
535 p1 = self.geompyD.PointCoordinates(vertices[0])
536 p2 = self.geompyD.PointCoordinates(vertices[1])
537 pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
538 dirst = DirStruct(pnt)
541 def MakeDirStruct(self,x,y,z):
543 Make :class:`SMESH.DirStruct` from a triplet of floats
546 x,y,z (float): vector components
549 :class:`SMESH.DirStruct`
552 pnt = PointStruct(x,y,z)
553 return DirStruct(pnt)
555 def GetAxisStruct(self,theObj):
557 Get :class:`SMESH.AxisStruct` from a geometrical object
560 theObj (GEOM.GEOM_Object): line or plane
563 :class:`SMESH.AxisStruct`
566 edges = self.geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
569 vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
570 vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
571 vertex1 = self.geompyD.PointCoordinates(vertex1)
572 vertex2 = self.geompyD.PointCoordinates(vertex2)
573 vertex3 = self.geompyD.PointCoordinates(vertex3)
574 vertex4 = self.geompyD.PointCoordinates(vertex4)
575 v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
576 v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
577 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] ]
578 axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
579 axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
580 elif len(edges) == 1:
581 vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
582 p1 = self.geompyD.PointCoordinates( vertex1 )
583 p2 = self.geompyD.PointCoordinates( vertex2 )
584 axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
585 axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
586 elif theObj.GetShapeType() == GEOM.VERTEX:
587 x,y,z = self.geompyD.PointCoordinates( theObj )
588 axis = AxisStruct( x,y,z, 1,0,0,)
589 axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
592 # From SMESH_Gen interface:
593 # ------------------------
595 def SetName(self, obj, name):
597 Set the given name to an object
600 obj: the object to rename
601 name: a new object name
604 if isinstance( obj, Mesh ):
606 elif isinstance( obj, Mesh_Algorithm ):
607 obj = obj.GetAlgorithm()
608 ior = salome.orb.object_to_string(obj)
609 SMESH._objref_SMESH_Gen.SetName(self, ior, name)
611 def SetEmbeddedMode( self,theMode ):
616 SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
618 def IsEmbeddedMode(self):
623 return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
625 def UpdateStudy( self, geompyD = None ):
627 Update the current study. Calling UpdateStudy() allows to
628 update meshes at switching GEOM->SMESH
632 from salome.geom import geomBuilder
633 geompyD = geomBuilder.geom
635 geompyD = geomBuilder.New()
638 self.SetGeomEngine(geompyD)
639 SMESH._objref_SMESH_Gen.UpdateStudy(self)
640 sb = salome.myStudy.NewBuilder()
641 sc = salome.myStudy.FindComponent("SMESH")
643 sb.LoadWith(sc, self)
646 def SetEnablePublish( self, theIsEnablePublish ):
648 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
649 switch **off** publishing in the Study of mesh objects.
651 #self.SetEnablePublish(theIsEnablePublish)
652 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
654 notebook = salome_notebook.NoteBook( theIsEnablePublish )
657 def CreateMeshesFromUNV( self,theFileName ):
659 Create a Mesh object importing data from the given UNV file
662 an instance of class :class:`Mesh`
665 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
666 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
669 def CreateMeshesFromMED( self,theFileName ):
671 Create a Mesh object(s) importing data from the given MED file
674 a tuple ( list of class :class:`Mesh` instances,
675 :class:`SMESH.DriverMED_ReadStatus` )
678 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
679 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
680 return aMeshes, aStatus
682 def CreateMeshesFromSAUV( self,theFileName ):
684 Create a Mesh object(s) importing data from the given SAUV file
687 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
690 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
691 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
692 return aMeshes, aStatus
694 def CreateMeshesFromSTL( self, theFileName ):
696 Create a Mesh object importing data from the given STL file
699 an instance of class :class:`Mesh`
702 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
703 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
706 def CreateMeshesFromCGNS( self, theFileName ):
708 Create Mesh objects importing data from the given CGNS file
711 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
714 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
715 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
716 return aMeshes, aStatus
718 def CreateMeshesFromGMF( self, theFileName ):
720 Create a Mesh object importing data from the given GMF file.
721 GMF files must have .mesh extension for the ASCII format and .meshb for
725 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
728 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
731 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
732 return Mesh(self, self.geompyD, aSmeshMesh), error
734 def Concatenate( self, meshes, uniteIdenticalGroups,
735 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
738 Concatenate the given meshes into one mesh. All groups of input meshes will be
739 present in the new mesh.
742 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
743 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
744 mergeNodesAndElements: if True, equal nodes and elements are merged
745 mergeTolerance: tolerance for merging nodes
746 allGroups: forces creation of groups corresponding to every input mesh
747 name: name of a new mesh
750 an instance of class :class:`Mesh`
753 if not meshes: return None
754 for i,m in enumerate(meshes):
755 if isinstance(m, Mesh):
756 meshes[i] = m.GetMesh()
757 mergeTolerance,Parameters,hasVars = ParseParameters(mergeTolerance)
758 meshes[0].SetParameters(Parameters)
760 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
761 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
763 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
764 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
765 aMesh = Mesh(self, self.geompyD, aSmeshMesh, name=name)
768 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
770 Create a mesh by copying a part of another mesh.
773 meshPart: a part of mesh to copy, either
774 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
775 To copy nodes or elements not forming any mesh object,
776 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
777 meshName: a name of the new mesh
778 toCopyGroups: to create in the new mesh groups the copied elements belongs to
779 toKeepIDs: to preserve order of the copied elements or not
782 an instance of class :class:`Mesh`
785 if (isinstance( meshPart, Mesh )):
786 meshPart = meshPart.GetMesh()
787 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
788 return Mesh(self, self.geompyD, mesh)
790 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
792 Return IDs of sub-shapes
795 theMainObject (GEOM.GEOM_Object): a shape
796 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
798 the list of integer values
801 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
803 def GetPattern(self):
805 Create a pattern mapper.
808 an instance of :class:`SMESH.SMESH_Pattern`
810 :ref:`Example of Patterns usage <tui_pattern_mapping>`
813 return SMESH._objref_SMESH_Gen.GetPattern(self)
815 def SetBoundaryBoxSegmentation(self, nbSegments):
817 Set number of segments per diagonal of boundary box of geometry, by which
818 default segment length of appropriate 1D hypotheses is defined in GUI.
822 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
824 # Filtering. Auxiliary functions:
825 # ------------------------------
827 def GetEmptyCriterion(self):
829 Create an empty criterion
832 :class:`SMESH.Filter.Criterion`
835 Type = self.EnumToLong(FT_Undefined)
836 Compare = self.EnumToLong(FT_Undefined)
840 UnaryOp = self.EnumToLong(FT_Undefined)
841 BinaryOp = self.EnumToLong(FT_Undefined)
844 Precision = -1 ##@1e-07
845 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
846 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
848 def GetCriterion(self,elementType,
850 Compare = FT_EqualTo,
852 UnaryOp=FT_Undefined,
853 BinaryOp=FT_Undefined,
856 Create a criterion by the given parameters
857 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
860 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
861 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
862 Note that the items starting from FT_LessThan are not suitable for *CritType*.
863 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
864 Threshold: the threshold value (range of ids as string, shape, numeric)
865 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
866 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
868 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
869 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
872 :class:`SMESH.Filter.Criterion`
874 Example: :ref:`combining_filters`
877 if not CritType in SMESH.FunctorType._items:
878 raise TypeError("CritType should be of SMESH.FunctorType")
879 aCriterion = self.GetEmptyCriterion()
880 aCriterion.TypeOfElement = elementType
881 aCriterion.Type = self.EnumToLong(CritType)
882 aCriterion.Tolerance = Tolerance
884 aThreshold = Threshold
886 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
887 aCriterion.Compare = self.EnumToLong(Compare)
888 elif Compare == "=" or Compare == "==":
889 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
891 aCriterion.Compare = self.EnumToLong(FT_LessThan)
893 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
894 elif Compare != FT_Undefined:
895 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
898 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
899 FT_BelongToCylinder, FT_LyingOnGeom]:
900 # Check that Threshold is GEOM object
901 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
902 aCriterion.ThresholdStr = GetName(aThreshold)
903 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
904 if not aCriterion.ThresholdID:
905 name = aCriterion.ThresholdStr
907 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
908 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
909 # or a name of GEOM object
910 elif isinstance( aThreshold, str ):
911 aCriterion.ThresholdStr = aThreshold
913 raise TypeError("The Threshold should be a shape.")
914 if isinstance(UnaryOp,float):
915 aCriterion.Tolerance = UnaryOp
916 UnaryOp = FT_Undefined
918 elif CritType == FT_BelongToMeshGroup:
919 # Check that Threshold is a group
920 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
921 if aThreshold.GetType() != elementType:
922 raise ValueError("Group type mismatches Element type")
923 aCriterion.ThresholdStr = aThreshold.GetName()
924 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
925 study = salome.myStudy
927 so = study.FindObjectIOR( aCriterion.ThresholdID )
931 aCriterion.ThresholdID = entry
933 raise TypeError("The Threshold should be a Mesh Group")
934 elif CritType == FT_RangeOfIds:
935 # Check that Threshold is string
936 if isinstance(aThreshold, str):
937 aCriterion.ThresholdStr = aThreshold
939 raise TypeError("The Threshold should be a string.")
940 elif CritType == FT_CoplanarFaces:
941 # Check the Threshold
942 if isinstance(aThreshold, int):
943 aCriterion.ThresholdID = str(aThreshold)
944 elif isinstance(aThreshold, str):
947 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
948 aCriterion.ThresholdID = aThreshold
950 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
951 elif CritType == FT_ConnectedElements:
952 # Check the Threshold
953 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
954 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
955 if not aCriterion.ThresholdID:
956 name = aThreshold.GetName()
958 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
959 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
960 elif isinstance(aThreshold, int): # node id
961 aCriterion.Threshold = aThreshold
962 elif isinstance(aThreshold, list): # 3 point coordinates
963 if len( aThreshold ) < 3:
964 raise ValueError("too few point coordinates, must be 3")
965 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
966 elif isinstance(aThreshold, str):
967 if aThreshold.isdigit():
968 aCriterion.Threshold = aThreshold # node id
970 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
972 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
973 "or a list of point coordinates and not '%s'"%aThreshold)
974 elif CritType == FT_ElemGeomType:
975 # Check the Threshold
977 aCriterion.Threshold = self.EnumToLong(aThreshold)
978 assert( aThreshold in SMESH.GeometryType._items )
980 if isinstance(aThreshold, int):
981 aCriterion.Threshold = aThreshold
983 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
986 elif CritType == FT_EntityType:
987 # Check the Threshold
989 aCriterion.Threshold = self.EnumToLong(aThreshold)
990 assert( aThreshold in SMESH.EntityType._items )
992 if isinstance(aThreshold, int):
993 aCriterion.Threshold = aThreshold
995 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
999 elif CritType == FT_GroupColor:
1000 # Check the Threshold
1002 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1004 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1006 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1007 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1008 FT_BareBorderFace, FT_BareBorderVolume,
1009 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1010 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1011 # At this point the Threshold is unnecessary
1012 if aThreshold == FT_LogicalNOT:
1013 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1014 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1015 aCriterion.BinaryOp = aThreshold
1019 aThreshold = float(aThreshold)
1020 aCriterion.Threshold = aThreshold
1022 raise TypeError("The Threshold should be a number.")
1025 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1026 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1028 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1029 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1031 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1032 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1034 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1035 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1039 def GetFilter(self,elementType,
1040 CritType=FT_Undefined,
1043 UnaryOp=FT_Undefined,
1047 Create a filter with the given parameters
1050 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1051 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1052 Note that the items starting from FT_LessThan are not suitable for CritType.
1053 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1054 Threshold: the threshold value (range of ids as string, shape, numeric)
1055 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1056 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1057 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1058 mesh: the mesh to initialize the filter with
1061 :class:`SMESH.Filter`
1064 See :doc:`Filters usage examples <tui_filters>`
1067 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1068 aFilterMgr = self.CreateFilterManager()
1069 aFilter = aFilterMgr.CreateFilter()
1071 aCriteria.append(aCriterion)
1072 aFilter.SetCriteria(aCriteria)
1074 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1075 else : aFilter.SetMesh( mesh )
1076 aFilterMgr.UnRegister()
1079 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1081 Create a filter from criteria
1084 criteria: a list of :class:`SMESH.Filter.Criterion`
1085 binOp: binary operator used when binary operator of criteria is undefined
1088 :class:`SMESH.Filter`
1091 See :doc:`Filters usage examples <tui_filters>`
1094 for i in range( len( criteria ) - 1 ):
1095 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1096 criteria[i].BinaryOp = self.EnumToLong( binOp )
1097 aFilterMgr = self.CreateFilterManager()
1098 aFilter = aFilterMgr.CreateFilter()
1099 aFilter.SetCriteria(criteria)
1100 aFilterMgr.UnRegister()
1103 def GetFunctor(self,theCriterion):
1105 Create a numerical functor by its type
1108 theCriterion (SMESH.FunctorType): functor type.
1109 Note that not all items correspond to numerical functors.
1112 :class:`SMESH.NumericalFunctor`
1115 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1117 aFilterMgr = self.CreateFilterManager()
1119 if theCriterion == FT_AspectRatio:
1120 functor = aFilterMgr.CreateAspectRatio()
1121 elif theCriterion == FT_AspectRatio3D:
1122 functor = aFilterMgr.CreateAspectRatio3D()
1123 elif theCriterion == FT_Warping:
1124 functor = aFilterMgr.CreateWarping()
1125 elif theCriterion == FT_MinimumAngle:
1126 functor = aFilterMgr.CreateMinimumAngle()
1127 elif theCriterion == FT_Taper:
1128 functor = aFilterMgr.CreateTaper()
1129 elif theCriterion == FT_Skew:
1130 functor = aFilterMgr.CreateSkew()
1131 elif theCriterion == FT_Area:
1132 functor = aFilterMgr.CreateArea()
1133 elif theCriterion == FT_Volume3D:
1134 functor = aFilterMgr.CreateVolume3D()
1135 elif theCriterion == FT_MaxElementLength2D:
1136 functor = aFilterMgr.CreateMaxElementLength2D()
1137 elif theCriterion == FT_MaxElementLength3D:
1138 functor = aFilterMgr.CreateMaxElementLength3D()
1139 elif theCriterion == FT_MultiConnection:
1140 functor = aFilterMgr.CreateMultiConnection()
1141 elif theCriterion == FT_MultiConnection2D:
1142 functor = aFilterMgr.CreateMultiConnection2D()
1143 elif theCriterion == FT_Length:
1144 functor = aFilterMgr.CreateLength()
1145 elif theCriterion == FT_Length2D:
1146 functor = aFilterMgr.CreateLength2D()
1147 elif theCriterion == FT_Deflection2D:
1148 functor = aFilterMgr.CreateDeflection2D()
1149 elif theCriterion == FT_NodeConnectivityNumber:
1150 functor = aFilterMgr.CreateNodeConnectivityNumber()
1151 elif theCriterion == FT_BallDiameter:
1152 functor = aFilterMgr.CreateBallDiameter()
1154 print("Error: given parameter is not numerical functor type.")
1155 aFilterMgr.UnRegister()
1158 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1163 theHType (string): mesh hypothesis type
1164 theLibName (string): mesh plug-in library name
1167 created hypothesis instance
1169 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1171 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1174 # wrap hypothesis methods
1175 for meth_name in dir( hyp.__class__ ):
1176 if not meth_name.startswith("Get") and \
1177 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1178 method = getattr ( hyp.__class__, meth_name )
1179 if callable(method):
1180 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1184 def GetMeshInfo(self, obj):
1186 Get the mesh statistic.
1187 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
1188 an item of :class:`SMESH.EntityType`.
1191 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1194 if isinstance( obj, Mesh ):
1197 if hasattr(obj, "GetMeshInfo"):
1198 values = obj.GetMeshInfo()
1199 for i in range(SMESH.Entity_Last._v):
1200 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1204 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1206 Get minimum distance between two objects
1208 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1209 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1212 src1 (SMESH.SMESH_IDSource): first source object
1213 src2 (SMESH.SMESH_IDSource): second source object
1214 id1 (int): node/element id from the first source
1215 id2 (int): node/element id from the second (or first) source
1216 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1217 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1220 minimum distance value
1223 :meth:`GetMinDistance`
1226 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1230 result = result.value
1233 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1235 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1237 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1238 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1241 src1 (SMESH.SMESH_IDSource): first source object
1242 src2 (SMESH.SMESH_IDSource): second source object
1243 id1 (int): node/element id from the first source
1244 id2 (int): node/element id from the second (or first) source
1245 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1246 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1249 :class:`SMESH.Measure` structure or None if input data is invalid
1254 if isinstance(src1, Mesh): src1 = src1.mesh
1255 if isinstance(src2, Mesh): src2 = src2.mesh
1256 if src2 is None and id2 != 0: src2 = src1
1257 if not hasattr(src1, "_narrow"): return None
1258 src1 = src1._narrow(SMESH.SMESH_IDSource)
1259 if not src1: return None
1260 unRegister = genObjUnRegister()
1263 e = m.GetMeshEditor()
1265 src1 = e.MakeIDSource([id1], SMESH.FACE)
1267 src1 = e.MakeIDSource([id1], SMESH.NODE)
1268 unRegister.set( src1 )
1270 if hasattr(src2, "_narrow"):
1271 src2 = src2._narrow(SMESH.SMESH_IDSource)
1272 if src2 and id2 != 0:
1274 e = m.GetMeshEditor()
1276 src2 = e.MakeIDSource([id2], SMESH.FACE)
1278 src2 = e.MakeIDSource([id2], SMESH.NODE)
1279 unRegister.set( src2 )
1282 aMeasurements = self.CreateMeasurements()
1283 unRegister.set( aMeasurements )
1284 result = aMeasurements.MinDistance(src1, src2)
1287 def BoundingBox(self, objects):
1289 Get bounding box of the specified object(s)
1292 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1295 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1298 :meth:`GetBoundingBox`
1301 result = self.GetBoundingBox(objects)
1305 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1308 def GetBoundingBox(self, objects):
1310 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1313 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1316 :class:`SMESH.Measure` structure
1322 if isinstance(objects, tuple):
1323 objects = list(objects)
1324 if not isinstance(objects, list):
1328 if isinstance(o, Mesh):
1329 srclist.append(o.mesh)
1330 elif hasattr(o, "_narrow"):
1331 src = o._narrow(SMESH.SMESH_IDSource)
1332 if src: srclist.append(src)
1335 aMeasurements = self.CreateMeasurements()
1336 result = aMeasurements.BoundingBox(srclist)
1337 aMeasurements.UnRegister()
1340 def GetLength(self, obj):
1342 Get sum of lengths of all 1D elements in the mesh object.
1345 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1348 sum of lengths of all 1D elements
1351 if isinstance(obj, Mesh): obj = obj.mesh
1352 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1353 aMeasurements = self.CreateMeasurements()
1354 value = aMeasurements.Length(obj)
1355 aMeasurements.UnRegister()
1358 def GetArea(self, obj):
1360 Get sum of areas of all 2D elements in the mesh object.
1363 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1366 sum of areas of all 2D elements
1369 if isinstance(obj, Mesh): obj = obj.mesh
1370 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1371 aMeasurements = self.CreateMeasurements()
1372 value = aMeasurements.Area(obj)
1373 aMeasurements.UnRegister()
1376 def GetVolume(self, obj):
1378 Get sum of volumes of all 3D elements in the mesh object.
1381 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1384 sum of volumes of all 3D elements
1387 if isinstance(obj, Mesh): obj = obj.mesh
1388 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1389 aMeasurements = self.CreateMeasurements()
1390 value = aMeasurements.Volume(obj)
1391 aMeasurements.UnRegister()
1394 def GetGravityCenter(self, obj):
1396 Get gravity center of all nodes of the mesh object.
1399 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1402 Three components of the gravity center (x,y,z)
1404 if isinstance(obj, Mesh): obj = obj.mesh
1405 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1406 aMeasurements = self.CreateMeasurements()
1407 pointStruct = aMeasurements.GravityCenter(obj)
1408 aMeasurements.UnRegister()
1409 return pointStruct.x, pointStruct.y, pointStruct.z
1411 pass # end of class smeshBuilder
1414 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1415 """Registering the new proxy for SMESH.SMESH_Gen"""
1418 def New( instance=None, instanceGeom=None):
1420 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1421 interface to create or load meshes.
1426 salome.salome_init()
1427 from salome.smesh import smeshBuilder
1428 smesh = smeshBuilder.New()
1431 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1432 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1434 :class:`smeshBuilder` instance
1439 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1441 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1446 smeshInst = smeshBuilder()
1447 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1448 smeshInst.init_smesh(instanceGeom)
1452 # Public class: Mesh
1453 # ==================
1456 class Mesh(metaclass = MeshMeta):
1458 This class allows defining and managing a mesh.
1459 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1460 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1461 new nodes and elements and by changing the existing entities), to get information
1462 about a mesh and to export a mesh in different formats.
1469 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1474 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1475 sets the GUI name of this mesh to *name*.
1478 smeshpyD: an instance of smeshBuilder class
1479 geompyD: an instance of geomBuilder class
1480 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1481 name: Study name of the mesh
1484 self.smeshpyD = smeshpyD
1485 self.geompyD = geompyD
1490 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1493 # publish geom of mesh (issue 0021122)
1494 if not self.geom.GetStudyEntry():
1498 geo_name = name + " shape"
1500 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1501 geompyD.addToStudy( self.geom, geo_name )
1502 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1504 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1507 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1509 self.smeshpyD.SetName(self.mesh, name)
1511 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1514 self.geom = self.mesh.GetShapeToMesh()
1516 self.editor = self.mesh.GetMeshEditor()
1517 self.functors = [None] * SMESH.FT_Undefined._v
1519 # set self to algoCreator's
1520 for attrName in dir(self):
1521 attr = getattr( self, attrName )
1522 if isinstance( attr, algoCreator ):
1523 setattr( self, attrName, attr.copy( self ))
1530 Destructor. Clean-up resources
1533 #self.mesh.UnRegister()
1537 def SetMesh(self, theMesh):
1539 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1542 theMesh: a :class:`SMESH.SMESH_Mesh` object
1546 # do not call Register() as this prevents mesh servant deletion at closing study
1547 #if self.mesh: self.mesh.UnRegister()
1550 #self.mesh.Register()
1551 self.geom = self.mesh.GetShapeToMesh()
1556 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1559 a :class:`SMESH.SMESH_Mesh` object
1566 Get the name of the mesh
1569 the name of the mesh as a string
1572 name = GetName(self.GetMesh())
1575 def SetName(self, name):
1577 Set a name to the mesh
1580 name: a new name of the mesh
1583 self.smeshpyD.SetName(self.GetMesh(), name)
1585 def GetSubMesh(self, geom, name):
1587 Get a sub-mesh object associated to a *geom* geometrical object.
1590 geom: a geometrical object (shape)
1591 name: a name for the sub-mesh in the Object Browser
1594 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1595 which lies on the given shape
1598 A sub-mesh is implicitly created when a sub-shape is specified at
1599 creating an algorithm, for example::
1601 algo1D = mesh.Segment(geom=Edge_1)
1603 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1604 The created sub-mesh can be retrieved from the algorithm::
1606 submesh = algo1D.GetSubMesh()
1609 AssureGeomPublished( self, geom, name )
1610 submesh = self.mesh.GetSubMesh( geom, name )
1615 Return the shape associated to the mesh
1623 def SetShape(self, geom):
1625 Associate the given shape to the mesh (entails the recreation of the mesh)
1628 geom: the shape to be meshed (GEOM_Object)
1631 self.mesh = self.smeshpyD.CreateMesh(geom)
1633 def HasShapeToMesh(self):
1635 Return ``True`` if this mesh is based on geometry
1637 return self.mesh.HasShapeToMesh()
1641 Load mesh from the study after opening the study
1645 def IsReadyToCompute(self, theSubObject):
1647 Return true if the hypotheses are defined well
1650 theSubObject: a sub-shape of a mesh shape
1656 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1658 def GetAlgoState(self, theSubObject):
1660 Return errors of hypotheses definition.
1661 The list of errors is empty if everything is OK.
1664 theSubObject: a sub-shape of a mesh shape
1670 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1672 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1674 Return a geometrical object on which the given element was built.
1675 The returned geometrical object, if not nil, is either found in the
1676 study or published by this method with the given name
1679 theElementID: the id of the mesh element
1680 theGeomName: the user-defined name of the geometrical object
1683 GEOM.GEOM_Object instance
1686 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1688 def MeshDimension(self):
1690 Return the mesh dimension depending on the dimension of the underlying shape
1691 or, if the mesh is not based on any shape, basing on deimension of elements
1694 mesh dimension as an integer value [0,3]
1697 if self.mesh.HasShapeToMesh():
1698 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1699 if len( shells ) > 0 :
1701 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1703 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1708 if self.NbVolumes() > 0: return 3
1709 if self.NbFaces() > 0: return 2
1710 if self.NbEdges() > 0: return 1
1713 def Evaluate(self, geom=0):
1715 Evaluate size of prospective mesh on a shape
1718 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1719 To know predicted number of e.g. edges, inquire it this way::
1721 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1724 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1726 geom = self.mesh.GetShapeToMesh()
1729 return self.smeshpyD.Evaluate(self.mesh, geom)
1732 def Compute(self, geom=0, discardModifs=False, refresh=False):
1734 Compute the mesh and return the status of the computation
1737 geom: geomtrical shape on which mesh data should be computed
1738 discardModifs: if True and the mesh has been edited since
1739 a last total re-compute and that may prevent successful partial re-compute,
1740 then the mesh is cleaned before Compute()
1741 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1747 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1749 geom = self.mesh.GetShapeToMesh()
1754 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1756 ok = self.smeshpyD.Compute(self.mesh, geom)
1757 except SALOME.SALOME_Exception as ex:
1758 print("Mesh computation failed, exception caught:")
1759 print(" ", ex.details.text)
1762 print("Mesh computation failed, exception caught:")
1763 traceback.print_exc()
1767 # Treat compute errors
1768 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1770 for err in computeErrors:
1771 if self.mesh.HasShapeToMesh():
1772 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1774 stdErrors = ["OK", #COMPERR_OK
1775 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1776 "std::exception", #COMPERR_STD_EXCEPTION
1777 "OCC exception", #COMPERR_OCC_EXCEPTION
1778 "..", #COMPERR_SLM_EXCEPTION
1779 "Unknown exception", #COMPERR_EXCEPTION
1780 "Memory allocation problem", #COMPERR_MEMORY_PB
1781 "Algorithm failed", #COMPERR_ALGO_FAILED
1782 "Unexpected geometry", #COMPERR_BAD_SHAPE
1783 "Warning", #COMPERR_WARNING
1784 "Computation cancelled",#COMPERR_CANCELED
1785 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1787 if err.code < len(stdErrors): errText = stdErrors[err.code]
1789 errText = "code %s" % -err.code
1790 if errText: errText += ". "
1791 errText += err.comment
1792 if allReasons: allReasons += "\n"
1794 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1796 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1800 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1802 if err.isGlobalAlgo:
1810 reason = '%s %sD algorithm is missing' % (glob, dim)
1811 elif err.state == HYP_MISSING:
1812 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1813 % (glob, dim, name, dim))
1814 elif err.state == HYP_NOTCONFORM:
1815 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1816 elif err.state == HYP_BAD_PARAMETER:
1817 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1818 % ( glob, dim, name ))
1819 elif err.state == HYP_BAD_GEOMETRY:
1820 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1821 'geometry' % ( glob, dim, name ))
1822 elif err.state == HYP_HIDDEN_ALGO:
1823 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1824 'algorithm of upper dimension generating %sD mesh'
1825 % ( glob, dim, name, glob, dim ))
1827 reason = ("For unknown reason. "
1828 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1830 if allReasons: allReasons += "\n"
1831 allReasons += "- " + reason
1833 if not ok or allReasons != "":
1834 msg = '"' + GetName(self.mesh) + '"'
1835 if ok: msg += " has been computed with warnings"
1836 else: msg += " has not been computed"
1837 if allReasons != "": msg += ":"
1842 if salome.sg.hasDesktop():
1843 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1844 if refresh: salome.sg.updateObjBrowser()
1848 def GetComputeErrors(self, shape=0 ):
1850 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1854 shape = self.mesh.GetShapeToMesh()
1855 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1857 def GetSubShapeName(self, subShapeID ):
1859 Return a name of a sub-shape by its ID.
1860 Possible variants (for *subShapeID* == 3):
1862 - **"Face_12"** - published sub-shape
1863 - **FACE #3** - not published sub-shape
1864 - **sub-shape #3** - invalid sub-shape ID
1865 - **#3** - error in this function
1868 subShapeID: a unique ID of a sub-shape
1871 a string describing the sub-shape
1875 if not self.mesh.HasShapeToMesh():
1879 mainIOR = salome.orb.object_to_string( self.GetShape() )
1881 mainSO = s.FindObjectIOR(mainIOR)
1884 shapeText = '"%s"' % mainSO.GetName()
1885 subIt = s.NewChildIterator(mainSO)
1887 subSO = subIt.Value()
1889 obj = subSO.GetObject()
1890 if not obj: continue
1891 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1894 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1897 if ids == subShapeID:
1898 shapeText = '"%s"' % subSO.GetName()
1901 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
1903 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
1905 shapeText = 'sub-shape #%s' % (subShapeID)
1907 shapeText = "#%s" % (subShapeID)
1910 def GetFailedShapes(self, publish=False):
1912 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
1913 error of an algorithm
1916 publish: if *True*, the returned groups will be published in the study
1919 a list of GEOM groups each named after a failed algorithm
1924 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
1925 for err in computeErrors:
1926 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
1927 if not shape: continue
1928 if err.algoName in algo2shapes:
1929 algo2shapes[ err.algoName ].append( shape )
1931 algo2shapes[ err.algoName ] = [ shape ]
1935 for algoName, shapes in list(algo2shapes.items()):
1937 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
1938 otherTypeShapes = []
1940 group = self.geompyD.CreateGroup( self.geom, groupType )
1941 for shape in shapes:
1942 if shape.GetShapeType() == shapes[0].GetShapeType():
1943 sameTypeShapes.append( shape )
1945 otherTypeShapes.append( shape )
1946 self.geompyD.UnionList( group, sameTypeShapes )
1948 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
1950 group.SetName( algoName )
1951 groups.append( group )
1952 shapes = otherTypeShapes
1955 for group in groups:
1956 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
1959 def GetMeshOrder(self):
1961 Return sub-mesh objects list in meshing order
1964 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
1967 return self.mesh.GetMeshOrder()
1969 def SetMeshOrder(self, submeshes):
1971 Set order in which concurrent sub-meshes should be meshed
1974 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
1977 return self.mesh.SetMeshOrder(submeshes)
1979 def Clear(self, refresh=False):
1981 Remove all nodes and elements generated on geometry. Imported elements remain.
1984 refresh: if *True*, Object browser is automatically updated (when running in GUI)
1988 if ( salome.sg.hasDesktop() ):
1989 if refresh: salome.sg.updateObjBrowser()
1991 def ClearSubMesh(self, geomId, refresh=False):
1993 Remove all nodes and elements of indicated shape
1996 geomId: the ID of a sub-shape to remove elements on
1997 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2000 self.mesh.ClearSubMesh(geomId)
2001 if salome.sg.hasDesktop():
2002 if refresh: salome.sg.updateObjBrowser()
2004 def AutomaticTetrahedralization(self, fineness=0):
2006 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2009 fineness: [0.0,1.0] defines mesh fineness
2015 dim = self.MeshDimension()
2017 self.RemoveGlobalHypotheses()
2018 self.Segment().AutomaticLength(fineness)
2020 self.Triangle().LengthFromEdges()
2025 return self.Compute()
2027 def AutomaticHexahedralization(self, fineness=0):
2029 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2032 fineness: [0.0, 1.0] defines mesh fineness
2038 dim = self.MeshDimension()
2039 # assign the hypotheses
2040 self.RemoveGlobalHypotheses()
2041 self.Segment().AutomaticLength(fineness)
2048 return self.Compute()
2050 def AddHypothesis(self, hyp, geom=0):
2055 hyp: a hypothesis to assign
2056 geom: a subhape of mesh geometry
2059 :class:`SMESH.Hypothesis_Status`
2062 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2063 hyp, geom = geom, hyp
2064 if isinstance( hyp, Mesh_Algorithm ):
2065 hyp = hyp.GetAlgorithm()
2070 geom = self.mesh.GetShapeToMesh()
2073 if self.mesh.HasShapeToMesh():
2074 hyp_type = hyp.GetName()
2075 lib_name = hyp.GetLibName()
2076 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2077 # if checkAll and geom:
2078 # checkAll = geom.GetType() == 37
2080 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2082 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2083 status = self.mesh.AddHypothesis(geom, hyp)
2085 status = HYP_BAD_GEOMETRY, ""
2086 hyp_name = GetName( hyp )
2089 geom_name = geom.GetName()
2090 isAlgo = hyp._narrow( SMESH_Algo )
2091 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2094 def IsUsedHypothesis(self, hyp, geom):
2096 Return True if an algorithm or hypothesis is assigned to a given shape
2099 hyp: an algorithm or hypothesis to check
2100 geom: a subhape of mesh geometry
2106 if not hyp: # or not geom
2108 if isinstance( hyp, Mesh_Algorithm ):
2109 hyp = hyp.GetAlgorithm()
2111 hyps = self.GetHypothesisList(geom)
2113 if h.GetId() == hyp.GetId():
2117 def RemoveHypothesis(self, hyp, geom=0):
2119 Unassign a hypothesis
2122 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2123 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2126 :class:`SMESH.Hypothesis_Status`
2131 if isinstance( hyp, Mesh_Algorithm ):
2132 hyp = hyp.GetAlgorithm()
2138 if self.IsUsedHypothesis( hyp, shape ):
2139 return self.mesh.RemoveHypothesis( shape, hyp )
2140 hypName = GetName( hyp )
2141 geoName = GetName( shape )
2142 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2145 def GetHypothesisList(self, geom):
2147 Get the list of hypotheses added on a geometry
2150 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2153 the sequence of :class:`SMESH.SMESH_Hypothesis`
2156 return self.mesh.GetHypothesisList( geom )
2158 def RemoveGlobalHypotheses(self):
2160 Remove all global hypotheses
2163 current_hyps = self.mesh.GetHypothesisList( self.geom )
2164 for hyp in current_hyps:
2165 self.mesh.RemoveHypothesis( self.geom, hyp )
2168 def ExportMED(self, *args, **kwargs):
2170 Export the mesh in a file in MED format
2171 allowing to overwrite the file if it exists or add the exported data to its contents
2174 fileName: is the file name
2175 auto_groups (boolean): parameter for creating/not creating
2176 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2177 the typical use is auto_groups=False.
2178 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2179 The minor must be between 0 and the current minor version of MED file library.
2180 If minor is equal to -1, the minor version is not changed (default).
2181 The major version (x, where version is x.y.z) cannot be changed.
2182 overwrite (boolean): parameter for overwriting/not overwriting the file
2183 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2184 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2186 - 1D if all mesh nodes lie on OX coordinate axis, or
2187 - 2D if all mesh nodes lie on XOY coordinate plane, or
2188 - 3D in the rest cases.
2190 If *autoDimension* is *False*, the space dimension is always 3.
2191 fields: list of GEOM fields defined on the shape to mesh.
2192 geomAssocFields: each character of this string means a need to export a
2193 corresponding field; correspondence between fields and characters is following:
2195 - 'v' stands for "_vertices_" field;
2196 - 'e' stands for "_edges_" field;
2197 - 'f' stands for "_faces_" field;
2198 - 's' stands for "_solids_" field.
2200 # process positional arguments
2201 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2203 auto_groups = args[1] if len(args) > 1 else False
2204 minor = args[2] if len(args) > 2 else -1
2205 overwrite = args[3] if len(args) > 3 else True
2206 meshPart = args[4] if len(args) > 4 else None
2207 autoDimension = args[5] if len(args) > 5 else True
2208 fields = args[6] if len(args) > 6 else []
2209 geomAssocFields = args[7] if len(args) > 7 else ''
2210 # process keywords arguments
2211 auto_groups = kwargs.get("auto_groups", auto_groups)
2212 minor = kwargs.get("minor", minor)
2213 overwrite = kwargs.get("overwrite", overwrite)
2214 meshPart = kwargs.get("meshPart", meshPart)
2215 autoDimension = kwargs.get("autoDimension", autoDimension)
2216 fields = kwargs.get("fields", fields)
2217 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2218 # invoke engine's function
2219 if meshPart or fields or geomAssocFields:
2220 unRegister = genObjUnRegister()
2221 if isinstance( meshPart, list ):
2222 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2223 unRegister.set( meshPart )
2224 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2225 fields, geomAssocFields)
2227 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2229 def ExportSAUV(self, f, auto_groups=0):
2231 Export the mesh in a file in SAUV format
2236 auto_groups: boolean parameter for creating/not creating
2237 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2238 the typical use is auto_groups=False.
2241 self.mesh.ExportSAUV(f, auto_groups)
2243 def ExportDAT(self, f, meshPart=None):
2245 Export the mesh in a file in DAT format
2249 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2253 unRegister = genObjUnRegister()
2254 if isinstance( meshPart, list ):
2255 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2256 unRegister.set( meshPart )
2257 self.mesh.ExportPartToDAT( meshPart, f )
2259 self.mesh.ExportDAT(f)
2261 def ExportUNV(self, f, meshPart=None):
2263 Export the mesh in a file in UNV format
2267 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2271 unRegister = genObjUnRegister()
2272 if isinstance( meshPart, list ):
2273 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2274 unRegister.set( meshPart )
2275 self.mesh.ExportPartToUNV( meshPart, f )
2277 self.mesh.ExportUNV(f)
2279 def ExportSTL(self, f, ascii=1, meshPart=None):
2281 Export the mesh in a file in STL format
2285 ascii: defines the file encoding
2286 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2290 unRegister = genObjUnRegister()
2291 if isinstance( meshPart, list ):
2292 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2293 unRegister.set( meshPart )
2294 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2296 self.mesh.ExportSTL(f, ascii)
2298 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2300 Export the mesh in a file in CGNS format
2304 overwrite: boolean parameter for overwriting/not overwriting the file
2305 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2306 groupElemsByType: if True all elements of same entity type are exported at ones,
2307 else elements are exported in order of their IDs which can cause creation
2308 of multiple cgns sections
2311 unRegister = genObjUnRegister()
2312 if isinstance( meshPart, list ):
2313 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2314 unRegister.set( meshPart )
2315 if isinstance( meshPart, Mesh ):
2316 meshPart = meshPart.mesh
2318 meshPart = self.mesh
2319 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2321 def ExportGMF(self, f, meshPart=None):
2323 Export the mesh in a file in GMF format.
2324 GMF files must have .mesh extension for the ASCII format and .meshb for
2325 the bynary format. Other extensions are not allowed.
2329 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2332 unRegister = genObjUnRegister()
2333 if isinstance( meshPart, list ):
2334 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2335 unRegister.set( meshPart )
2336 if isinstance( meshPart, Mesh ):
2337 meshPart = meshPart.mesh
2339 meshPart = self.mesh
2340 self.mesh.ExportGMF(meshPart, f, True)
2342 def ExportToMED(self, *args, **kwargs):
2344 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2345 Export the mesh in a file in MED format
2346 allowing to overwrite the file if it exists or add the exported data to its contents
2349 fileName: the file name
2350 opt (boolean): parameter for creating/not creating
2351 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2352 overwrite: boolean parameter for overwriting/not overwriting the file
2353 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2355 - 1D if all mesh nodes lie on OX coordinate axis, or
2356 - 2D if all mesh nodes lie on XOY coordinate plane, or
2357 - 3D in the rest cases.
2359 If **autoDimension** is *False*, the space dimension is always 3.
2362 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2363 # process positional arguments
2364 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2366 auto_groups = args[1] if len(args) > 1 else False
2367 overwrite = args[2] if len(args) > 2 else True
2368 autoDimension = args[3] if len(args) > 3 else True
2369 # process keywords arguments
2370 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2371 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2372 overwrite = kwargs.get("overwrite", overwrite)
2373 autoDimension = kwargs.get("autoDimension", autoDimension)
2375 # invoke engine's function
2376 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2378 def ExportToMEDX(self, *args, **kwargs):
2380 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2381 Export the mesh in a file in MED format
2384 fileName: the file name
2385 opt (boolean): parameter for creating/not creating
2386 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2387 overwrite: boolean parameter for overwriting/not overwriting the file
2388 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2390 - 1D if all mesh nodes lie on OX coordinate axis, or
2391 - 2D if all mesh nodes lie on XOY coordinate plane, or
2392 - 3D in the rest cases.
2394 If **autoDimension** is *False*, the space dimension is always 3.
2397 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2398 # process positional arguments
2399 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2401 auto_groups = args[1] if len(args) > 1 else False
2402 overwrite = args[2] if len(args) > 2 else True
2403 autoDimension = args[3] if len(args) > 3 else True
2404 # process keywords arguments
2405 auto_groups = kwargs.get("auto_groups", auto_groups)
2406 overwrite = kwargs.get("overwrite", overwrite)
2407 autoDimension = kwargs.get("autoDimension", autoDimension)
2409 # invoke engine's function
2410 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2412 # Operations with groups:
2413 # ----------------------
2414 def CreateEmptyGroup(self, elementType, name):
2416 Create an empty standalone mesh group
2419 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2420 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2421 name: the name of the mesh group
2424 :class:`SMESH.SMESH_Group`
2427 return self.mesh.CreateGroup(elementType, name)
2429 def Group(self, grp, name=""):
2431 Create a mesh group based on the geometric object *grp*
2432 and give it a *name*.
2433 If *name* is not defined the name of the geometric group is used
2436 Works like :meth:`GroupOnGeom`.
2439 grp: a geometric group, a vertex, an edge, a face or a solid
2440 name: the name of the mesh group
2443 :class:`SMESH.SMESH_GroupOnGeom`
2446 return self.GroupOnGeom(grp, name)
2448 def GroupOnGeom(self, grp, name="", typ=None):
2450 Create a mesh group based on the geometrical object *grp*
2451 and give it a *name*.
2452 if *name* is not defined the name of the geometric group is used
2455 grp: a geometrical group, a vertex, an edge, a face or a solid
2456 name: the name of the mesh group
2457 typ: the type of elements in the group; either of
2458 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2459 automatically detected by the type of the geometry
2462 :class:`SMESH.SMESH_GroupOnGeom`
2465 AssureGeomPublished( self, grp, name )
2467 name = grp.GetName()
2469 typ = self._groupTypeFromShape( grp )
2470 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2472 def _groupTypeFromShape( self, shape ):
2474 Pivate method to get a type of group on geometry
2476 tgeo = str(shape.GetShapeType())
2477 if tgeo == "VERTEX":
2479 elif tgeo == "EDGE":
2481 elif tgeo == "FACE" or tgeo == "SHELL":
2483 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2485 elif tgeo == "COMPOUND":
2486 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2488 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2489 return self._groupTypeFromShape( sub[0] )
2491 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2494 def GroupOnFilter(self, typ, name, filter):
2496 Create a mesh group with given *name* based on the *filter*.
2497 It is a special type of group dynamically updating it's contents during
2501 typ: the type of elements in the group; either of
2502 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2503 name: the name of the mesh group
2504 filter (SMESH.Filter): the filter defining group contents
2507 :class:`SMESH.SMESH_GroupOnFilter`
2510 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2512 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2514 Create a mesh group by the given ids of elements
2517 groupName: the name of the mesh group
2518 elementType: the type of elements in the group; either of
2519 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2520 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2523 :class:`SMESH.SMESH_Group`
2526 group = self.mesh.CreateGroup(elementType, groupName)
2527 if isinstance( elemIDs, Mesh ):
2528 elemIDs = elemIDs.GetMesh()
2529 if hasattr( elemIDs, "GetIDs" ):
2530 if hasattr( elemIDs, "SetMesh" ):
2531 elemIDs.SetMesh( self.GetMesh() )
2532 group.AddFrom( elemIDs )
2540 CritType=FT_Undefined,
2543 UnaryOp=FT_Undefined,
2546 Create a mesh group by the given conditions
2549 groupName: the name of the mesh group
2550 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2551 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2552 Note that the items starting from FT_LessThan are not suitable for CritType.
2553 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2554 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2555 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2556 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2557 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2560 :class:`SMESH.SMESH_GroupOnFilter`
2563 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2564 group = self.MakeGroupByCriterion(groupName, aCriterion)
2567 def MakeGroupByCriterion(self, groupName, Criterion):
2569 Create a mesh group by the given criterion
2572 groupName: the name of the mesh group
2573 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2576 :class:`SMESH.SMESH_GroupOnFilter`
2579 :meth:`smeshBuilder.GetCriterion`
2582 return self.MakeGroupByCriteria( groupName, [Criterion] )
2584 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2586 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2589 groupName: the name of the mesh group
2590 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2591 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2594 :class:`SMESH.SMESH_GroupOnFilter`
2597 :meth:`smeshBuilder.GetCriterion`
2600 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2601 group = self.MakeGroupByFilter(groupName, aFilter)
2604 def MakeGroupByFilter(self, groupName, theFilter):
2606 Create a mesh group by the given filter
2609 groupName (string): the name of the mesh group
2610 theFilter (SMESH.Filter): the filter
2613 :class:`SMESH.SMESH_GroupOnFilter`
2616 :meth:`smeshBuilder.GetFilter`
2619 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2620 #theFilter.SetMesh( self.mesh )
2621 #group.AddFrom( theFilter )
2622 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2625 def RemoveGroup(self, group):
2630 group (SMESH.SMESH_GroupBase): group to remove
2633 self.mesh.RemoveGroup(group)
2635 def RemoveGroupWithContents(self, group):
2637 Remove a group with its contents
2640 group (SMESH.SMESH_GroupBase): group to remove
2643 self.mesh.RemoveGroupWithContents(group)
2645 def GetGroups(self, elemType = SMESH.ALL):
2647 Get the list of groups existing in the mesh in the order of creation
2648 (starting from the oldest one)
2651 elemType (SMESH.ElementType): type of elements the groups contain;
2652 by default groups of elements of all types are returned
2655 a list of :class:`SMESH.SMESH_GroupBase`
2658 groups = self.mesh.GetGroups()
2659 if elemType == SMESH.ALL:
2663 if g.GetType() == elemType:
2664 typedGroups.append( g )
2671 Get the number of groups existing in the mesh
2674 the quantity of groups as an integer value
2677 return self.mesh.NbGroups()
2679 def GetGroupNames(self):
2681 Get the list of names of groups existing in the mesh
2687 groups = self.GetGroups()
2689 for group in groups:
2690 names.append(group.GetName())
2693 def GetGroupByName(self, name, elemType = None):
2695 Find groups by name and type
2698 name (string): name of the group of interest
2699 elemType (SMESH.ElementType): type of elements the groups contain;
2700 by default one group of any type is returned;
2701 if elemType == SMESH.ALL then all groups of any type are returned
2704 a list of :class:`SMESH.SMESH_GroupBase`
2708 for group in self.GetGroups():
2709 if group.GetName() == name:
2710 if elemType is None:
2712 if ( elemType == SMESH.ALL or
2713 group.GetType() == elemType ):
2714 groups.append( group )
2717 def UnionGroups(self, group1, group2, name):
2719 Produce a union of two groups.
2720 A new group is created. All mesh elements that are
2721 present in the initial groups are added to the new one
2724 group1 (SMESH.SMESH_GroupBase): a group
2725 group2 (SMESH.SMESH_GroupBase): another group
2728 instance of :class:`SMESH.SMESH_Group`
2731 return self.mesh.UnionGroups(group1, group2, name)
2733 def UnionListOfGroups(self, groups, name):
2735 Produce a union list of groups.
2736 New group is created. All mesh elements that are present in
2737 initial groups are added to the new one
2740 groups: list of :class:`SMESH.SMESH_GroupBase`
2743 instance of :class:`SMESH.SMESH_Group`
2745 return self.mesh.UnionListOfGroups(groups, name)
2747 def IntersectGroups(self, group1, group2, name):
2749 Prodice an intersection of two groups.
2750 A new group is created. All mesh elements that are common
2751 for the two initial groups are added to the new one.
2754 group1 (SMESH.SMESH_GroupBase): a group
2755 group2 (SMESH.SMESH_GroupBase): another group
2758 instance of :class:`SMESH.SMESH_Group`
2761 return self.mesh.IntersectGroups(group1, group2, name)
2763 def IntersectListOfGroups(self, groups, name):
2765 Produce an intersection of groups.
2766 New group is created. All mesh elements that are present in all
2767 initial groups simultaneously are added to the new one
2770 groups: a list of :class:`SMESH.SMESH_GroupBase`
2773 instance of :class:`SMESH.SMESH_Group`
2775 return self.mesh.IntersectListOfGroups(groups, name)
2777 def CutGroups(self, main_group, tool_group, name):
2779 Produce a cut of two groups.
2780 A new group is created. All mesh elements that are present in
2781 the main group but are not present in the tool group are added to the new one
2784 main_group (SMESH.SMESH_GroupBase): a group to cut from
2785 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2788 an instance of :class:`SMESH.SMESH_Group`
2791 return self.mesh.CutGroups(main_group, tool_group, name)
2793 def CutListOfGroups(self, main_groups, tool_groups, name):
2795 Produce a cut of groups.
2796 A new group is created. All mesh elements that are present in main groups
2797 but do not present in tool groups are added to the new one
2800 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2801 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2804 an instance of :class:`SMESH.SMESH_Group`
2807 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2809 def CreateDimGroup(self, groups, elemType, name,
2810 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2812 Create a standalone group of entities basing on nodes of other groups.
2815 groups: list of reference :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2816 elemType: a type of elements to include to the new group; either of
2817 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2818 name: a name of the new group.
2819 nbCommonNodes: a criterion of inclusion of an element to the new group
2820 basing on number of element nodes common with reference *groups*.
2821 Meaning of possible values are:
2823 - SMESH.ALL_NODES - include if all nodes are common,
2824 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2825 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2826 - SMEHS.MAJORITY - include if half of nodes or more are common.
2827 underlyingOnly: if *True* (default), an element is included to the
2828 new group provided that it is based on nodes of an element of *groups*;
2829 in this case the reference *groups* are supposed to be of higher dimension
2830 than *elemType*, which can be useful for example to get all faces lying on
2831 volumes of the reference *groups*.
2834 an instance of :class:`SMESH.SMESH_Group`
2837 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2839 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2842 def ConvertToStandalone(self, group):
2844 Convert group on geom into standalone group
2847 return self.mesh.ConvertToStandalone(group)
2849 # Get some info about mesh:
2850 # ------------------------
2852 def GetLog(self, clearAfterGet):
2854 Return the log of nodes and elements added or removed
2855 since the previous clear of the log.
2858 clearAfterGet: log is emptied after Get (safe if concurrents access)
2861 list of SMESH.log_block structures { commandType, number, coords, indexes }
2864 return self.mesh.GetLog(clearAfterGet)
2868 Clear the log of nodes and elements added or removed since the previous
2869 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
2872 self.mesh.ClearLog()
2874 def SetAutoColor(self, theAutoColor):
2876 Toggle auto color mode on the object.
2877 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
2880 theAutoColor (boolean): the flag which toggles auto color mode.
2883 self.mesh.SetAutoColor(theAutoColor)
2885 def GetAutoColor(self):
2887 Get flag of object auto color mode.
2893 return self.mesh.GetAutoColor()
2900 integer value, which is the internal Id of the mesh
2903 return self.mesh.GetId()
2905 def HasDuplicatedGroupNamesMED(self):
2907 Check the group names for duplications.
2908 Consider the maximum group name length stored in MED file.
2914 return self.mesh.HasDuplicatedGroupNamesMED()
2916 def GetMeshEditor(self):
2918 Obtain the mesh editor tool
2921 an instance of :class:`SMESH.SMESH_MeshEditor`
2926 def GetIDSource(self, ids, elemType = SMESH.ALL):
2928 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
2929 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2933 elemType: type of elements; this parameter is used to distinguish
2934 IDs of nodes from IDs of elements; by default ids are treated as
2935 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
2938 an instance of :class:`SMESH.SMESH_IDSource`
2941 call UnRegister() for the returned object as soon as it is no more useful::
2943 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
2944 mesh.DoSomething( idSrc )
2948 if isinstance( ids, int ):
2950 return self.editor.MakeIDSource(ids, elemType)
2953 # Get information about mesh contents:
2954 # ------------------------------------
2956 def GetMeshInfo(self, obj = None):
2958 Get the mesh statistic.
2959 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
2960 an item of :class:`SMESH.EntityType`.
2963 dictionary { :class:`SMESH.EntityType` - "count of elements" }
2966 if not obj: obj = self.mesh
2967 return self.smeshpyD.GetMeshInfo(obj)
2971 Return the number of nodes in the mesh
2977 return self.mesh.NbNodes()
2979 def NbElements(self):
2981 Return the number of elements in the mesh
2987 return self.mesh.NbElements()
2989 def Nb0DElements(self):
2991 Return the number of 0d elements in the mesh
2997 return self.mesh.Nb0DElements()
3001 Return the number of ball discrete elements in the mesh
3007 return self.mesh.NbBalls()
3011 Return the number of edges in the mesh
3017 return self.mesh.NbEdges()
3019 def NbEdgesOfOrder(self, elementOrder):
3021 Return the number of edges with the given order in the mesh
3024 elementOrder: the order of elements
3025 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3031 return self.mesh.NbEdgesOfOrder(elementOrder)
3035 Return the number of faces in the mesh
3041 return self.mesh.NbFaces()
3043 def NbFacesOfOrder(self, elementOrder):
3045 Return the number of faces with the given order in the mesh
3048 elementOrder: the order of elements
3049 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3055 return self.mesh.NbFacesOfOrder(elementOrder)
3057 def NbTriangles(self):
3059 Return the number of triangles in the mesh
3065 return self.mesh.NbTriangles()
3067 def NbTrianglesOfOrder(self, elementOrder):
3069 Return the number of triangles with the given order in the mesh
3072 elementOrder: is the order of elements
3073 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3079 return self.mesh.NbTrianglesOfOrder(elementOrder)
3081 def NbBiQuadTriangles(self):
3083 Return the number of biquadratic triangles in the mesh
3089 return self.mesh.NbBiQuadTriangles()
3091 def NbQuadrangles(self):
3093 Return the number of quadrangles in the mesh
3099 return self.mesh.NbQuadrangles()
3101 def NbQuadranglesOfOrder(self, elementOrder):
3103 Return the number of quadrangles with the given order in the mesh
3106 elementOrder: the order of elements
3107 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3113 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3115 def NbBiQuadQuadrangles(self):
3117 Return the number of biquadratic quadrangles in the mesh
3123 return self.mesh.NbBiQuadQuadrangles()
3125 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3127 Return the number of polygons of given order in the mesh
3130 elementOrder: the order of elements
3131 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3137 return self.mesh.NbPolygonsOfOrder(elementOrder)
3139 def NbVolumes(self):
3141 Return the number of volumes in the mesh
3147 return self.mesh.NbVolumes()
3150 def NbVolumesOfOrder(self, elementOrder):
3152 Return the number of volumes with the given order in the mesh
3155 elementOrder: the order of elements
3156 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3162 return self.mesh.NbVolumesOfOrder(elementOrder)
3166 Return the number of tetrahedrons in the mesh
3172 return self.mesh.NbTetras()
3174 def NbTetrasOfOrder(self, elementOrder):
3176 Return the number of tetrahedrons with the given order in the mesh
3179 elementOrder: the order of elements
3180 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3186 return self.mesh.NbTetrasOfOrder(elementOrder)
3190 Return the number of hexahedrons in the mesh
3196 return self.mesh.NbHexas()
3198 def NbHexasOfOrder(self, elementOrder):
3200 Return the number of hexahedrons with the given order in the mesh
3203 elementOrder: the order of elements
3204 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3210 return self.mesh.NbHexasOfOrder(elementOrder)
3212 def NbTriQuadraticHexas(self):
3214 Return the number of triquadratic hexahedrons in the mesh
3220 return self.mesh.NbTriQuadraticHexas()
3222 def NbPyramids(self):
3224 Return the number of pyramids in the mesh
3230 return self.mesh.NbPyramids()
3232 def NbPyramidsOfOrder(self, elementOrder):
3234 Return the number of pyramids with the given order in the mesh
3237 elementOrder: the order of elements
3238 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3244 return self.mesh.NbPyramidsOfOrder(elementOrder)
3248 Return the number of prisms in the mesh
3254 return self.mesh.NbPrisms()
3256 def NbPrismsOfOrder(self, elementOrder):
3258 Return the number of prisms with the given order in the mesh
3261 elementOrder: the order of elements
3262 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3268 return self.mesh.NbPrismsOfOrder(elementOrder)
3270 def NbHexagonalPrisms(self):
3272 Return the number of hexagonal prisms in the mesh
3278 return self.mesh.NbHexagonalPrisms()
3280 def NbPolyhedrons(self):
3282 Return the number of polyhedrons in the mesh
3288 return self.mesh.NbPolyhedrons()
3290 def NbSubMesh(self):
3292 Return the number of submeshes in the mesh
3298 return self.mesh.NbSubMesh()
3300 def GetElementsId(self):
3302 Return the list of all mesh elements IDs
3305 the list of integer values
3308 :meth:`GetElementsByType`
3311 return self.mesh.GetElementsId()
3313 def GetElementsByType(self, elementType):
3315 Return the list of IDs of mesh elements with the given type
3318 elementType (SMESH.ElementType): the required type of elements
3321 list of integer values
3324 return self.mesh.GetElementsByType(elementType)
3326 def GetNodesId(self):
3328 Return the list of mesh nodes IDs
3331 the list of integer values
3334 return self.mesh.GetNodesId()
3336 # Get the information about mesh elements:
3337 # ------------------------------------
3339 def GetElementType(self, id, iselem=True):
3341 Return the type of mesh element or node
3344 the value from :class:`SMESH.ElementType` enumeration.
3345 Return SMESH.ALL if element or node with the given ID does not exist
3348 return self.mesh.GetElementType(id, iselem)
3350 def GetElementGeomType(self, id):
3352 Return the geometric type of mesh element
3355 the value from :class:`SMESH.EntityType` enumeration.
3358 return self.mesh.GetElementGeomType(id)
3360 def GetElementShape(self, id):
3362 Return the shape type of mesh element
3365 the value from :class:`SMESH.GeometryType` enumeration.
3368 return self.mesh.GetElementShape(id)
3370 def GetSubMeshElementsId(self, Shape):
3372 Return the list of sub-mesh elements IDs
3375 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3376 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3379 list of integer values
3382 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3383 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3386 return self.mesh.GetSubMeshElementsId(ShapeID)
3388 def GetSubMeshNodesId(self, Shape, all):
3390 Return the list of sub-mesh nodes IDs
3393 Shape: a geom object (sub-shape).
3394 *Shape* must be the sub-shape of a :meth:`GetShape`
3395 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3398 list of integer values
3401 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3402 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3405 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3407 def GetSubMeshElementType(self, Shape):
3409 Return type of elements on given shape
3412 Shape: a geom object (sub-shape).
3413 *Shape* must be a sub-shape of a ShapeToMesh()
3416 :class:`SMESH.ElementType`
3419 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3420 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3423 return self.mesh.GetSubMeshElementType(ShapeID)
3427 Get the mesh description
3433 return self.mesh.Dump()
3436 # Get the information about nodes and elements of a mesh by its IDs:
3437 # -----------------------------------------------------------
3439 def GetNodeXYZ(self, id):
3441 Get XYZ coordinates of a node.
3442 If there is no node for the given ID - return an empty list
3445 list of float values
3448 return self.mesh.GetNodeXYZ(id)
3450 def GetNodeInverseElements(self, id):
3452 Return list of IDs of inverse elements for the given node.
3453 If there is no node for the given ID - return an empty list
3456 list of integer values
3459 return self.mesh.GetNodeInverseElements(id)
3461 def GetNodePosition(self,NodeID):
3463 Return the position of a node on the shape
3466 :class:`SMESH.NodePosition`
3469 return self.mesh.GetNodePosition(NodeID)
3471 def GetElementPosition(self,ElemID):
3473 Return the position of an element on the shape
3476 :class:`SMESH.ElementPosition`
3479 return self.mesh.GetElementPosition(ElemID)
3481 def GetShapeID(self, id):
3483 Return the ID of the shape, on which the given node was generated.
3486 an integer value > 0 or -1 if there is no node for the given
3487 ID or the node is not assigned to any geometry
3490 return self.mesh.GetShapeID(id)
3492 def GetShapeIDForElem(self,id):
3494 Return the ID of the shape, on which the given element was generated.
3497 an integer value > 0 or -1 if there is no element for the given
3498 ID or the element is not assigned to any geometry
3501 return self.mesh.GetShapeIDForElem(id)
3503 def GetElemNbNodes(self, id):
3505 Return the number of nodes of the given element
3508 an integer value > 0 or -1 if there is no element for the given ID
3511 return self.mesh.GetElemNbNodes(id)
3513 def GetElemNode(self, id, index):
3515 Return the node ID the given (zero based) index for the given element.
3517 * If there is no element for the given ID - return -1.
3518 * If there is no node for the given index - return -2.
3521 id (int): element ID
3522 index (int): node index within the element
3525 an integer value (ID)
3528 :meth:`GetElemNodes`
3531 return self.mesh.GetElemNode(id, index)
3533 def GetElemNodes(self, id):
3535 Return the IDs of nodes of the given element
3538 a list of integer values
3541 return self.mesh.GetElemNodes(id)
3543 def IsMediumNode(self, elementID, nodeID):
3545 Return true if the given node is the medium node in the given quadratic element
3548 return self.mesh.IsMediumNode(elementID, nodeID)
3550 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3552 Return true if the given node is the medium node in one of quadratic elements
3555 nodeID: ID of the node
3556 elementType: the type of elements to check a state of the node, either of
3557 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3560 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3562 def ElemNbEdges(self, id):
3564 Return the number of edges for the given element
3567 return self.mesh.ElemNbEdges(id)
3569 def ElemNbFaces(self, id):
3571 Return the number of faces for the given element
3574 return self.mesh.ElemNbFaces(id)
3576 def GetElemFaceNodes(self,elemId, faceIndex):
3578 Return nodes of given face (counted from zero) for given volumic element.
3581 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3583 def GetFaceNormal(self, faceId, normalized=False):
3585 Return three components of normal of given mesh face
3586 (or an empty array in KO case)
3589 return self.mesh.GetFaceNormal(faceId,normalized)
3591 def FindElementByNodes(self, nodes):
3593 Return an element based on all given nodes.
3596 return self.mesh.FindElementByNodes(nodes)
3598 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3600 Return elements including all given nodes.
3603 return self.mesh.GetElementsByNodes( nodes, elemType )
3605 def IsPoly(self, id):
3607 Return true if the given element is a polygon
3610 return self.mesh.IsPoly(id)
3612 def IsQuadratic(self, id):
3614 Return true if the given element is quadratic
3617 return self.mesh.IsQuadratic(id)
3619 def GetBallDiameter(self, id):
3621 Return diameter of a ball discrete element or zero in case of an invalid *id*
3624 return self.mesh.GetBallDiameter(id)
3626 def BaryCenter(self, id):
3628 Return XYZ coordinates of the barycenter of the given element.
3629 If there is no element for the given ID - return an empty list
3632 a list of three double values
3635 return self.mesh.BaryCenter(id)
3637 def GetIdsFromFilter(self, theFilter):
3639 Pass mesh elements through the given filter and return IDs of fitting elements
3642 theFilter: :class:`SMESH.Filter`
3648 :meth:`SMESH.Filter.GetIDs`
3651 theFilter.SetMesh( self.mesh )
3652 return theFilter.GetIDs()
3654 # Get mesh measurements information:
3655 # ------------------------------------
3657 def GetFreeBorders(self):
3659 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3660 Return a list of special structures (borders).
3663 a list of :class:`SMESH.FreeEdges.Border`
3666 aFilterMgr = self.smeshpyD.CreateFilterManager()
3667 aPredicate = aFilterMgr.CreateFreeEdges()
3668 aPredicate.SetMesh(self.mesh)
3669 aBorders = aPredicate.GetBorders()
3670 aFilterMgr.UnRegister()
3673 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3675 Get minimum distance between two nodes, elements or distance to the origin
3678 id1: first node/element id
3679 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3680 isElem1: *True* if *id1* is element id, *False* if it is node id
3681 isElem2: *True* if *id2* is element id, *False* if it is node id
3684 minimum distance value
3686 :meth:`GetMinDistance`
3689 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3690 return aMeasure.value
3692 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3694 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3697 id1: first node/element id
3698 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3699 isElem1: *True* if *id1* is element id, *False* if it is node id
3700 isElem2: *True* if *id2* is element id, *False* if it is node id
3703 :class:`SMESH.Measure` structure
3709 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3711 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3714 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3716 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3721 aMeasurements = self.smeshpyD.CreateMeasurements()
3722 aMeasure = aMeasurements.MinDistance(id1, id2)
3723 genObjUnRegister([aMeasurements,id1, id2])
3726 def BoundingBox(self, objects=None, isElem=False):
3728 Get bounding box of the specified object(s)
3731 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3732 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3733 *False* specifies that *objects* are nodes
3736 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3739 :meth:`GetBoundingBox()`
3742 result = self.GetBoundingBox(objects, isElem)
3746 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3749 def GetBoundingBox(self, objects=None, isElem=False):
3751 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3754 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3755 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3756 False means that *objects* are nodes
3759 :class:`SMESH.Measure` structure
3762 :meth:`BoundingBox()`
3766 objects = [self.mesh]
3767 elif isinstance(objects, tuple):
3768 objects = list(objects)
3769 if not isinstance(objects, list):
3771 if len(objects) > 0 and isinstance(objects[0], int):
3774 unRegister = genObjUnRegister()
3776 if isinstance(o, Mesh):
3777 srclist.append(o.mesh)
3778 elif hasattr(o, "_narrow"):
3779 src = o._narrow(SMESH.SMESH_IDSource)
3780 if src: srclist.append(src)
3782 elif isinstance(o, list):
3784 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3786 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3787 unRegister.set( srclist[-1] )
3790 aMeasurements = self.smeshpyD.CreateMeasurements()
3791 unRegister.set( aMeasurements )
3792 aMeasure = aMeasurements.BoundingBox(srclist)
3795 # Mesh edition (SMESH_MeshEditor functionality):
3796 # ---------------------------------------------
3798 def RemoveElements(self, IDsOfElements):
3800 Remove the elements from the mesh by ids
3803 IDsOfElements: is a list of ids of elements to remove
3809 return self.editor.RemoveElements(IDsOfElements)
3811 def RemoveNodes(self, IDsOfNodes):
3813 Remove nodes from mesh by ids
3816 IDsOfNodes: is a list of ids of nodes to remove
3822 return self.editor.RemoveNodes(IDsOfNodes)
3824 def RemoveOrphanNodes(self):
3826 Remove all orphan (free) nodes from mesh
3829 number of the removed nodes
3832 return self.editor.RemoveOrphanNodes()
3834 def AddNode(self, x, y, z):
3836 Add a node to the mesh by coordinates
3842 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
3843 if hasVars: self.mesh.SetParameters(Parameters)
3844 return self.editor.AddNode( x, y, z)
3846 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
3848 Create a 0D element on a node with given number.
3851 IDOfNode: the ID of node for creation of the element.
3852 DuplicateElements: to add one more 0D element to a node or not
3855 ID of the new 0D element
3858 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
3860 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
3862 Create 0D elements on all nodes of the given elements except those
3863 nodes on which a 0D element already exists.
3866 theObject: an object on whose nodes 0D elements will be created.
3867 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3868 theGroupName: optional name of a group to add 0D elements created
3869 and/or found on nodes of *theObject*.
3870 DuplicateElements: to add one more 0D element to a node or not
3873 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
3874 IDs of new and/or found 0D elements. IDs of 0D elements
3875 can be retrieved from the returned object by
3876 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
3879 unRegister = genObjUnRegister()
3880 if isinstance( theObject, Mesh ):
3881 theObject = theObject.GetMesh()
3882 elif isinstance( theObject, list ):
3883 theObject = self.GetIDSource( theObject, SMESH.ALL )
3884 unRegister.set( theObject )
3885 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
3887 def AddBall(self, IDOfNode, diameter):
3889 Create a ball element on a node with given ID.
3892 IDOfNode: the ID of node for creation of the element.
3893 diameter: the bal diameter.
3896 ID of the new ball element
3899 return self.editor.AddBall( IDOfNode, diameter )
3901 def AddEdge(self, IDsOfNodes):
3903 Create a linear or quadratic edge (this is determined
3904 by the number of given nodes).
3907 IDsOfNodes: list of node IDs for creation of the element.
3908 The order of nodes in this list should correspond to
3909 the :ref:`connectivity convention <connectivity_page>`.
3915 return self.editor.AddEdge(IDsOfNodes)
3917 def AddFace(self, IDsOfNodes):
3919 Create a linear or quadratic face (this is determined
3920 by the number of given nodes).
3923 IDsOfNodes: list of node IDs for creation of the element.
3924 The order of nodes in this list should correspond to
3925 the :ref:`connectivity convention <connectivity_page>`.
3931 return self.editor.AddFace(IDsOfNodes)
3933 def AddPolygonalFace(self, IdsOfNodes):
3935 Add a polygonal face defined by a list of node IDs
3938 IdsOfNodes: the list of node IDs for creation of the element.
3944 return self.editor.AddPolygonalFace(IdsOfNodes)
3946 def AddQuadPolygonalFace(self, IdsOfNodes):
3948 Add a quadratic polygonal face defined by a list of node IDs
3951 IdsOfNodes: the list of node IDs for creation of the element;
3952 corner nodes follow first.
3958 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
3960 def AddVolume(self, IDsOfNodes):
3962 Create both simple and quadratic volume (this is determined
3963 by the number of given nodes).
3966 IDsOfNodes: list of node IDs for creation of the element.
3967 The order of nodes in this list should correspond to
3968 the :ref:`connectivity convention <connectivity_page>`.
3971 ID of the new volumic element
3974 return self.editor.AddVolume(IDsOfNodes)
3976 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
3978 Create a volume of many faces, giving nodes for each face.
3981 IdsOfNodes: list of node IDs for volume creation, face by face.
3982 Quantities: list of integer values, Quantities[i]
3983 gives the quantity of nodes in face number i.
3986 ID of the new volumic element
3989 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
3991 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
3993 Create a volume of many faces, giving the IDs of the existing faces.
3996 The created volume will refer only to the nodes
3997 of the given faces, not to the faces themselves.
4000 IdsOfFaces: the list of face IDs for volume creation.
4003 ID of the new volumic element
4006 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4009 def SetNodeOnVertex(self, NodeID, Vertex):
4011 Bind a node to a vertex
4015 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4018 True if succeed else raises an exception
4021 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4022 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4026 self.editor.SetNodeOnVertex(NodeID, VertexID)
4027 except SALOME.SALOME_Exception as inst:
4028 raise ValueError(inst.details.text)
4032 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4034 Store the node position on an edge
4038 Edge: an edge (GEOM.GEOM_Object) or edge ID
4039 paramOnEdge: a parameter on the edge where the node is located
4042 True if succeed else raises an exception
4045 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4046 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4050 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4051 except SALOME.SALOME_Exception as inst:
4052 raise ValueError(inst.details.text)
4055 def SetNodeOnFace(self, NodeID, Face, u, v):
4057 Store node position on a face
4061 Face: a face (GEOM.GEOM_Object) or face ID
4062 u: U parameter on the face where the node is located
4063 v: V parameter on the face where the node is located
4066 True if succeed else raises an exception
4069 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4070 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4074 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4075 except SALOME.SALOME_Exception as inst:
4076 raise ValueError(inst.details.text)
4079 def SetNodeInVolume(self, NodeID, Solid):
4081 Bind a node to a solid
4085 Solid: a solid (GEOM.GEOM_Object) or solid ID
4088 True if succeed else raises an exception
4091 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4092 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4096 self.editor.SetNodeInVolume(NodeID, SolidID)
4097 except SALOME.SALOME_Exception as inst:
4098 raise ValueError(inst.details.text)
4101 def SetMeshElementOnShape(self, ElementID, Shape):
4103 Bind an element to a shape
4106 ElementID: an element ID
4107 Shape: a shape (GEOM.GEOM_Object) or shape ID
4110 True if succeed else raises an exception
4113 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4114 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4118 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4119 except SALOME.SALOME_Exception as inst:
4120 raise ValueError(inst.details.text)
4124 def MoveNode(self, NodeID, x, y, z):
4126 Move the node with the given id
4129 NodeID: the id of the node
4130 x: a new X coordinate
4131 y: a new Y coordinate
4132 z: a new Z coordinate
4135 True if succeed else False
4138 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4139 if hasVars: self.mesh.SetParameters(Parameters)
4140 return self.editor.MoveNode(NodeID, x, y, z)
4142 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4144 Find the node closest to a point and moves it to a point location
4147 x: the X coordinate of a point
4148 y: the Y coordinate of a point
4149 z: the Z coordinate of a point
4150 NodeID: if specified (>0), the node with this ID is moved,
4151 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4154 the ID of a moved node
4157 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4158 if hasVars: self.mesh.SetParameters(Parameters)
4159 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4161 def FindNodeClosestTo(self, x, y, z):
4163 Find the node closest to a point
4166 x: the X coordinate of a point
4167 y: the Y coordinate of a point
4168 z: the Z coordinate of a point
4174 #preview = self.mesh.GetMeshEditPreviewer()
4175 #return preview.MoveClosestNodeToPoint(x, y, z, -1)
4176 return self.editor.FindNodeClosestTo(x, y, z)
4178 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4180 Find the elements where a point lays IN or ON
4183 x,y,z (float): coordinates of the point
4184 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4185 means elements of any type excluding nodes, discrete and 0D elements.
4186 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4189 list of IDs of found elements
4192 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4194 return self.editor.FindElementsByPoint(x, y, z, elementType)
4196 def GetPointState(self, x, y, z):
4198 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4199 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4200 UNKNOWN state means that either mesh is wrong or the analysis fails.
4203 return self.editor.GetPointState(x, y, z)
4205 def IsManifold(self):
4207 Check if a 2D mesh is manifold
4210 return self.editor.IsManifold()
4212 def IsCoherentOrientation2D(self):
4214 Check if orientation of 2D elements is coherent
4217 return self.editor.IsCoherentOrientation2D()
4219 def MeshToPassThroughAPoint(self, x, y, z):
4221 Find the node closest to a point and moves it to a point location
4224 x: the X coordinate of a point
4225 y: the Y coordinate of a point
4226 z: the Z coordinate of a point
4229 the ID of a moved node
4232 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4234 def InverseDiag(self, NodeID1, NodeID2):
4236 Replace two neighbour triangles sharing Node1-Node2 link
4237 with the triangles built on the same 4 nodes but having other common link.
4240 NodeID1: the ID of the first node
4241 NodeID2: the ID of the second node
4244 False if proper faces were not found
4246 return self.editor.InverseDiag(NodeID1, NodeID2)
4248 def DeleteDiag(self, NodeID1, NodeID2):
4250 Replace two neighbour triangles sharing *Node1-Node2* link
4251 with a quadrangle built on the same 4 nodes.
4254 NodeID1: ID of the first node
4255 NodeID2: ID of the second node
4258 False if proper faces were not found
4261 return self.editor.DeleteDiag(NodeID1, NodeID2)
4263 def Reorient(self, IDsOfElements=None):
4265 Reorient elements by ids
4268 IDsOfElements: if undefined reorients all mesh elements
4271 True if succeed else False
4274 if IDsOfElements == None:
4275 IDsOfElements = self.GetElementsId()
4276 return self.editor.Reorient(IDsOfElements)
4278 def ReorientObject(self, theObject):
4280 Reorient all elements of the object
4283 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4286 True if succeed else False
4289 if ( isinstance( theObject, Mesh )):
4290 theObject = theObject.GetMesh()
4291 return self.editor.ReorientObject(theObject)
4293 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4295 Reorient faces contained in *the2DObject*.
4298 the2DObject: is a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4299 theDirection: is a desired direction of normal of *theFace*.
4300 It can be either a GEOM vector or a list of coordinates [x,y,z].
4301 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4302 compared with theDirection. It can be either ID of face or a point
4303 by which the face will be found. The point can be given as either
4304 a GEOM vertex or a list of point coordinates.
4307 number of reoriented faces
4310 unRegister = genObjUnRegister()
4312 if isinstance( the2DObject, Mesh ):
4313 the2DObject = the2DObject.GetMesh()
4314 if isinstance( the2DObject, list ):
4315 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4316 unRegister.set( the2DObject )
4317 # check theDirection
4318 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4319 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4320 if isinstance( theDirection, list ):
4321 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4322 # prepare theFace and thePoint
4323 theFace = theFaceOrPoint
4324 thePoint = PointStruct(0,0,0)
4325 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4326 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4328 if isinstance( theFaceOrPoint, list ):
4329 thePoint = PointStruct( *theFaceOrPoint )
4331 if isinstance( theFaceOrPoint, PointStruct ):
4332 thePoint = theFaceOrPoint
4334 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4336 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4338 Reorient faces according to adjacent volumes.
4341 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4342 either IDs of faces or face groups.
4343 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4344 theOutsideNormal: to orient faces to have their normals
4345 pointing either *outside* or *inside* the adjacent volumes.
4348 number of reoriented faces.
4351 unRegister = genObjUnRegister()
4353 if not isinstance( the2DObject, list ):
4354 the2DObject = [ the2DObject ]
4355 elif the2DObject and isinstance( the2DObject[0], int ):
4356 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4357 unRegister.set( the2DObject )
4358 the2DObject = [ the2DObject ]
4359 for i,obj2D in enumerate( the2DObject ):
4360 if isinstance( obj2D, Mesh ):
4361 the2DObject[i] = obj2D.GetMesh()
4362 if isinstance( obj2D, list ):
4363 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4364 unRegister.set( the2DObject[i] )
4366 if isinstance( the3DObject, Mesh ):
4367 the3DObject = the3DObject.GetMesh()
4368 if isinstance( the3DObject, list ):
4369 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4370 unRegister.set( the3DObject )
4371 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4373 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4375 Fuse the neighbouring triangles into quadrangles.
4378 IDsOfElements: The triangles to be fused.
4379 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4380 applied to possible quadrangles to choose a neighbour to fuse with.
4381 Note that not all items of :class:`SMESH.FunctorType` corresponds
4382 to numerical functors.
4383 MaxAngle: is the maximum angle between element normals at which the fusion
4384 is still performed; theMaxAngle is measured in radians.
4385 Also it could be a name of variable which defines angle in degrees.
4388 True in case of success, False otherwise.
4391 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4392 self.mesh.SetParameters(Parameters)
4393 if not IDsOfElements:
4394 IDsOfElements = self.GetElementsId()
4395 Functor = self.smeshpyD.GetFunctor(theCriterion)
4396 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4398 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4400 Fuse the neighbouring triangles of the object into quadrangles
4403 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4404 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4405 applied to possible quadrangles to choose a neighbour to fuse with.
4406 Note that not all items of :class:`SMESH.FunctorType` corresponds
4407 to numerical functors.
4408 MaxAngle: a max angle between element normals at which the fusion
4409 is still performed; theMaxAngle is measured in radians.
4412 True in case of success, False otherwise.
4415 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4416 self.mesh.SetParameters(Parameters)
4417 if isinstance( theObject, Mesh ):
4418 theObject = theObject.GetMesh()
4419 Functor = self.smeshpyD.GetFunctor(theCriterion)
4420 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4422 def QuadToTri (self, IDsOfElements, theCriterion = None):
4424 Split quadrangles into triangles.
4427 IDsOfElements: the faces to be splitted.
4428 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4429 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4430 value, then quadrangles will be split by the smallest diagonal.
4431 Note that not all items of :class:`SMESH.FunctorType` corresponds
4432 to numerical functors.
4435 True in case of success, False otherwise.
4437 if IDsOfElements == []:
4438 IDsOfElements = self.GetElementsId()
4439 if theCriterion is None:
4440 theCriterion = FT_MaxElementLength2D
4441 Functor = self.smeshpyD.GetFunctor(theCriterion)
4442 return self.editor.QuadToTri(IDsOfElements, Functor)
4444 def QuadToTriObject (self, theObject, theCriterion = None):
4446 Split quadrangles into triangles.
4449 theObject: the object from which the list of elements is taken,
4450 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4451 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4452 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4453 value, then quadrangles will be split by the smallest diagonal.
4454 Note that not all items of :class:`SMESH.FunctorType` corresponds
4455 to numerical functors.
4458 True in case of success, False otherwise.
4460 if ( isinstance( theObject, Mesh )):
4461 theObject = theObject.GetMesh()
4462 if theCriterion is None:
4463 theCriterion = FT_MaxElementLength2D
4464 Functor = self.smeshpyD.GetFunctor(theCriterion)
4465 return self.editor.QuadToTriObject(theObject, Functor)
4467 def QuadTo4Tri (self, theElements=[]):
4469 Split each of given quadrangles into 4 triangles. A node is added at the center of
4473 theElements: the faces to be splitted. This can be either
4474 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4475 or a list of face IDs. By default all quadrangles are split
4477 unRegister = genObjUnRegister()
4478 if isinstance( theElements, Mesh ):
4479 theElements = theElements.mesh
4480 elif not theElements:
4481 theElements = self.mesh
4482 elif isinstance( theElements, list ):
4483 theElements = self.GetIDSource( theElements, SMESH.FACE )
4484 unRegister.set( theElements )
4485 return self.editor.QuadTo4Tri( theElements )
4487 def SplitQuad (self, IDsOfElements, Diag13):
4489 Split quadrangles into triangles.
4492 IDsOfElements: the faces to be splitted
4493 Diag13: is used to choose a diagonal for splitting.
4496 True in case of success, False otherwise.
4498 if IDsOfElements == []:
4499 IDsOfElements = self.GetElementsId()
4500 return self.editor.SplitQuad(IDsOfElements, Diag13)
4502 def SplitQuadObject (self, theObject, Diag13):
4504 Split quadrangles into triangles.
4507 theObject: the object from which the list of elements is taken,
4508 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4509 Diag13: is used to choose a diagonal for splitting.
4512 True in case of success, False otherwise.
4514 if ( isinstance( theObject, Mesh )):
4515 theObject = theObject.GetMesh()
4516 return self.editor.SplitQuadObject(theObject, Diag13)
4518 def BestSplit (self, IDOfQuad, theCriterion):
4520 Find a better splitting of the given quadrangle.
4523 IDOfQuad: the ID of the quadrangle to be splitted.
4524 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4525 choose a diagonal for splitting.
4526 Note that not all items of :class:`SMESH.FunctorType` corresponds
4527 to numerical functors.
4530 * 1 if 1-3 diagonal is better,
4531 * 2 if 2-4 diagonal is better,
4532 * 0 if error occurs.
4534 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4536 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4538 Split volumic elements into tetrahedrons
4541 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4542 method: flags passing splitting method:
4543 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4544 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4546 unRegister = genObjUnRegister()
4547 if isinstance( elems, Mesh ):
4548 elems = elems.GetMesh()
4549 if ( isinstance( elems, list )):
4550 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4551 unRegister.set( elems )
4552 self.editor.SplitVolumesIntoTetra(elems, method)
4555 def SplitBiQuadraticIntoLinear(self, elems=None):
4557 Split bi-quadratic elements into linear ones without creation of additional nodes:
4559 - bi-quadratic triangle will be split into 3 linear quadrangles;
4560 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4561 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4563 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4564 will be split in order to keep the mesh conformal.
4567 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4568 if None (default), all bi-quadratic elements will be split
4570 unRegister = genObjUnRegister()
4571 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4572 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4573 unRegister.set( elems )
4575 elems = [ self.GetMesh() ]
4576 if isinstance( elems, Mesh ):
4577 elems = [ elems.GetMesh() ]
4578 if not isinstance( elems, list ):
4580 self.editor.SplitBiQuadraticIntoLinear( elems )
4582 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4583 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4585 Split hexahedra into prisms
4588 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4589 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4590 gives a normal vector defining facets to split into triangles.
4591 *startHexPoint* can be either a triple of coordinates or a vertex.
4592 facetNormal: a normal to a facet to split into triangles of a
4593 hexahedron found by *startHexPoint*.
4594 *facetNormal* can be either a triple of coordinates or an edge.
4595 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4596 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4597 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4598 to *startHexPoint* are split, else *startHexPoint*
4599 is used to find the facet to split in all domains present in *elems*.
4602 unRegister = genObjUnRegister()
4603 if isinstance( elems, Mesh ):
4604 elems = elems.GetMesh()
4605 if ( isinstance( elems, list )):
4606 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4607 unRegister.set( elems )
4610 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4611 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4612 elif isinstance( startHexPoint, list ):
4613 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4616 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4617 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4618 elif isinstance( facetNormal, list ):
4619 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4622 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4624 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4626 def SplitQuadsNearTriangularFacets(self):
4628 Split quadrangle faces near triangular facets of volumes
4630 faces_array = self.GetElementsByType(SMESH.FACE)
4631 for face_id in faces_array:
4632 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4633 quad_nodes = self.mesh.GetElemNodes(face_id)
4634 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4635 isVolumeFound = False
4636 for node1_elem in node1_elems:
4637 if not isVolumeFound:
4638 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4639 nb_nodes = self.GetElemNbNodes(node1_elem)
4640 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4641 volume_elem = node1_elem
4642 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4643 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4644 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4645 isVolumeFound = True
4646 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4647 self.SplitQuad([face_id], False) # diagonal 2-4
4648 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4649 isVolumeFound = True
4650 self.SplitQuad([face_id], True) # diagonal 1-3
4651 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4652 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4653 isVolumeFound = True
4654 self.SplitQuad([face_id], True) # diagonal 1-3
4656 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4658 Split hexahedrons into tetrahedrons.
4660 This operation uses :doc:`pattern_mapping` functionality for splitting.
4663 theObject: the object from which the list of hexahedrons is taken;
4664 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4665 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4666 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4667 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4668 key-point will be mapped into *theNode001*-th node of each volume.
4669 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4672 True in case of success, False otherwise.
4680 # (0,0,1) 4.---------.7 * |
4687 # (0,0,0) 0.---------.3
4688 pattern_tetra = "!!! Nb of points: \n 8 \n\
4698 !!! Indices of points of 6 tetras: \n\
4706 pattern = self.smeshpyD.GetPattern()
4707 isDone = pattern.LoadFromFile(pattern_tetra)
4709 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4712 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4713 isDone = pattern.MakeMesh(self.mesh, False, False)
4714 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4716 # split quafrangle faces near triangular facets of volumes
4717 self.SplitQuadsNearTriangularFacets()
4721 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
4723 Split hexahedrons into prisms.
4725 Uses the :doc:`pattern_mapping` functionality for splitting.
4728 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
4729 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
4730 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
4731 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
4732 will be mapped into the *theNode001* -th node of each volume.
4733 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
4736 True in case of success, False otherwise.
4738 # Pattern: 5.---------.6
4743 # (0,0,1) 4.---------.7 |
4750 # (0,0,0) 0.---------.3
4751 pattern_prism = "!!! Nb of points: \n 8 \n\
4761 !!! Indices of points of 2 prisms: \n\
4765 pattern = self.smeshpyD.GetPattern()
4766 isDone = pattern.LoadFromFile(pattern_prism)
4768 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4771 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4772 isDone = pattern.MakeMesh(self.mesh, False, False)
4773 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4775 # Split quafrangle faces near triangular facets of volumes
4776 self.SplitQuadsNearTriangularFacets()
4780 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
4781 MaxNbOfIterations, MaxAspectRatio, Method):
4786 IDsOfElements: the list if ids of elements to smooth
4787 IDsOfFixedNodes: the list of ids of fixed nodes.
4788 Note that nodes built on edges and boundary nodes are always fixed.
4789 MaxNbOfIterations: the maximum number of iterations
4790 MaxAspectRatio: varies in range [1.0, inf]
4791 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4792 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4795 True in case of success, False otherwise.
4798 if IDsOfElements == []:
4799 IDsOfElements = self.GetElementsId()
4800 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4801 self.mesh.SetParameters(Parameters)
4802 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
4803 MaxNbOfIterations, MaxAspectRatio, Method)
4805 def SmoothObject(self, theObject, IDsOfFixedNodes,
4806 MaxNbOfIterations, MaxAspectRatio, Method):
4808 Smooth elements which belong to the given object
4811 theObject: the object to smooth
4812 IDsOfFixedNodes: the list of ids of fixed nodes.
4813 Note that nodes built on edges and boundary nodes are always fixed.
4814 MaxNbOfIterations: the maximum number of iterations
4815 MaxAspectRatio: varies in range [1.0, inf]
4816 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4817 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4820 True in case of success, False otherwise.
4823 if ( isinstance( theObject, Mesh )):
4824 theObject = theObject.GetMesh()
4825 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
4826 MaxNbOfIterations, MaxAspectRatio, Method)
4828 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
4829 MaxNbOfIterations, MaxAspectRatio, Method):
4831 Parametrically smooth the given elements
4834 IDsOfElements: the list if ids of elements to smooth
4835 IDsOfFixedNodes: the list of ids of fixed nodes.
4836 Note that nodes built on edges and boundary nodes are always fixed.
4837 MaxNbOfIterations: the maximum number of iterations
4838 MaxAspectRatio: varies in range [1.0, inf]
4839 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4840 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4843 True in case of success, False otherwise.
4846 if IDsOfElements == []:
4847 IDsOfElements = self.GetElementsId()
4848 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4849 self.mesh.SetParameters(Parameters)
4850 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
4851 MaxNbOfIterations, MaxAspectRatio, Method)
4853 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
4854 MaxNbOfIterations, MaxAspectRatio, Method):
4856 Parametrically smooth the elements which belong to the given object
4859 theObject: the object to smooth
4860 IDsOfFixedNodes: the list of ids of fixed nodes.
4861 Note that nodes built on edges and boundary nodes are always fixed.
4862 MaxNbOfIterations: the maximum number of iterations
4863 MaxAspectRatio: varies in range [1.0, inf]
4864 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4865 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4868 True in case of success, False otherwise.
4871 if ( isinstance( theObject, Mesh )):
4872 theObject = theObject.GetMesh()
4873 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
4874 MaxNbOfIterations, MaxAspectRatio, Method)
4876 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
4878 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
4879 them with quadratic with the same id.
4882 theForce3d: method of new node creation:
4884 * False - the medium node lies at the geometrical entity from which the mesh element is built
4885 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
4886 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4887 theToBiQuad: If True, converts the mesh to bi-quadratic
4890 :class:`SMESH.ComputeError` which can hold a warning
4893 If *theSubMesh* is provided, the mesh can become non-conformal
4896 if isinstance( theSubMesh, Mesh ):
4897 theSubMesh = theSubMesh.mesh
4899 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
4902 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
4904 self.editor.ConvertToQuadratic(theForce3d)
4905 error = self.editor.GetLastError()
4906 if error and error.comment:
4907 print(error.comment)
4910 def ConvertFromQuadratic(self, theSubMesh=None):
4912 Convert the mesh from quadratic to ordinary,
4913 deletes old quadratic elements,
4914 replacing them with ordinary mesh elements with the same id.
4917 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4920 If *theSubMesh* is provided, the mesh can become non-conformal
4924 self.editor.ConvertFromQuadraticObject(theSubMesh)
4926 return self.editor.ConvertFromQuadratic()
4928 def Make2DMeshFrom3D(self):
4930 Create 2D mesh as skin on boundary faces of a 3D mesh
4933 True if operation has been completed successfully, False otherwise
4936 return self.editor.Make2DMeshFrom3D()
4938 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4939 toCopyElements=False, toCopyExistingBondary=False):
4941 Create missing boundary elements
4944 elements: elements whose boundary is to be checked:
4945 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
4946 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
4947 dimension: defines type of boundary elements to create, either of
4948 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
4949 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
4950 groupName: a name of group to store created boundary elements in,
4951 "" means not to create the group
4952 meshName: a name of new mesh to store created boundary elements in,
4953 "" means not to create the new mesh
4954 toCopyElements: if True, the checked elements will be copied into
4955 the new mesh else only boundary elements will be copied into the new mesh
4956 toCopyExistingBondary: if True, not only new but also pre-existing
4957 boundary elements will be copied into the new mesh
4960 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
4963 unRegister = genObjUnRegister()
4964 if isinstance( elements, Mesh ):
4965 elements = elements.GetMesh()
4966 if ( isinstance( elements, list )):
4967 elemType = SMESH.ALL
4968 if elements: elemType = self.GetElementType( elements[0], iselem=True)
4969 elements = self.editor.MakeIDSource(elements, elemType)
4970 unRegister.set( elements )
4971 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
4972 toCopyElements,toCopyExistingBondary)
4973 if mesh: mesh = self.smeshpyD.Mesh(mesh)
4976 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4977 toCopyAll=False, groups=[]):
4979 Create missing boundary elements around either the whole mesh or
4983 dimension: defines type of boundary elements to create, either of
4984 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
4985 groupName: a name of group to store all boundary elements in,
4986 "" means not to create the group
4987 meshName: a name of a new mesh, which is a copy of the initial
4988 mesh + created boundary elements; "" means not to create the new mesh
4989 toCopyAll: if True, the whole initial mesh will be copied into
4990 the new mesh else only boundary elements will be copied into the new mesh
4991 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
4994 tuple( long, mesh, groups )
4995 - long - number of added boundary elements
4996 - mesh - the :class:`Mesh` where elements were added to
4997 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5000 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5002 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5003 return nb, mesh, group
5005 def RenumberNodes(self):
5007 Renumber mesh nodes to remove unused node IDs
5009 self.editor.RenumberNodes()
5011 def RenumberElements(self):
5013 Renumber mesh elements to remove unused element IDs
5015 self.editor.RenumberElements()
5017 def _getIdSourceList(self, arg, idType, unRegister):
5019 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5021 if arg and isinstance( arg, list ):
5022 if isinstance( arg[0], int ):
5023 arg = self.GetIDSource( arg, idType )
5024 unRegister.set( arg )
5025 elif isinstance( arg[0], Mesh ):
5026 arg[0] = arg[0].GetMesh()
5027 elif isinstance( arg, Mesh ):
5029 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5033 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5034 MakeGroups=False, TotalAngle=False):
5036 Generate new elements by rotation of the given elements and nodes around the axis
5039 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5040 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5041 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5042 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5043 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5044 which defines angle in degrees
5045 NbOfSteps: the number of steps
5046 Tolerance: tolerance
5047 MakeGroups: forces the generation of new groups from existing ones
5048 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5049 of all steps, else - size of each step
5052 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5055 unRegister = genObjUnRegister()
5056 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5057 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5058 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5060 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5061 Axis = self.smeshpyD.GetAxisStruct( Axis )
5062 if isinstance( Axis, list ):
5063 Axis = SMESH.AxisStruct( *Axis )
5065 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5066 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5067 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5068 self.mesh.SetParameters(Parameters)
5069 if TotalAngle and NbOfSteps:
5070 AngleInRadians /= NbOfSteps
5071 return self.editor.RotationSweepObjects( nodes, edges, faces,
5072 Axis, AngleInRadians,
5073 NbOfSteps, Tolerance, MakeGroups)
5075 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5076 MakeGroups=False, TotalAngle=False):
5078 Generate new elements by rotation of the elements around the axis
5081 IDsOfElements: the list of ids of elements to sweep
5082 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5083 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5084 NbOfSteps: the number of steps
5085 Tolerance: tolerance
5086 MakeGroups: forces the generation of new groups from existing ones
5087 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5088 of all steps, else - size of each step
5091 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5094 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5095 AngleInRadians, NbOfSteps, Tolerance,
5096 MakeGroups, TotalAngle)
5098 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5099 MakeGroups=False, TotalAngle=False):
5101 Generate new elements by rotation of the elements of object around the axis
5102 theObject object which elements should be sweeped.
5103 It can be a mesh, a sub mesh or a group.
5106 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5107 AngleInRadians: the angle of Rotation
5108 NbOfSteps: number of steps
5109 Tolerance: tolerance
5110 MakeGroups: forces the generation of new groups from existing ones
5111 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5112 of all steps, else - size of each step
5115 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5118 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5119 AngleInRadians, NbOfSteps, Tolerance,
5120 MakeGroups, TotalAngle )
5122 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5123 MakeGroups=False, TotalAngle=False):
5125 Generate new elements by rotation of the elements of object around the axis
5126 theObject object which elements should be sweeped.
5127 It can be a mesh, a sub mesh or a group.
5130 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5131 AngleInRadians: the angle of Rotation
5132 NbOfSteps: number of steps
5133 Tolerance: tolerance
5134 MakeGroups: forces the generation of new groups from existing ones
5135 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5136 of all steps, else - size of each step
5139 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5140 empty list otherwise
5143 return self.RotationSweepObjects([],theObject,[], Axis,
5144 AngleInRadians, NbOfSteps, Tolerance,
5145 MakeGroups, TotalAngle)
5147 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5148 MakeGroups=False, TotalAngle=False):
5150 Generate new elements by rotation of the elements of object around the axis
5151 theObject object which elements should be sweeped.
5152 It can be a mesh, a sub mesh or a group.
5155 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5156 AngleInRadians: the angle of Rotation
5157 NbOfSteps: number of steps
5158 Tolerance: tolerance
5159 MakeGroups: forces the generation of new groups from existing ones
5160 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5161 of all steps, else - size of each step
5164 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5167 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5168 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5170 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5171 scaleFactors=[], linearVariation=False, basePoint=[] ):
5173 Generate new elements by extrusion of the given elements and nodes
5176 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5177 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5178 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5179 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5180 the direction and value of extrusion for one step (the total extrusion
5181 length will be NbOfSteps * ||StepVector||)
5182 NbOfSteps: the number of steps
5183 MakeGroups: forces the generation of new groups from existing ones
5184 scaleFactors: optional scale factors to apply during extrusion
5185 linearVariation: if *True*, scaleFactors are spread over all *scaleFactors*,
5186 else scaleFactors[i] is applied to nodes at the i-th extrusion step
5187 basePoint: optional scaling center; if not provided, a gravity center of
5188 nodes and elements being extruded is used as the scaling center.
5191 - a list of tree components of the point or
5195 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5197 Example: :ref:`tui_extrusion`
5199 unRegister = genObjUnRegister()
5200 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5201 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5202 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5204 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5205 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5206 if isinstance( StepVector, list ):
5207 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5209 if isinstance( basePoint, int):
5210 xyz = self.GetNodeXYZ( basePoint )
5212 raise RuntimeError("Invalid node ID: %s" % basePoint)
5214 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5215 basePoint = self.geompyD.PointCoordinates( basePoint )
5217 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5218 Parameters = StepVector.PS.parameters + var_separator + Parameters
5219 self.mesh.SetParameters(Parameters)
5221 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5222 StepVector, NbOfSteps,
5223 scaleFactors, linearVariation, basePoint,
5227 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5229 Generate new elements by extrusion of the elements with given ids
5232 IDsOfElements: the list of ids of elements or nodes for extrusion
5233 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5234 the direction and value of extrusion for one step (the total extrusion
5235 length will be NbOfSteps * ||StepVector||)
5236 NbOfSteps: the number of steps
5237 MakeGroups: forces the generation of new groups from existing ones
5238 IsNodes: is True if elements with given ids are nodes
5241 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5243 Example: :ref:`tui_extrusion`
5246 if IsNodes: n = IDsOfElements
5247 else : e,f, = IDsOfElements,IDsOfElements
5248 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5250 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5251 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5253 Generate new elements by extrusion along the normal to a discretized surface or wire
5256 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5257 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5258 StepSize: length of one extrusion step (the total extrusion
5259 length will be *NbOfSteps* *StepSize*).
5260 NbOfSteps: number of extrusion steps.
5261 ByAverageNormal: if True each node is translated by *StepSize*
5262 along the average of the normal vectors to the faces sharing the node;
5263 else each node is translated along the same average normal till
5264 intersection with the plane got by translation of the face sharing
5265 the node along its own normal by *StepSize*.
5266 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5267 for every node of *Elements*.
5268 MakeGroups: forces generation of new groups from existing ones.
5269 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5270 is not yet implemented. This parameter is used if *Elements* contains
5271 both faces and edges, i.e. *Elements* is a Mesh.
5274 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5275 empty list otherwise.
5276 Example: :ref:`tui_extrusion`
5279 unRegister = genObjUnRegister()
5280 if isinstance( Elements, Mesh ):
5281 Elements = [ Elements.GetMesh() ]
5282 if isinstance( Elements, list ):
5284 raise RuntimeError("Elements empty!")
5285 if isinstance( Elements[0], int ):
5286 Elements = self.GetIDSource( Elements, SMESH.ALL )
5287 unRegister.set( Elements )
5288 if not isinstance( Elements, list ):
5289 Elements = [ Elements ]
5290 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5291 self.mesh.SetParameters(Parameters)
5292 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5293 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5295 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5297 Generate new elements by extrusion of the elements or nodes which belong to the object
5300 theObject: the object whose elements or nodes should be processed.
5301 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5302 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5303 the direction and value of extrusion for one step (the total extrusion
5304 length will be NbOfSteps * ||StepVector||)
5305 NbOfSteps: the number of steps
5306 MakeGroups: forces the generation of new groups from existing ones
5307 IsNodes: is True if elements to extrude are nodes
5310 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5311 Example: :ref:`tui_extrusion`
5315 if IsNodes: n = theObject
5316 else : e,f, = theObject,theObject
5317 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5319 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5321 Generate new elements by extrusion of edges which belong to the object
5324 theObject: object whose 1D elements should be processed.
5325 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5326 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5327 the direction and value of extrusion for one step (the total extrusion
5328 length will be NbOfSteps * ||StepVector||)
5329 NbOfSteps: the number of steps
5330 MakeGroups: to generate new groups from existing ones
5333 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5334 Example: :ref:`tui_extrusion`
5337 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5339 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5341 Generate new elements by extrusion of faces which belong to the object
5344 theObject: object whose 2D elements should be processed.
5345 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5346 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5347 the direction and value of extrusion for one step (the total extrusion
5348 length will be NbOfSteps * ||StepVector||)
5349 NbOfSteps: the number of steps
5350 MakeGroups: forces the generation of new groups from existing ones
5353 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5354 Example: :ref:`tui_extrusion`
5357 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5359 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5360 ExtrFlags, SewTolerance, MakeGroups=False):
5362 Generate new elements by extrusion of the elements with given ids
5365 IDsOfElements: is ids of elements
5366 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5367 the direction and value of extrusion for one step (the total extrusion
5368 length will be NbOfSteps * ||StepVector||)
5369 NbOfSteps: the number of steps
5370 ExtrFlags: sets flags for extrusion
5371 SewTolerance: uses for comparing locations of nodes if flag
5372 EXTRUSION_FLAG_SEW is set
5373 MakeGroups: forces the generation of new groups from existing ones
5376 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5379 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5380 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5381 if isinstance( StepVector, list ):
5382 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5383 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5384 ExtrFlags, SewTolerance, MakeGroups)
5386 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
5387 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5388 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
5390 Generate new elements by extrusion of the given elements and nodes along the path.
5391 The path of extrusion must be a meshed edge.
5394 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5395 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5396 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5397 PathMesh: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5398 PathShape: shape (edge) defines the sub-mesh of PathMesh if PathMesh
5399 contains not only path segments, else it can be None
5400 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5401 HasAngles: allows the shape to be rotated around the path
5402 to get the resulting mesh in a helical fashion
5403 Angles: list of angles
5404 LinearVariation: forces the computation of rotation angles as linear
5405 variation of the given Angles along path steps
5406 HasRefPoint: allows using the reference point
5407 RefPoint: the reference point around which the shape is rotated (the mass center of the
5408 shape by default). The User can specify any point as the Reference Point.
5409 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5410 MakeGroups: forces the generation of new groups from existing ones
5413 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5414 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5415 Example: :ref:`tui_extrusion_along_path`
5418 unRegister = genObjUnRegister()
5419 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5420 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5421 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5423 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5424 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5425 if isinstance( RefPoint, list ):
5426 if not RefPoint: RefPoint = [0,0,0]
5427 RefPoint = SMESH.PointStruct( *RefPoint )
5428 if isinstance( PathMesh, Mesh ):
5429 PathMesh = PathMesh.GetMesh()
5430 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5431 Parameters = AnglesParameters + var_separator + RefPoint.parameters
5432 self.mesh.SetParameters(Parameters)
5433 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5434 PathMesh, PathShape, NodeStart,
5435 HasAngles, Angles, LinearVariation,
5436 HasRefPoint, RefPoint, MakeGroups)
5438 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5439 HasAngles=False, Angles=[], LinearVariation=False,
5440 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5441 ElemType=SMESH.FACE):
5443 Generate new elements by extrusion of the given elements.
5444 The path of extrusion must be a meshed edge.
5447 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5448 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5449 NodeStart: the start node from Path. Defines the direction of extrusion
5450 HasAngles: allows the shape to be rotated around the path
5451 to get the resulting mesh in a helical fashion
5452 Angles: list of angles in radians
5453 LinearVariation: forces the computation of rotation angles as linear
5454 variation of the given Angles along path steps
5455 HasRefPoint: allows using the reference point
5456 RefPoint: the reference point around which the elements are rotated (the mass
5457 center of the elements by default).
5458 The User can specify any point as the Reference Point.
5459 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5460 MakeGroups: forces the generation of new groups from existing ones
5461 ElemType: type of elements for extrusion (if param Base is a mesh)
5464 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5465 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5466 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5468 Example: :ref:`tui_extrusion_along_path`
5472 if ElemType == SMESH.NODE: n = Base
5473 if ElemType == SMESH.EDGE: e = Base
5474 if ElemType == SMESH.FACE: f = Base
5475 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5476 HasAngles, Angles, LinearVariation,
5477 HasRefPoint, RefPoint, MakeGroups)
5478 if MakeGroups: return gr,er
5481 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5482 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5483 MakeGroups=False, LinearVariation=False):
5485 Generate new elements by extrusion of the given elements.
5486 The path of extrusion must be a meshed edge.
5489 IDsOfElements: ids of elements
5490 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5491 PathShape: shape (edge) defines the sub-mesh for the path
5492 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5493 HasAngles: allows the shape to be rotated around the path
5494 to get the resulting mesh in a helical fashion
5495 Angles: list of angles in radians
5496 HasRefPoint: allows using the reference point
5497 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5498 The User can specify any point as the Reference Point.
5499 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5500 MakeGroups: forces the generation of new groups from existing ones
5501 LinearVariation: forces the computation of rotation angles as linear
5502 variation of the given Angles along path steps
5505 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5506 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5507 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5508 Example: :ref:`tui_extrusion_along_path`
5511 n,e,f = [],IDsOfElements,IDsOfElements
5512 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5513 NodeStart, HasAngles, Angles,
5515 HasRefPoint, RefPoint, MakeGroups)
5516 if MakeGroups: return gr,er
5519 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5520 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5521 MakeGroups=False, LinearVariation=False):
5523 Generate new elements by extrusion of the elements which belong to the object.
5524 The path of extrusion must be a meshed edge.
5527 theObject: the object whose elements should be processed.
5528 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5529 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5530 PathShape: shape (edge) defines the sub-mesh for the path
5531 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5532 HasAngles: allows the shape to be rotated around the path
5533 to get the resulting mesh in a helical fashion
5534 Angles: list of angles
5535 HasRefPoint: allows using the reference point
5536 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5537 The User can specify any point as the Reference Point.
5538 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5539 MakeGroups: forces the generation of new groups from existing ones
5540 LinearVariation: forces the computation of rotation angles as linear
5541 variation of the given Angles along path steps
5544 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5545 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5546 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5547 Example: :ref:`tui_extrusion_along_path`
5550 n,e,f = [],theObject,theObject
5551 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5552 HasAngles, Angles, LinearVariation,
5553 HasRefPoint, RefPoint, MakeGroups)
5554 if MakeGroups: return gr,er
5557 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5558 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5559 MakeGroups=False, LinearVariation=False):
5561 Generate new elements by extrusion of mesh segments which belong to the object.
5562 The path of extrusion must be a meshed edge.
5565 theObject: the object whose 1D elements should be processed.
5566 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5567 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5568 PathShape: shape (edge) defines the sub-mesh for the path
5569 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5570 HasAngles: allows the shape to be rotated around the path
5571 to get the resulting mesh in a helical fashion
5572 Angles: list of angles
5573 HasRefPoint: allows using the reference point
5574 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5575 The User can specify any point as the Reference Point.
5576 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5577 MakeGroups: forces the generation of new groups from existing ones
5578 LinearVariation: forces the computation of rotation angles as linear
5579 variation of the given Angles along path steps
5582 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5583 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5584 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5585 Example: :ref:`tui_extrusion_along_path`
5588 n,e,f = [],theObject,[]
5589 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5590 HasAngles, Angles, LinearVariation,
5591 HasRefPoint, RefPoint, MakeGroups)
5592 if MakeGroups: return gr,er
5595 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5596 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5597 MakeGroups=False, LinearVariation=False):
5599 Generate new elements by extrusion of faces which belong to the object.
5600 The path of extrusion must be a meshed edge.
5603 theObject: the object whose 2D elements should be processed.
5604 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5605 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5606 PathShape: shape (edge) defines the sub-mesh for the path
5607 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5608 HasAngles: allows the shape to be rotated around the path
5609 to get the resulting mesh in a helical fashion
5610 Angles: list of angles
5611 HasRefPoint: allows using the reference point
5612 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5613 The User can specify any point as the Reference Point.
5614 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5615 MakeGroups: forces the generation of new groups from existing ones
5616 LinearVariation: forces the computation of rotation angles as linear
5617 variation of the given Angles along path steps
5620 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5621 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5622 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5623 Example: :ref:`tui_extrusion_along_path`
5626 n,e,f = [],[],theObject
5627 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5628 HasAngles, Angles, LinearVariation,
5629 HasRefPoint, RefPoint, MakeGroups)
5630 if MakeGroups: return gr,er
5633 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5635 Create a symmetrical copy of mesh elements
5638 IDsOfElements: list of elements ids
5639 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5640 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5641 If the *Mirror* is a geom object this parameter is unnecessary
5642 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5643 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5646 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5649 if IDsOfElements == []:
5650 IDsOfElements = self.GetElementsId()
5651 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5652 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5653 theMirrorType = Mirror._mirrorType
5655 self.mesh.SetParameters(Mirror.parameters)
5656 if Copy and MakeGroups:
5657 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5658 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5661 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5663 Create a new mesh by a symmetrical copy of mesh elements
5666 IDsOfElements: the list of elements ids
5667 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5668 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5669 If the *Mirror* is a geom object this parameter is unnecessary
5670 MakeGroups: to generate new groups from existing ones
5671 NewMeshName: a name of the new mesh to create
5674 instance of class :class:`Mesh`
5677 if IDsOfElements == []:
5678 IDsOfElements = self.GetElementsId()
5679 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5680 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5681 theMirrorType = Mirror._mirrorType
5683 self.mesh.SetParameters(Mirror.parameters)
5684 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5685 MakeGroups, NewMeshName)
5686 return Mesh(self.smeshpyD,self.geompyD,mesh)
5688 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5690 Create a symmetrical copy of the object
5693 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5694 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5695 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5696 If the *Mirror* is a geom object this parameter is unnecessary
5697 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
5698 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5701 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5704 if ( isinstance( theObject, Mesh )):
5705 theObject = theObject.GetMesh()
5706 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5707 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5708 theMirrorType = Mirror._mirrorType
5710 self.mesh.SetParameters(Mirror.parameters)
5711 if Copy and MakeGroups:
5712 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
5713 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
5716 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
5718 Create a new mesh by a symmetrical copy of the object
5721 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5722 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5723 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5724 If the *Mirror* is a geom object this parameter is unnecessary
5725 MakeGroups: forces the generation of new groups from existing ones
5726 NewMeshName: the name of the new mesh to create
5729 instance of class :class:`Mesh`
5732 if ( isinstance( theObject, Mesh )):
5733 theObject = theObject.GetMesh()
5734 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5735 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5736 theMirrorType = Mirror._mirrorType
5738 self.mesh.SetParameters(Mirror.parameters)
5739 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
5740 MakeGroups, NewMeshName)
5741 return Mesh( self.smeshpyD,self.geompyD,mesh )
5743 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
5745 Translate the elements
5748 IDsOfElements: list of elements ids
5749 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5750 Copy: allows copying the translated elements
5751 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5754 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5757 if IDsOfElements == []:
5758 IDsOfElements = self.GetElementsId()
5759 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5760 Vector = self.smeshpyD.GetDirStruct(Vector)
5761 if isinstance( Vector, list ):
5762 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5763 self.mesh.SetParameters(Vector.PS.parameters)
5764 if Copy and MakeGroups:
5765 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
5766 self.editor.Translate(IDsOfElements, Vector, Copy)
5769 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
5771 Create a new mesh of translated elements
5774 IDsOfElements: list of elements ids
5775 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5776 MakeGroups: forces the generation of new groups from existing ones
5777 NewMeshName: the name of the newly created mesh
5780 instance of class :class:`Mesh`
5783 if IDsOfElements == []:
5784 IDsOfElements = self.GetElementsId()
5785 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5786 Vector = self.smeshpyD.GetDirStruct(Vector)
5787 if isinstance( Vector, list ):
5788 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5789 self.mesh.SetParameters(Vector.PS.parameters)
5790 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
5791 return Mesh ( self.smeshpyD, self.geompyD, mesh )
5793 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
5795 Translate the object
5798 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5799 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5800 Copy: allows copying the translated elements
5801 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5804 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5807 if ( isinstance( theObject, Mesh )):
5808 theObject = theObject.GetMesh()
5809 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5810 Vector = self.smeshpyD.GetDirStruct(Vector)
5811 if isinstance( Vector, list ):
5812 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5813 self.mesh.SetParameters(Vector.PS.parameters)
5814 if Copy and MakeGroups:
5815 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
5816 self.editor.TranslateObject(theObject, Vector, Copy)
5819 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
5821 Create a new mesh from the translated object
5824 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5825 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5826 MakeGroups: forces the generation of new groups from existing ones
5827 NewMeshName: the name of the newly created mesh
5830 instance of class :class:`Mesh`
5833 if isinstance( theObject, Mesh ):
5834 theObject = theObject.GetMesh()
5835 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
5836 Vector = self.smeshpyD.GetDirStruct(Vector)
5837 if isinstance( Vector, list ):
5838 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5839 self.mesh.SetParameters(Vector.PS.parameters)
5840 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
5841 return Mesh( self.smeshpyD, self.geompyD, mesh )
5845 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
5850 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5851 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5852 theScaleFact: list of 1-3 scale factors for axises
5853 Copy: allows copying the translated elements
5854 MakeGroups: forces the generation of new groups from existing
5858 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5859 empty list otherwise
5861 unRegister = genObjUnRegister()
5862 if ( isinstance( theObject, Mesh )):
5863 theObject = theObject.GetMesh()
5864 if ( isinstance( theObject, list )):
5865 theObject = self.GetIDSource(theObject, SMESH.ALL)
5866 unRegister.set( theObject )
5867 if ( isinstance( thePoint, list )):
5868 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5869 if ( isinstance( theScaleFact, float )):
5870 theScaleFact = [theScaleFact]
5871 if ( isinstance( theScaleFact, int )):
5872 theScaleFact = [ float(theScaleFact)]
5874 self.mesh.SetParameters(thePoint.parameters)
5876 if Copy and MakeGroups:
5877 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
5878 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
5881 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
5883 Create a new mesh from the translated object
5886 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5887 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5888 theScaleFact: list of 1-3 scale factors for axises
5889 MakeGroups: forces the generation of new groups from existing ones
5890 NewMeshName: the name of the newly created mesh
5893 instance of class :class:`Mesh`
5895 unRegister = genObjUnRegister()
5896 if (isinstance(theObject, Mesh)):
5897 theObject = theObject.GetMesh()
5898 if ( isinstance( theObject, list )):
5899 theObject = self.GetIDSource(theObject,SMESH.ALL)
5900 unRegister.set( theObject )
5901 if ( isinstance( thePoint, list )):
5902 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5903 if ( isinstance( theScaleFact, float )):
5904 theScaleFact = [theScaleFact]
5905 if ( isinstance( theScaleFact, int )):
5906 theScaleFact = [ float(theScaleFact)]
5908 self.mesh.SetParameters(thePoint.parameters)
5909 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
5910 MakeGroups, NewMeshName)
5911 return Mesh( self.smeshpyD, self.geompyD, mesh )
5915 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
5920 IDsOfElements: list of elements ids
5921 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5922 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5923 Copy: allows copying the rotated elements
5924 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5927 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5931 if IDsOfElements == []:
5932 IDsOfElements = self.GetElementsId()
5933 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5934 Axis = self.smeshpyD.GetAxisStruct(Axis)
5935 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5936 Parameters = Axis.parameters + var_separator + Parameters
5937 self.mesh.SetParameters(Parameters)
5938 if Copy and MakeGroups:
5939 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
5940 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
5943 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
5945 Create a new mesh of rotated elements
5948 IDsOfElements: list of element ids
5949 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5950 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5951 MakeGroups: forces the generation of new groups from existing ones
5952 NewMeshName: the name of the newly created mesh
5955 instance of class :class:`Mesh`
5958 if IDsOfElements == []:
5959 IDsOfElements = self.GetElementsId()
5960 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5961 Axis = self.smeshpyD.GetAxisStruct(Axis)
5962 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5963 Parameters = Axis.parameters + var_separator + Parameters
5964 self.mesh.SetParameters(Parameters)
5965 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
5966 MakeGroups, NewMeshName)
5967 return Mesh( self.smeshpyD, self.geompyD, mesh )
5969 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
5974 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5975 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5976 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5977 Copy: allows copying the rotated elements
5978 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5981 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
5984 if (isinstance(theObject, Mesh)):
5985 theObject = theObject.GetMesh()
5986 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5987 Axis = self.smeshpyD.GetAxisStruct(Axis)
5988 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5989 Parameters = Axis.parameters + ":" + Parameters
5990 self.mesh.SetParameters(Parameters)
5991 if Copy and MakeGroups:
5992 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
5993 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
5996 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
5998 Create a new mesh from the rotated object
6001 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6002 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6003 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6004 MakeGroups: forces the generation of new groups from existing ones
6005 NewMeshName: the name of the newly created mesh
6008 instance of class :class:`Mesh`
6011 if (isinstance( theObject, Mesh )):
6012 theObject = theObject.GetMesh()
6013 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6014 Axis = self.smeshpyD.GetAxisStruct(Axis)
6015 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6016 Parameters = Axis.parameters + ":" + Parameters
6017 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6018 MakeGroups, NewMeshName)
6019 self.mesh.SetParameters(Parameters)
6020 return Mesh( self.smeshpyD, self.geompyD, mesh )
6022 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6024 Create an offset mesh from the given 2D object
6027 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6028 theValue (float): signed offset size
6029 MakeGroups (boolean): forces the generation of new groups from existing ones
6030 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6031 False means to remove original elements.
6032 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6035 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6038 if isinstance( theObject, Mesh ):
6039 theObject = theObject.GetMesh()
6040 theValue,Parameters,hasVars = ParseParameters(Value)
6041 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6042 self.mesh.SetParameters(Parameters)
6043 # if mesh_groups[0]:
6044 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6047 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6049 Find groups of adjacent nodes within Tolerance.
6052 Tolerance (float): the value of tolerance
6053 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6054 corner and medium nodes in separate groups thus preventing
6055 their further merge.
6058 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6061 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6063 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6064 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6066 Find groups of adjacent nodes within Tolerance.
6069 Tolerance: the value of tolerance
6070 SubMeshOrGroup: :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6071 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6072 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6073 corner and medium nodes in separate groups thus preventing
6074 their further merge.
6077 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6080 unRegister = genObjUnRegister()
6081 if (isinstance( SubMeshOrGroup, Mesh )):
6082 SubMeshOrGroup = SubMeshOrGroup.GetMesh()
6083 if not isinstance( exceptNodes, list ):
6084 exceptNodes = [ exceptNodes ]
6085 if exceptNodes and isinstance( exceptNodes[0], int ):
6086 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6087 unRegister.set( exceptNodes )
6088 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6089 exceptNodes, SeparateCornerAndMediumNodes)
6091 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6096 GroupsOfNodes: a list of groups of nodes IDs for merging.
6097 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6098 in all elements and groups by nodes 1 and 25 correspondingly
6099 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6100 If *NodesToKeep* does not include a node to keep for some group to merge,
6101 then the first node in the group is kept.
6102 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6105 # NodesToKeep are converted to SMESH.SMESH_IDSource in meshEditor.MergeNodes()
6106 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6108 def FindEqualElements (self, MeshOrSubMeshOrGroup=None):
6110 Find the elements built on the same nodes.
6113 MeshOrSubMeshOrGroup: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6116 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6119 if not MeshOrSubMeshOrGroup:
6120 MeshOrSubMeshOrGroup=self.mesh
6121 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6122 MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh()
6123 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup )
6125 def MergeElements(self, GroupsOfElementsID):
6127 Merge elements in each given group.
6130 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6131 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6132 replaced in all groups by elements 1 and 25)
6135 self.editor.MergeElements(GroupsOfElementsID)
6137 def MergeEqualElements(self):
6139 Leave one element and remove all other elements built on the same nodes.
6142 self.editor.MergeEqualElements()
6144 def FindFreeBorders(self, ClosedOnly=True):
6146 Returns all or only closed free borders
6149 list of SMESH.FreeBorder's
6152 return self.editor.FindFreeBorders( ClosedOnly )
6154 def FillHole(self, holeNodes, groupName=""):
6156 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6159 FreeBorder: either a SMESH.FreeBorder or a list on node IDs. These nodes
6160 must describe all sequential nodes of the hole border. The first and the last
6161 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6162 groupName (string): name of a group to add new faces
6164 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if :option:`groupName` == ""
6168 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6169 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6170 if not isinstance( holeNodes, SMESH.FreeBorder ):
6171 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6172 self.editor.FillHole( holeNodes, groupName )
6174 def FindCoincidentFreeBorders (self, tolerance=0.):
6176 Return groups of FreeBorder's coincident within the given tolerance.
6179 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6180 size of elements adjacent to free borders being compared is used.
6183 SMESH.CoincidentFreeBorders structure
6186 return self.editor.FindCoincidentFreeBorders( tolerance )
6188 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6190 Sew FreeBorder's of each group
6193 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6194 where each enclosed list contains node IDs of a group of coincident free
6195 borders such that each consequent triple of IDs within a group describes
6196 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6197 last node of a border.
6198 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6199 groups of coincident free borders, each group including two borders.
6200 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6201 polygons if a node of opposite border falls on a face edge, else such
6202 faces are split into several ones.
6203 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6204 polyhedra if a node of opposite border falls on a volume edge, else such
6205 volumes, if any, remain intact and the mesh becomes non-conformal.
6208 a number of successfully sewed groups
6211 if freeBorders and isinstance( freeBorders, list ):
6212 # construct SMESH.CoincidentFreeBorders
6213 if isinstance( freeBorders[0], int ):
6214 freeBorders = [freeBorders]
6216 coincidentGroups = []
6217 for nodeList in freeBorders:
6218 if not nodeList or len( nodeList ) % 3:
6219 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6222 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6223 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6224 nodeList = nodeList[3:]
6226 coincidentGroups.append( group )
6228 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6230 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6232 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6233 FirstNodeID2, SecondNodeID2, LastNodeID2,
6234 CreatePolygons, CreatePolyedrs):
6239 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6242 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6243 FirstNodeID2, SecondNodeID2, LastNodeID2,
6244 CreatePolygons, CreatePolyedrs)
6246 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6247 FirstNodeID2, SecondNodeID2):
6249 Sew conform free borders
6252 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6255 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6256 FirstNodeID2, SecondNodeID2)
6258 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6259 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6264 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6267 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6268 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6270 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6271 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6272 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6274 Sew two sides of a mesh. The nodes belonging to Side1 are
6275 merged with the nodes of elements of Side2.
6276 The number of elements in theSide1 and in theSide2 must be
6277 equal and they should have similar nodal connectivity.
6278 The nodes to merge should belong to side borders and
6279 the first node should be linked to the second.
6282 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6285 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6286 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6287 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6289 def ChangeElemNodes(self, ide, newIDs):
6291 Set new nodes for the given element.
6298 False if the number of nodes does not correspond to the type of element
6301 return self.editor.ChangeElemNodes(ide, newIDs)
6303 def GetLastCreatedNodes(self):
6305 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6306 created, this method return the list of their IDs.
6307 If new nodes were not created - return empty list
6310 the list of integer values (can be empty)
6313 return self.editor.GetLastCreatedNodes()
6315 def GetLastCreatedElems(self):
6317 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6318 created this method return the list of their IDs.
6319 If new elements were not created - return empty list
6322 the list of integer values (can be empty)
6325 return self.editor.GetLastCreatedElems()
6327 def ClearLastCreated(self):
6329 Forget what nodes and elements were created by the last mesh edition operation
6332 self.editor.ClearLastCreated()
6334 def DoubleElements(self, theElements, theGroupName=""):
6336 Create duplicates of given elements, i.e. create new elements based on the
6337 same nodes as the given ones.
6340 theElements: container of elements to duplicate. It can be a
6341 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6342 or a list of element IDs. If *theElements* is
6343 a :class:`Mesh`, elements of highest dimension are duplicated
6344 theGroupName: a name of group to contain the generated elements.
6345 If a group with such a name already exists, the new elements
6346 are added to the existing group, else a new group is created.
6347 If *theGroupName* is empty, new elements are not added
6351 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6352 None if *theGroupName* == "".
6355 unRegister = genObjUnRegister()
6356 if isinstance( theElements, Mesh ):
6357 theElements = theElements.mesh
6358 elif isinstance( theElements, list ):
6359 theElements = self.GetIDSource( theElements, SMESH.ALL )
6360 unRegister.set( theElements )
6361 return self.editor.DoubleElements(theElements, theGroupName)
6363 def DoubleNodes(self, theNodes, theModifiedElems):
6365 Create a hole in a mesh by doubling the nodes of some particular elements
6368 theNodes: IDs of nodes to be doubled
6369 theModifiedElems: IDs of elements to be updated by the new (doubled)
6370 nodes. If list of element identifiers is empty then nodes are doubled but
6371 they not assigned to elements
6374 True if operation has been completed successfully, False otherwise
6377 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6379 def DoubleNode(self, theNodeId, theModifiedElems):
6381 Create a hole in a mesh by doubling the nodes of some particular elements.
6382 This method provided for convenience works as :meth:`DoubleNodes`.
6385 theNodeId: IDs of node to double
6386 theModifiedElems: IDs of elements to update
6389 True if operation has been completed successfully, False otherwise
6392 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6394 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6396 Create a hole in a mesh by doubling the nodes of some particular elements.
6397 This method provided for convenience works as :meth:`DoubleNodes`.
6400 theNodes: group of nodes to double.
6401 theModifiedElems: group of elements to update.
6402 theMakeGroup: forces the generation of a group containing new nodes.
6405 True or a created group if operation has been completed successfully,
6406 False or None otherwise
6410 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6411 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6413 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6415 Create a hole in a mesh by doubling the nodes of some particular elements.
6416 This method provided for convenience works as :meth:`DoubleNodes`.
6419 theNodes: list of groups of nodes to double.
6420 theModifiedElems: list of groups of elements to update.
6421 theMakeGroup: forces the generation of a group containing new nodes.
6424 True if operation has been completed successfully, False otherwise
6428 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6429 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6431 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6433 Create a hole in a mesh by doubling the nodes of some particular elements
6436 theElems: the list of elements (edges or faces) to replicate.
6437 The nodes for duplication could be found from these elements
6438 theNodesNot: list of nodes NOT to replicate
6439 theAffectedElems: the list of elements (cells and edges) to which the
6440 replicated nodes should be associated to
6443 True if operation has been completed successfully, False otherwise
6446 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6448 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6450 Create a hole in a mesh by doubling the nodes of some particular elements
6453 theElems: the list of elements (edges or faces) to replicate.
6454 The nodes for duplication could be found from these elements
6455 theNodesNot: list of nodes NOT to replicate
6456 theShape: shape to detect affected elements (element which geometric center
6457 located on or inside shape).
6458 The replicated nodes should be associated to affected elements.
6461 True if operation has been completed successfully, False otherwise
6464 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6466 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6467 theMakeGroup=False, theMakeNodeGroup=False):
6469 Create a hole in a mesh by doubling the nodes of some particular elements.
6470 This method provided for convenience works as :meth:`DoubleNodes`.
6473 theElems: group of of elements (edges or faces) to replicate.
6474 theNodesNot: group of nodes NOT to replicate.
6475 theAffectedElems: group of elements to which the replicated nodes
6476 should be associated to.
6477 theMakeGroup: forces the generation of a group containing new elements.
6478 theMakeNodeGroup: forces the generation of a group containing new nodes.
6481 True or created groups (one or two) if operation has been completed successfully,
6482 False or None otherwise
6485 if theMakeGroup or theMakeNodeGroup:
6486 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6488 theMakeGroup, theMakeNodeGroup)
6489 if theMakeGroup and theMakeNodeGroup:
6492 return twoGroups[ int(theMakeNodeGroup) ]
6493 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6495 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6497 Create a hole in a mesh by doubling the nodes of some particular elements.
6498 This method provided for convenience works as :meth:`DoubleNodes`.
6501 theElems: group of of elements (edges or faces) to replicate
6502 theNodesNot: group of nodes not to replicate
6503 theShape: shape to detect affected elements (element which geometric center
6504 located on or inside shape).
6505 The replicated nodes should be associated to affected elements
6508 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6510 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6511 theMakeGroup=False, theMakeNodeGroup=False):
6513 Create a hole in a mesh by doubling the nodes of some particular elements.
6514 This method provided for convenience works as :meth:`DoubleNodes`.
6517 theElems: list of groups of elements (edges or faces) to replicate
6518 theNodesNot: list of groups of nodes NOT to replicate
6519 theAffectedElems: group of elements to which the replicated nodes
6520 should be associated to
6521 theMakeGroup: forces generation of a group containing new elements.
6522 theMakeNodeGroup: forces generation of a group containing new nodes
6525 True or created groups (one or two) if operation has been completed successfully,
6526 False or None otherwise
6529 if theMakeGroup or theMakeNodeGroup:
6530 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6532 theMakeGroup, theMakeNodeGroup)
6533 if theMakeGroup and theMakeNodeGroup:
6536 return twoGroups[ int(theMakeNodeGroup) ]
6537 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6539 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6541 Create a hole in a mesh by doubling the nodes of some particular elements.
6542 This method provided for convenience works as :meth:`DoubleNodes`.
6545 theElems: list of groups of elements (edges or faces) to replicate
6546 theNodesNot: list of groups of nodes NOT to replicate
6547 theShape: shape to detect affected elements (element which geometric center
6548 located on or inside shape).
6549 The replicated nodes should be associated to affected elements
6552 True if operation has been completed successfully, False otherwise
6555 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6557 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6559 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6560 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6563 theElems: list of groups of nodes or elements (edges or faces) to replicate
6564 theNodesNot: list of groups of nodes NOT to replicate
6565 theShape: shape to detect affected elements (element which geometric center
6566 located on or inside shape).
6567 The replicated nodes should be associated to affected elements
6570 groups of affected elements in order: volumes, faces, edges
6573 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6575 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6578 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6579 The list of groups must describe a partition of the mesh volumes.
6580 The nodes of the internal faces at the boundaries of the groups are doubled.
6581 In option, the internal faces are replaced by flat elements.
6582 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6585 theDomains: list of groups of volumes
6586 createJointElems: if True, create the elements
6587 onAllBoundaries: if True, the nodes and elements are also created on
6588 the boundary between *theDomains* and the rest mesh
6591 True if operation has been completed successfully, False otherwise
6594 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6596 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6598 Double nodes on some external faces and create flat elements.
6599 Flat elements are mainly used by some types of mechanic calculations.
6601 Each group of the list must be constituted of faces.
6602 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6605 theGroupsOfFaces: list of groups of faces
6608 True if operation has been completed successfully, False otherwise
6611 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6613 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6615 Identify all the elements around a geom shape, get the faces delimiting the hole
6617 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
6619 def MakePolyLine(self, segments, groupName='', isPreview=False ):
6621 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
6622 the initial mesh. Positions of new nodes are found by cutting the mesh by the
6623 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
6624 If there are several paths connecting a pair of points, the shortest path is
6625 selected by the module. Position of the cutting plane is defined by the two
6626 points and an optional vector lying on the plane specified by a PolySegment.
6627 By default the vector is defined by Mesh module as following. A middle point
6628 of the two given points is computed. The middle point is projected to the mesh.
6629 The vector goes from the middle point to the projection point. In case of planar
6630 mesh, the vector is normal to the mesh.
6632 *segments* [i].vector returns the used vector which goes from the middle point to its projection.
6635 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
6636 groupName: optional name of a group where created mesh segments will be added.
6639 editor = self.editor
6641 editor = self.mesh.GetMeshEditPreviewer()
6642 segmentsRes = editor.MakePolyLine( segments, groupName )
6643 for i, seg in enumerate( segmentsRes ):
6644 segments[i].vector = seg.vector
6646 return editor.GetPreviewData()
6649 def GetFunctor(self, funcType ):
6651 Return a cached numerical functor by its type.
6654 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
6655 Note that not all items correspond to numerical functors.
6658 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
6661 fn = self.functors[ funcType._v ]
6663 fn = self.smeshpyD.GetFunctor(funcType)
6664 fn.SetMesh(self.mesh)
6665 self.functors[ funcType._v ] = fn
6668 def FunctorValue(self, funcType, elemId, isElem=True):
6670 Return value of a functor for a given element
6673 funcType: an item of :class:`SMESH.FunctorType` enum.
6674 elemId: element or node ID
6675 isElem: *elemId* is ID of element or node
6678 the functor value or zero in case of invalid arguments
6681 fn = self.GetFunctor( funcType )
6682 if fn.GetElementType() == self.GetElementType(elemId, isElem):
6683 val = fn.GetValue(elemId)
6688 def GetLength(self, elemId=None):
6690 Get length of 1D element or sum of lengths of all 1D mesh elements
6693 elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
6696 element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise
6701 length = self.smeshpyD.GetLength(self)
6703 length = self.FunctorValue(SMESH.FT_Length, elemId)
6706 def GetArea(self, elemId=None):
6708 Get area of 2D element or sum of areas of all 2D mesh elements
6709 elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
6712 element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
6717 area = self.smeshpyD.GetArea(self)
6719 area = self.FunctorValue(SMESH.FT_Area, elemId)
6722 def GetVolume(self, elemId=None):
6724 Get volume of 3D element or sum of volumes of all 3D mesh elements
6727 elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
6730 element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
6735 volume = self.smeshpyD.GetVolume(self)
6737 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
6740 def GetMaxElementLength(self, elemId):
6742 Get maximum element length.
6745 elemId: mesh element ID
6748 element's maximum length value
6751 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6752 ftype = SMESH.FT_MaxElementLength3D
6754 ftype = SMESH.FT_MaxElementLength2D
6755 return self.FunctorValue(ftype, elemId)
6757 def GetAspectRatio(self, elemId):
6759 Get aspect ratio of 2D or 3D element.
6762 elemId: mesh element ID
6765 element's aspect ratio value
6768 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6769 ftype = SMESH.FT_AspectRatio3D
6771 ftype = SMESH.FT_AspectRatio
6772 return self.FunctorValue(ftype, elemId)
6774 def GetWarping(self, elemId):
6776 Get warping angle of 2D element.
6779 elemId: mesh element ID
6782 element's warping angle value
6785 return self.FunctorValue(SMESH.FT_Warping, elemId)
6787 def GetMinimumAngle(self, elemId):
6789 Get minimum angle of 2D element.
6792 elemId: mesh element ID
6795 element's minimum angle value
6798 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
6800 def GetTaper(self, elemId):
6802 Get taper of 2D element.
6805 elemId: mesh element ID
6808 element's taper value
6811 return self.FunctorValue(SMESH.FT_Taper, elemId)
6813 def GetSkew(self, elemId):
6815 Get skew of 2D element.
6818 elemId: mesh element ID
6821 element's skew value
6824 return self.FunctorValue(SMESH.FT_Skew, elemId)
6826 def GetMinMax(self, funType, meshPart=None):
6828 Return minimal and maximal value of a given functor.
6831 funType (SMESH.FunctorType): a functor type.
6832 Note that not all items of :class:`SMESH.FunctorType` corresponds
6833 to numerical functors.
6834 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
6840 unRegister = genObjUnRegister()
6841 if isinstance( meshPart, list ):
6842 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
6843 unRegister.set( meshPart )
6844 if isinstance( meshPart, Mesh ):
6845 meshPart = meshPart.mesh
6846 fun = self.GetFunctor( funType )
6849 if hasattr( meshPart, "SetMesh" ):
6850 meshPart.SetMesh( self.mesh ) # set mesh to filter
6851 hist = fun.GetLocalHistogram( 1, False, meshPart )
6853 hist = fun.GetHistogram( 1, False )
6855 return hist[0].min, hist[0].max
6858 pass # end of Mesh class
6861 class meshProxy(SMESH._objref_SMESH_Mesh):
6863 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
6864 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
6866 def __init__(self,*args):
6867 SMESH._objref_SMESH_Mesh.__init__(self,*args)
6868 def __deepcopy__(self, memo=None):
6869 new = self.__class__(self)
6871 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
6872 if len( args ) == 3:
6873 args += SMESH.ALL_NODES, True
6874 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
6875 def ExportToMEDX(self, *args): # function removed
6876 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
6877 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6878 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6879 def ExportToMED(self, *args): # function removed
6880 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
6881 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6883 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
6885 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
6886 def ExportPartToMED(self, *args): # 'version' parameter removed
6887 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6888 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
6889 def ExportMED(self, *args): # signature of method changed
6890 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6892 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
6894 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
6896 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
6899 class submeshProxy(SMESH._objref_SMESH_subMesh):
6902 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
6904 def __init__(self,*args):
6905 SMESH._objref_SMESH_subMesh.__init__(self,*args)
6907 def __deepcopy__(self, memo=None):
6908 new = self.__class__(self)
6911 def Compute(self,refresh=False):
6913 Compute the sub-mesh and return the status of the computation
6916 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
6921 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
6922 :meth:`smeshBuilder.Mesh.GetSubMesh`.
6926 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
6928 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
6930 if salome.sg.hasDesktop():
6931 if refresh: salome.sg.updateObjBrowser()
6936 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
6939 class meshEditor(SMESH._objref_SMESH_MeshEditor):
6941 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
6942 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
6945 def __init__(self,*args):
6946 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
6948 def __getattr__(self, name ): # method called if an attribute not found
6949 if not self.mesh: # look for name() method in Mesh class
6950 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
6951 if hasattr( self.mesh, name ):
6952 return getattr( self.mesh, name )
6953 if name == "ExtrusionAlongPathObjX":
6954 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
6955 print("meshEditor: attribute '%s' NOT FOUND" % name)
6957 def __deepcopy__(self, memo=None):
6958 new = self.__class__(self)
6960 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
6961 if len( args ) == 1: args += False,
6962 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
6963 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
6964 if len( args ) == 2: args += False,
6965 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
6966 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
6967 if len( args ) == 1:
6968 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
6969 NodesToKeep = args[1]
6970 AvoidMakingHoles = args[2] if len( args ) == 3 else False
6971 unRegister = genObjUnRegister()
6973 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
6974 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
6975 if not isinstance( NodesToKeep, list ):
6976 NodesToKeep = [ NodesToKeep ]
6977 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
6979 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
6981 class Pattern(SMESH._objref_SMESH_Pattern):
6983 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
6984 variables in some methods
6987 def LoadFromFile(self, patternTextOrFile ):
6988 text = patternTextOrFile
6989 if os.path.exists( text ):
6990 text = open( patternTextOrFile ).read()
6992 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
6994 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
6995 decrFun = lambda i: i-1
6996 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
6997 theMesh.SetParameters(Parameters)
6998 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7000 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7001 decrFun = lambda i: i-1
7002 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7003 theMesh.SetParameters(Parameters)
7004 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7006 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7007 if isinstance( mesh, Mesh ):
7008 mesh = mesh.GetMesh()
7009 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7011 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7013 Registering the new proxy for Pattern
7018 Private class used to bind methods creating algorithms to the class Mesh
7021 def __init__(self, method):
7023 self.defaultAlgoType = ""
7024 self.algoTypeToClass = {}
7025 self.method = method
7027 def add(self, algoClass):
7029 Store a python class of algorithm
7031 if inspect.isclass(algoClass) and \
7032 hasattr( algoClass, "algoType"):
7033 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7034 if not self.defaultAlgoType and \
7035 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7036 self.defaultAlgoType = algoClass.algoType
7037 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7039 def copy(self, mesh):
7041 Create a copy of self and assign mesh to the copy
7044 other = algoCreator( self.method )
7045 other.defaultAlgoType = self.defaultAlgoType
7046 other.algoTypeToClass = self.algoTypeToClass
7050 def __call__(self,algo="",geom=0,*args):
7052 Create an instance of algorithm
7056 if isinstance( algo, str ):
7058 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7059 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7064 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7066 elif not algoType and isinstance( geom, str ):
7071 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7073 elif isinstance( arg, str ) and not algoType:
7076 import traceback, sys
7077 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7078 sys.stderr.write( msg + '\n' )
7079 tb = traceback.extract_stack(None,2)
7080 traceback.print_list( [tb[0]] )
7082 algoType = self.defaultAlgoType
7083 if not algoType and self.algoTypeToClass:
7084 algoType = sorted( self.algoTypeToClass.keys() )[0]
7085 if algoType in self.algoTypeToClass:
7086 #print("Create algo",algoType)
7087 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7088 raise RuntimeError( "No class found for algo type %s" % algoType)
7091 class hypMethodWrapper:
7093 Private class used to substitute and store variable parameters of hypotheses.
7096 def __init__(self, hyp, method):
7098 self.method = method
7099 #print("REBIND:", method.__name__)
7102 def __call__(self,*args):
7104 call a method of hypothesis with calling SetVarParameter() before
7108 return self.method( self.hyp, *args ) # hypothesis method with no args
7110 #print("MethWrapper.__call__", self.method.__name__, args)
7112 parsed = ParseParameters(*args) # replace variables with their values
7113 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7114 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7115 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7116 # maybe there is a replaced string arg which is not variable
7117 result = self.method( self.hyp, *args )
7118 except ValueError as detail: # raised by ParseParameters()
7120 result = self.method( self.hyp, *args )
7121 except omniORB.CORBA.BAD_PARAM:
7122 raise ValueError(detail) # wrong variable name
7127 class genObjUnRegister:
7129 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7132 def __init__(self, genObj=None):
7133 self.genObjList = []
7137 def set(self, genObj):
7138 "Store one or a list of of SALOME.GenericObj'es"
7139 if isinstance( genObj, list ):
7140 self.genObjList.extend( genObj )
7142 self.genObjList.append( genObj )
7146 for genObj in self.genObjList:
7147 if genObj and hasattr( genObj, "UnRegister" ):
7150 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7152 Bind methods creating mesher plug-ins to the Mesh class
7155 # print("pluginName: ", pluginName)
7156 pluginBuilderName = pluginName + "Builder"
7158 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7159 except Exception as e:
7160 from salome_utils import verbose
7161 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7163 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7164 plugin = eval( pluginBuilderName )
7165 # print(" plugin:" , str(plugin))
7167 # add methods creating algorithms to Mesh
7168 for k in dir( plugin ):
7169 if k[0] == '_': continue
7170 algo = getattr( plugin, k )
7171 #print(" algo:", str(algo))
7172 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7173 #print(" meshMethod:" , str(algo.meshMethod))
7174 if not hasattr( Mesh, algo.meshMethod ):
7175 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7177 _mmethod = getattr( Mesh, algo.meshMethod )
7178 if hasattr( _mmethod, "add" ):