1 # Copyright (C) 2007-2022 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
43 from StdMeshers import BlockCS
50 # In case the omniORBpy EnumItem class does not fully support Python 3
51 # (for instance in version 4.2.1-2), the comparison ordering methods must be
55 SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
57 def enumitem_eq(self, other):
59 if isinstance(other, omniORB.EnumItem):
60 if other._parent_id == self._parent_id:
61 return self._v == other._v
63 return self._parent_id == other._parent_id
65 return id(self) == id(other)
67 return id(self) == id(other)
69 def enumitem_lt(self, other):
71 if isinstance(other, omniORB.EnumItem):
72 if other._parent_id == self._parent_id:
73 return self._v < other._v
75 return self._parent_id < other._parent_id
77 return id(self) < id(other)
79 return id(self) < id(other)
81 def enumitem_le(self, other):
83 if isinstance(other, omniORB.EnumItem):
84 if other._parent_id == self._parent_id:
85 return self._v <= other._v
87 return self._parent_id <= other._parent_id
89 return id(self) <= id(other)
91 return id(self) <= id(other)
93 def enumitem_gt(self, other):
95 if isinstance(other, omniORB.EnumItem):
96 if other._parent_id == self._parent_id:
97 return self._v > other._v
99 return self._parent_id > other._parent_id
101 return id(self) > id(other)
103 return id(self) > id(other)
105 def enumitem_ge(self, other):
107 if isinstance(other, omniORB.EnumItem):
108 if other._parent_id == self._parent_id:
109 return self._v >= other._v
111 return self._parent_id >= other._parent_id
113 return id(self) >= id(other)
115 return id(self) >= id(other)
117 omniORB.EnumItem.__eq__ = enumitem_eq
118 omniORB.EnumItem.__lt__ = enumitem_lt
119 omniORB.EnumItem.__le__ = enumitem_le
120 omniORB.EnumItem.__gt__ = enumitem_gt
121 omniORB.EnumItem.__ge__ = enumitem_ge
124 class MeshMeta(type):
125 """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
127 def __instancecheck__(cls, inst):
128 """Implement isinstance(inst, cls)."""
129 return any(cls.__subclasscheck__(c)
130 for c in {type(inst), inst.__class__})
132 def __subclasscheck__(cls, sub):
133 """Implement issubclass(sub, cls)."""
134 return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
136 def DegreesToRadians(AngleInDegrees):
137 """Convert an angle from degrees to radians
140 return AngleInDegrees * pi / 180.0
142 import salome_notebook
143 notebook = salome_notebook.notebook
144 # Salome notebook variable separator
147 def ParseParameters(*args):
149 Return list of variable values from salome notebook.
150 The last argument, if is callable, is used to modify values got from notebook
156 if args and callable(args[-1]):
157 args, varModifFun = args[:-1], args[-1]
158 for parameter in args:
160 Parameters += str(parameter) + var_separator
162 if isinstance(parameter,str):
163 # check if there is an inexistent variable name
164 if not notebook.isVariable(parameter):
165 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
166 parameter = notebook.get(parameter)
169 parameter = varModifFun(parameter)
172 Result.append(parameter)
175 Parameters = Parameters[:-1]
176 Result.append( Parameters )
177 Result.append( hasVariables )
180 def ParseAngles(*args):
182 Parse parameters while converting variables to radians
184 return ParseParameters( *( args + (DegreesToRadians, )))
186 def __initPointStruct(point,*args):
188 Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
189 Parameters are stored in PointStruct.parameters attribute
191 point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
193 SMESH.PointStruct.__init__ = __initPointStruct
195 def __initAxisStruct(ax,*args):
197 Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
198 Parameters are stored in AxisStruct.parameters attribute
201 raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
202 ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
204 SMESH.AxisStruct.__init__ = __initAxisStruct
206 smeshPrecisionConfusion = 1.e-07
207 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
208 """Compare real values using smeshPrecisionConfusion as tolerance
210 if abs(val1 - val2) < tol:
218 Return a name of an object
225 if isinstance(obj, SALOMEDS._objref_SObject):
229 ior = salome.orb.object_to_string(obj)
233 sobj = salome.myStudy.FindObjectIOR(ior)
235 return sobj.GetName()
236 if hasattr(obj, "GetName"):
237 # unknown CORBA object, having GetName() method
240 # unknown CORBA object, no GetName() method
243 if hasattr(obj, "GetName"):
244 # unknown non-CORBA object, having GetName() method
247 raise RuntimeError("Null or invalid object")
249 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
251 Print error message if a hypothesis was not assigned.
254 hypType = "algorithm"
256 hypType = "hypothesis"
259 if hasattr( status, "__getitem__" ):
260 status, reason = status[0], status[1]
261 if status == HYP_UNKNOWN_FATAL:
262 reason = "for unknown reason"
263 elif status == HYP_INCOMPATIBLE:
264 reason = "this hypothesis mismatches the algorithm"
265 elif status == HYP_NOTCONFORM:
266 reason = "a non-conform mesh would be built"
267 elif status == HYP_ALREADY_EXIST:
268 if isAlgo: return # it does not influence anything
269 reason = hypType + " of the same dimension is already assigned to this shape"
270 elif status == HYP_BAD_DIM:
271 reason = hypType + " mismatches the shape"
272 elif status == HYP_CONCURRENT :
273 reason = "there are concurrent hypotheses on sub-shapes"
274 elif status == HYP_BAD_SUBSHAPE:
275 reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
276 elif status == HYP_BAD_GEOMETRY:
277 reason = "the algorithm is not applicable to this geometry"
278 elif status == HYP_HIDDEN_ALGO:
279 reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
280 elif status == HYP_HIDING_ALGO:
281 reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
282 elif status == HYP_NEED_SHAPE:
283 reason = "algorithm can't work without shape"
284 elif status == HYP_INCOMPAT_HYPS:
290 where = '"%s"' % geomName
292 meshName = GetName( mesh )
293 if meshName and meshName != NO_NAME:
294 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
295 if status < HYP_UNKNOWN_FATAL and where:
296 print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
298 print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
300 print('"%s" was not assigned : %s' %( hypName, reason ))
303 def AssureGeomPublished(mesh, geom, name=''):
305 Private method. Add geom (sub-shape of the main shape) into the study if not yet there
307 if not mesh.smeshpyD.IsEnablePublish():
309 if not hasattr( geom, "GetShapeType" ):
311 if not geom.GetStudyEntry():
313 if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
314 # for all groups SubShapeName() return "Compound_-1"
315 name = mesh.geompyD.SubShapeName(geom, mesh.geom)
317 name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
319 mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
322 # def FirstVertexOnCurve(mesh, edge):
325 # the first vertex of a geometrical edge by ignoring orientation
327 # return mesh.geompyD.GetVertexByIndex( edge, 0, False )
333 smeshInst is a singleton
339 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
341 This class allows to create, load or manipulate meshes.
342 It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
343 It also has methods to get infos and measure meshes.
346 # MirrorType enumeration
347 POINT = SMESH_MeshEditor.POINT
348 AXIS = SMESH_MeshEditor.AXIS
349 PLANE = SMESH_MeshEditor.PLANE
351 # Smooth_Method enumeration
352 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
353 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
355 PrecisionConfusion = smeshPrecisionConfusion
357 # TopAbs_State enumeration
358 [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
360 # Methods of splitting a hexahedron into tetrahedra
361 Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
363 def __new__(cls, *args):
367 #print("==== __new__", engine, smeshInst, doLcc)
369 if smeshInst is None:
370 # smesh engine is either retrieved from engine, or created
372 # Following test avoids a recursive loop
374 if smeshInst is not None:
375 # smesh engine not created: existing engine found
379 # FindOrLoadComponent called:
380 # 1. CORBA resolution of server
381 # 2. the __new__ method is called again
382 #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
383 smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
385 # FindOrLoadComponent not called
386 if smeshInst is None:
387 # smeshBuilder instance is created from lcc.FindOrLoadComponent
388 #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
389 smeshInst = super(smeshBuilder,cls).__new__(cls)
391 # smesh engine not created: existing engine found
392 #print("==== existing ", engine, smeshInst, doLcc)
394 #print("====1 ", smeshInst)
397 #print("====2 ", smeshInst)
400 def __init__(self, *args):
402 #print("--------------- smeshbuilder __init__ ---", created)
405 SMESH._objref_SMESH_Gen.__init__(self, *args)
408 def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
410 Dump component to the Python script.
411 This method overrides IDL function to allow default values for the parameters.
414 return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
416 def SetDumpPythonHistorical(self, isHistorical):
418 Set mode of DumpPython(), *historical* or *snapshot*.
419 In the *historical* mode, the Python Dump script includes all commands
420 performed by SMESH engine. In the *snapshot* mode, commands
421 relating to objects removed from the Study are excluded from the script
422 as well as commands not influencing the current state of meshes
425 if isHistorical: val = "true"
427 SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
429 def init_smesh(self,geompyD = None):
431 Set Geometry component
434 self.UpdateStudy(geompyD)
435 notebook.myStudy = salome.myStudy
437 def Mesh(self, obj=0, name=0):
439 Create a mesh. This mesh can be either
441 * an empty mesh not bound to geometry, if *obj* == 0
442 * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
443 * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
448 1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
451 salome.myStudy.FindObjectID("0:1:2:3").GetObject()
453 2. a geometrical object for meshing
455 name: the name for the new mesh.
458 an instance of class :class:`Mesh`.
461 if isinstance(obj,str):
463 return Mesh(self, self.geompyD, obj, name)
465 def RemoveMesh( self, mesh ):
469 if isinstance( mesh, Mesh ):
470 mesh = mesh.GetMesh()
472 if not isinstance( mesh, SMESH._objref_SMESH_Mesh ):
473 raise TypeError("%s is not a mesh" % mesh )
474 so = salome.ObjectToSObject( mesh )
476 sb = salome.myStudy.NewBuilder()
477 sb.RemoveObjectWithChildren( so )
483 def EnumToLong(self,theItem):
485 Return a long value from enumeration
490 def ColorToString(self,c):
492 Convert SALOMEDS.Color to string.
493 To be used with filters.
496 c: color value (SALOMEDS.Color)
499 a string representation of the color.
503 if isinstance(c, SALOMEDS.Color):
504 val = "%s;%s;%s" % (c.R, c.G, c.B)
505 elif isinstance(c, str):
508 raise ValueError("Color value should be of string or SALOMEDS.Color type")
511 def GetPointStruct(self,theVertex):
513 Get :class:`SMESH.PointStruct` from vertex
516 theVertex (GEOM.GEOM_Object): vertex
519 :class:`SMESH.PointStruct`
521 geompyD = theVertex.GetGen()
522 [x, y, z] = geompyD.PointCoordinates(theVertex)
523 return PointStruct(x,y,z)
525 def GetDirStruct(self,theVector):
527 Get :class:`SMESH.DirStruct` from vector
530 theVector (GEOM.GEOM_Object): vector
533 :class:`SMESH.DirStruct`
535 geompyD = theVector.GetGen()
536 vertices = geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
537 if(len(vertices) != 2):
538 print("Error: vector object is incorrect.")
540 p1 = geompyD.PointCoordinates(vertices[0])
541 p2 = geompyD.PointCoordinates(vertices[1])
542 pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
543 dirst = DirStruct(pnt)
546 def MakeDirStruct(self,x,y,z):
548 Make :class:`SMESH.DirStruct` from a triplet of floats
551 x,y,z (float): vector components
554 :class:`SMESH.DirStruct`
557 pnt = PointStruct(x,y,z)
558 return DirStruct(pnt)
560 def GetAxisStruct(self,theObj):
562 Get :class:`SMESH.AxisStruct` from a geometrical object
565 theObj (GEOM.GEOM_Object): line or plane
568 :class:`SMESH.AxisStruct`
571 geompyD = theObj.GetGen()
572 edges = geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
575 vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
576 vertex3, vertex4 = geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
577 vertex1 = geompyD.PointCoordinates(vertex1)
578 vertex2 = geompyD.PointCoordinates(vertex2)
579 vertex3 = geompyD.PointCoordinates(vertex3)
580 vertex4 = geompyD.PointCoordinates(vertex4)
581 v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
582 v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
583 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] ]
584 axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
585 axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
586 elif len(edges) == 1:
587 vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
588 p1 = geompyD.PointCoordinates( vertex1 )
589 p2 = geompyD.PointCoordinates( vertex2 )
590 axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
591 axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
592 elif theObj.GetShapeType() == GEOM.VERTEX:
593 x,y,z = geompyD.PointCoordinates( theObj )
594 axis = AxisStruct( x,y,z, 1,0,0,)
595 axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
598 # From SMESH_Gen interface:
599 # ------------------------
601 def SetName(self, obj, name):
603 Set the given name to an object
606 obj: the object to rename
607 name: a new object name
610 if isinstance( obj, Mesh ):
612 elif isinstance( obj, Mesh_Algorithm ):
613 obj = obj.GetAlgorithm()
614 ior = salome.orb.object_to_string(obj)
615 SMESH._objref_SMESH_Gen.SetName(self, ior, name)
617 def SetEmbeddedMode( self,theMode ):
622 SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
624 def IsEmbeddedMode(self):
629 return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
631 def UpdateStudy( self, geompyD = None ):
633 Update the current study. Calling UpdateStudy() allows to
634 update meshes at switching GEOM->SMESH
638 from salome.geom import geomBuilder
639 geompyD = geomBuilder.geom
641 geompyD = geomBuilder.New()
644 self.SetGeomEngine(geompyD)
645 SMESH._objref_SMESH_Gen.UpdateStudy(self)
646 sb = salome.myStudy.NewBuilder()
647 sc = salome.myStudy.FindComponent("SMESH")
649 sb.LoadWith(sc, self)
652 def SetEnablePublish( self, theIsEnablePublish ):
654 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
655 switch **off** publishing in the Study of mesh objects.
657 #self.SetEnablePublish(theIsEnablePublish)
658 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
660 notebook = salome_notebook.NoteBook( theIsEnablePublish )
663 def CreateMeshesFromUNV( self,theFileName ):
665 Create a Mesh object importing data from the given UNV file
668 an instance of class :class:`Mesh`
671 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
672 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
675 def CreateMeshesFromMED( self,theFileName ):
677 Create a Mesh object(s) importing data from the given MED file
680 a tuple ( list of class :class:`Mesh` instances,
681 :class:`SMESH.DriverMED_ReadStatus` )
684 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
685 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
686 return aMeshes, aStatus
688 def CreateMeshesFromSTL( self, theFileName ):
690 Create a Mesh object importing data from the given STL file
693 an instance of class :class:`Mesh`
696 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
697 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
700 def CreateMeshesFromCGNS( self, theFileName ):
702 Create Mesh objects importing data from the given CGNS file
705 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
708 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
709 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
710 return aMeshes, aStatus
712 def CreateMeshesFromGMF( self, theFileName ):
714 Create a Mesh object importing data from the given GMF file.
715 GMF files must have .mesh extension for the ASCII format and .meshb for
719 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
722 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
725 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
726 return Mesh(self, self.geompyD, aSmeshMesh), error
728 def Concatenate( self, meshes, uniteIdenticalGroups,
729 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
730 name = "", meshToAppendTo = None):
732 Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
733 All groups of input meshes will be present in the new mesh.
736 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
737 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
738 mergeNodesAndElements: if True, equal nodes and elements are merged
739 mergeTolerance: tolerance for merging nodes
740 allGroups: forces creation of groups corresponding to every input mesh
741 name: name of a new mesh
742 meshToAppendTo: a mesh to append all given meshes
745 an instance of class :class:`Mesh`
751 if not meshes: return None
752 if not isinstance( meshes, list ):
754 for i,m in enumerate( meshes ):
755 if isinstance( m, Mesh ):
756 meshes[i] = m.GetMesh()
757 mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
758 if hasattr(meshes[0], "SetParameters"):
759 meshes[0].SetParameters( Parameters )
761 meshes[0].GetMesh().SetParameters( Parameters )
762 if isinstance( meshToAppendTo, Mesh ):
763 meshToAppendTo = meshToAppendTo.GetMesh()
765 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
766 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
767 mergeTolerance,meshToAppendTo )
769 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
770 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
771 mergeTolerance,meshToAppendTo )
773 aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
776 def CreateDualMesh( self, mesh, meshName):
778 Create a dual of a mesh.
781 mesh: Tetrahedron mesh
782 :class:`mesh, <SMESH.SMESH_IDSource>`.
784 meshName: a name of the new mesh
787 an instance of class :class:`Mesh`
789 if isinstance( mesh, Mesh ):
790 mesh = mesh.GetMesh()
791 dualMesh = SMESH._objref_SMESH_Gen.CreateDualMesh(self, mesh, meshName)
792 return Mesh(self, self.geompyD, dualMesh)
795 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
797 Create a mesh by copying a part of another mesh.
800 meshPart: a part of mesh to copy, either
801 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
802 To copy nodes or elements not forming any mesh object,
803 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
804 meshName: a name of the new mesh
805 toCopyGroups: to create in the new mesh groups the copied elements belongs to
806 toKeepIDs: to preserve order of the copied elements or not
809 an instance of class :class:`Mesh`
812 if isinstance( meshPart, Mesh ):
813 meshPart = meshPart.GetMesh()
814 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
815 return Mesh(self, self.geompyD, mesh)
817 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
818 toReuseHypotheses=True, toCopyElements=True):
820 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
821 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
822 To facilitate and speed up the operation, consider using
823 "Set presentation parameters and sub-shapes from arguments" option in
824 a dialog of geometrical operation used to create the new geometry.
827 sourceMesh: the mesh to copy definition of.
828 newGeom: the new geometry.
829 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
830 toCopyGroups: to create groups in the new mesh.
831 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
832 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
835 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
836 *invalidEntries* are study entries of objects whose
837 counterparts are not found in the *newGeom*, followed by entries
838 of mesh sub-objects that are invalid because they depend on a not found
841 if isinstance( sourceMesh, Mesh ):
842 sourceMesh = sourceMesh.GetMesh()
844 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
845 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
849 return ( ok, Mesh(self, self.geompyD, newMesh),
850 newGroups, newSubMeshes, newHypotheses, invalidEntries )
852 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
854 Return IDs of sub-shapes
857 theMainObject (GEOM.GEOM_Object): a shape
858 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
860 the list of integer values
863 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
865 def GetPattern(self):
867 Create a pattern mapper.
870 an instance of :class:`SMESH.SMESH_Pattern`
872 :ref:`Example of Patterns usage <tui_pattern_mapping>`
875 return SMESH._objref_SMESH_Gen.GetPattern(self)
877 def SetBoundaryBoxSegmentation(self, nbSegments):
879 Set number of segments per diagonal of boundary box of geometry, by which
880 default segment length of appropriate 1D hypotheses is defined in GUI.
884 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
886 # Filtering. Auxiliary functions:
887 # ------------------------------
889 def GetEmptyCriterion(self):
891 Create an empty criterion
894 :class:`SMESH.Filter.Criterion`
897 Type = self.EnumToLong(FT_Undefined)
898 Compare = self.EnumToLong(FT_Undefined)
902 UnaryOp = self.EnumToLong(FT_Undefined)
903 BinaryOp = self.EnumToLong(FT_Undefined)
906 Precision = -1 ##@1e-07
907 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
908 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
910 def GetCriterion(self,elementType,
912 Compare = FT_EqualTo,
914 UnaryOp=FT_Undefined,
915 BinaryOp=FT_Undefined,
918 Create a criterion by the given parameters
919 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
922 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
923 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
924 Note that the items starting from FT_LessThan are not suitable for *CritType*.
925 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
926 Threshold: the threshold value (range of ids as string, shape, numeric)
927 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
928 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
930 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
931 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
934 :class:`SMESH.Filter.Criterion`
936 Example: :ref:`combining_filters`
939 if not CritType in SMESH.FunctorType._items:
940 raise TypeError("CritType should be of SMESH.FunctorType")
941 aCriterion = self.GetEmptyCriterion()
942 aCriterion.TypeOfElement = elementType
943 aCriterion.Type = self.EnumToLong(CritType)
944 aCriterion.Tolerance = Tolerance
946 aThreshold = Threshold
948 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
949 aCriterion.Compare = self.EnumToLong(Compare)
950 elif Compare == "=" or Compare == "==":
951 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
953 aCriterion.Compare = self.EnumToLong(FT_LessThan)
955 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
956 elif Compare != FT_Undefined:
957 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
960 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
961 FT_BelongToCylinder, FT_LyingOnGeom]:
962 # Check that Threshold is GEOM object
963 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
964 aCriterion.ThresholdStr = GetName(aThreshold)
965 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
966 if not aCriterion.ThresholdID:
967 name = aCriterion.ThresholdStr
969 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
970 geompyD = aThreshold.GetGen()
971 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
972 # or a name of GEOM object
973 elif isinstance( aThreshold, str ):
974 aCriterion.ThresholdStr = aThreshold
976 raise TypeError("The Threshold should be a shape.")
977 if isinstance(UnaryOp,float):
978 aCriterion.Tolerance = UnaryOp
979 UnaryOp = FT_Undefined
981 elif CritType == FT_BelongToMeshGroup:
982 # Check that Threshold is a group
983 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
984 if aThreshold.GetType() != elementType:
985 raise ValueError("Group type mismatches Element type")
986 aCriterion.ThresholdStr = aThreshold.GetName()
987 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
988 study = salome.myStudy
990 so = study.FindObjectIOR( aCriterion.ThresholdID )
994 aCriterion.ThresholdID = entry
996 raise TypeError("The Threshold should be a Mesh Group")
997 elif CritType == FT_RangeOfIds:
998 # Check that Threshold is string
999 if isinstance(aThreshold, str):
1000 aCriterion.ThresholdStr = aThreshold
1002 raise TypeError("The Threshold should be a string.")
1003 elif CritType == FT_CoplanarFaces:
1004 # Check the Threshold
1005 if isinstance(aThreshold, int):
1006 aCriterion.ThresholdID = str(aThreshold)
1007 elif isinstance(aThreshold, str):
1008 ID = int(aThreshold)
1010 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
1011 aCriterion.ThresholdID = aThreshold
1013 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1014 elif CritType == FT_ConnectedElements:
1015 # Check the Threshold
1016 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1017 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1018 if not aCriterion.ThresholdID:
1019 name = aThreshold.GetName()
1021 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1022 geompyD = aThreshold.GetGen()
1023 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
1024 elif isinstance(aThreshold, int): # node id
1025 aCriterion.Threshold = aThreshold
1026 elif isinstance(aThreshold, list): # 3 point coordinates
1027 if len( aThreshold ) < 3:
1028 raise ValueError("too few point coordinates, must be 3")
1029 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1030 elif isinstance(aThreshold, str):
1031 if aThreshold.isdigit():
1032 aCriterion.Threshold = aThreshold # node id
1034 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1036 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1037 "or a list of point coordinates and not '%s'"%aThreshold)
1038 elif CritType == FT_ElemGeomType:
1039 # Check the Threshold
1041 aCriterion.Threshold = self.EnumToLong(aThreshold)
1042 assert( aThreshold in SMESH.GeometryType._items )
1044 if isinstance(aThreshold, int):
1045 aCriterion.Threshold = aThreshold
1047 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1050 elif CritType == FT_EntityType:
1051 # Check the Threshold
1053 aCriterion.Threshold = self.EnumToLong(aThreshold)
1054 assert( aThreshold in SMESH.EntityType._items )
1056 if isinstance(aThreshold, int):
1057 aCriterion.Threshold = aThreshold
1059 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1063 elif CritType == FT_GroupColor:
1064 # Check the Threshold
1066 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1068 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1070 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1071 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1072 FT_BareBorderFace, FT_BareBorderVolume,
1073 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1074 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1075 # At this point the Threshold is unnecessary
1076 if aThreshold == FT_LogicalNOT:
1077 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1078 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1079 aCriterion.BinaryOp = aThreshold
1083 aThreshold = float(aThreshold)
1084 aCriterion.Threshold = aThreshold
1086 raise TypeError("The Threshold should be a number.")
1089 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1090 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1092 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1093 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1095 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1096 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1098 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1099 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1103 def GetFilter(self,elementType,
1104 CritType=FT_Undefined,
1107 UnaryOp=FT_Undefined,
1111 Create a filter with the given parameters
1114 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1115 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1116 Note that the items starting from FT_LessThan are not suitable for CritType.
1117 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1118 Threshold: the threshold value (range of ids as string, shape, numeric)
1119 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1120 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1121 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1122 mesh: the mesh to initialize the filter with
1125 :class:`SMESH.Filter`
1128 See :doc:`Filters usage examples <tui_filters>`
1131 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1132 aFilterMgr = self.CreateFilterManager()
1133 aFilter = aFilterMgr.CreateFilter()
1135 aCriteria.append(aCriterion)
1136 aFilter.SetCriteria(aCriteria)
1138 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1139 else : aFilter.SetMesh( mesh )
1140 aFilterMgr.UnRegister()
1143 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1145 Create a filter from criteria
1148 criteria: a list of :class:`SMESH.Filter.Criterion`
1149 binOp: binary operator used when binary operator of criteria is undefined
1152 :class:`SMESH.Filter`
1155 See :doc:`Filters usage examples <tui_filters>`
1158 for i in range( len( criteria ) - 1 ):
1159 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1160 criteria[i].BinaryOp = self.EnumToLong( binOp )
1161 aFilterMgr = self.CreateFilterManager()
1162 aFilter = aFilterMgr.CreateFilter()
1163 aFilter.SetCriteria(criteria)
1164 aFilterMgr.UnRegister()
1167 def GetFunctor(self,theCriterion):
1169 Create a numerical functor by its type
1172 theCriterion (SMESH.FunctorType): functor type.
1173 Note that not all items correspond to numerical functors.
1176 :class:`SMESH.NumericalFunctor`
1179 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1181 aFilterMgr = self.CreateFilterManager()
1183 if theCriterion == FT_AspectRatio:
1184 functor = aFilterMgr.CreateAspectRatio()
1185 elif theCriterion == FT_AspectRatio3D:
1186 functor = aFilterMgr.CreateAspectRatio3D()
1187 elif theCriterion == FT_Warping:
1188 functor = aFilterMgr.CreateWarping()
1189 elif theCriterion == FT_MinimumAngle:
1190 functor = aFilterMgr.CreateMinimumAngle()
1191 elif theCriterion == FT_Taper:
1192 functor = aFilterMgr.CreateTaper()
1193 elif theCriterion == FT_Skew:
1194 functor = aFilterMgr.CreateSkew()
1195 elif theCriterion == FT_Area:
1196 functor = aFilterMgr.CreateArea()
1197 elif theCriterion == FT_Volume3D:
1198 functor = aFilterMgr.CreateVolume3D()
1199 elif theCriterion == FT_MaxElementLength2D:
1200 functor = aFilterMgr.CreateMaxElementLength2D()
1201 elif theCriterion == FT_MaxElementLength3D:
1202 functor = aFilterMgr.CreateMaxElementLength3D()
1203 elif theCriterion == FT_MultiConnection:
1204 functor = aFilterMgr.CreateMultiConnection()
1205 elif theCriterion == FT_MultiConnection2D:
1206 functor = aFilterMgr.CreateMultiConnection2D()
1207 elif theCriterion == FT_Length:
1208 functor = aFilterMgr.CreateLength()
1209 elif theCriterion == FT_Length2D:
1210 functor = aFilterMgr.CreateLength2D()
1211 elif theCriterion == FT_Length3D:
1212 functor = aFilterMgr.CreateLength3D()
1213 elif theCriterion == FT_Deflection2D:
1214 functor = aFilterMgr.CreateDeflection2D()
1215 elif theCriterion == FT_NodeConnectivityNumber:
1216 functor = aFilterMgr.CreateNodeConnectivityNumber()
1217 elif theCriterion == FT_BallDiameter:
1218 functor = aFilterMgr.CreateBallDiameter()
1220 print("Error: given parameter is not numerical functor type.")
1221 aFilterMgr.UnRegister()
1224 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1229 theHType (string): mesh hypothesis type
1230 theLibName (string): mesh plug-in library name
1233 created hypothesis instance
1235 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1237 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1240 # wrap hypothesis methods
1241 for meth_name in dir( hyp.__class__ ):
1242 if not meth_name.startswith("Get") and \
1243 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1244 method = getattr ( hyp.__class__, meth_name )
1245 if callable(method):
1246 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1250 def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1252 Create hypothesis initialized according to parameters
1255 hypType (string): hypothesis type
1256 libName (string): plug-in library name
1257 mesh: optional mesh by which a hypotheses can initialize self
1258 shape: optional geometry by size of which a hypotheses can initialize self
1259 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1262 created hypothesis instance
1264 if isinstance( mesh, Mesh ):
1265 mesh = mesh.GetMesh()
1266 if isinstance( initParams, (bool,int)):
1267 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1268 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1269 mesh, shape, initParams )
1271 def GetMeshInfo(self, obj):
1273 Get the mesh statistic.
1276 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1279 if isinstance( obj, Mesh ):
1282 if hasattr(obj, "GetMeshInfo"):
1283 values = obj.GetMeshInfo()
1284 for i in range(SMESH.Entity_Last._v):
1285 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1289 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1291 Get minimum distance between two objects
1293 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1294 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1297 src1 (SMESH.SMESH_IDSource): first source object
1298 src2 (SMESH.SMESH_IDSource): second source object
1299 id1 (int): node/element id from the first source
1300 id2 (int): node/element id from the second (or first) source
1301 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1302 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1305 minimum distance value
1308 :meth:`GetMinDistance`
1311 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1315 result = result.value
1318 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1320 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1322 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1323 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1326 src1 (SMESH.SMESH_IDSource): first source object
1327 src2 (SMESH.SMESH_IDSource): second source object
1328 id1 (int): node/element id from the first source
1329 id2 (int): node/element id from the second (or first) source
1330 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1331 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1334 :class:`SMESH.Measure` structure or None if input data is invalid
1339 if isinstance(src1, Mesh): src1 = src1.mesh
1340 if isinstance(src2, Mesh): src2 = src2.mesh
1341 if src2 is None and id2 != 0: src2 = src1
1342 if not hasattr(src1, "_narrow"): return None
1343 src1 = src1._narrow(SMESH.SMESH_IDSource)
1344 if not src1: return None
1345 unRegister = genObjUnRegister()
1348 e = m.GetMeshEditor()
1350 src1 = e.MakeIDSource([id1], SMESH.FACE)
1352 src1 = e.MakeIDSource([id1], SMESH.NODE)
1353 unRegister.set( src1 )
1355 if hasattr(src2, "_narrow"):
1356 src2 = src2._narrow(SMESH.SMESH_IDSource)
1357 if src2 and id2 != 0:
1359 e = m.GetMeshEditor()
1361 src2 = e.MakeIDSource([id2], SMESH.FACE)
1363 src2 = e.MakeIDSource([id2], SMESH.NODE)
1364 unRegister.set( src2 )
1367 aMeasurements = self.CreateMeasurements()
1368 unRegister.set( aMeasurements )
1369 result = aMeasurements.MinDistance(src1, src2)
1372 def BoundingBox(self, objects):
1374 Get bounding box of the specified object(s)
1377 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1380 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1383 :meth:`GetBoundingBox`
1386 result = self.GetBoundingBox(objects)
1390 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1393 def GetBoundingBox(self, objects):
1395 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1398 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1401 :class:`SMESH.Measure` structure
1407 if isinstance(objects, tuple):
1408 objects = list(objects)
1409 if not isinstance(objects, list):
1413 if isinstance(o, Mesh):
1414 srclist.append(o.mesh)
1415 elif hasattr(o, "_narrow"):
1416 src = o._narrow(SMESH.SMESH_IDSource)
1417 if src: srclist.append(src)
1420 aMeasurements = self.CreateMeasurements()
1421 result = aMeasurements.BoundingBox(srclist)
1422 aMeasurements.UnRegister()
1425 def GetLength(self, obj):
1427 Get sum of lengths of all 1D elements in the mesh object.
1430 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1433 sum of lengths of all 1D elements
1436 if isinstance(obj, Mesh): obj = obj.mesh
1437 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1438 aMeasurements = self.CreateMeasurements()
1439 value = aMeasurements.Length(obj)
1440 aMeasurements.UnRegister()
1443 def GetArea(self, obj):
1445 Get sum of areas of all 2D elements in the mesh object.
1448 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1451 sum of areas of all 2D elements
1454 if isinstance(obj, Mesh): obj = obj.mesh
1455 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1456 aMeasurements = self.CreateMeasurements()
1457 value = aMeasurements.Area(obj)
1458 aMeasurements.UnRegister()
1461 def GetVolume(self, obj):
1463 Get sum of volumes of all 3D elements in the mesh object.
1466 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1469 sum of volumes of all 3D elements
1472 if isinstance(obj, Mesh): obj = obj.mesh
1473 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1474 aMeasurements = self.CreateMeasurements()
1475 value = aMeasurements.Volume(obj)
1476 aMeasurements.UnRegister()
1479 def GetGravityCenter(self, obj):
1481 Get gravity center of all nodes of a mesh object.
1484 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1487 Three components of the gravity center (x,y,z)
1490 :meth:`Mesh.BaryCenter`
1492 if isinstance(obj, Mesh): obj = obj.mesh
1493 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1494 aMeasurements = self.CreateMeasurements()
1495 pointStruct = aMeasurements.GravityCenter(obj)
1496 aMeasurements.UnRegister()
1497 return pointStruct.x, pointStruct.y, pointStruct.z
1499 def GetAngle(self, p1, p2, p3 ):
1501 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1504 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1510 if isinstance( p1, list ): p1 = PointStruct(*p1)
1511 if isinstance( p2, list ): p2 = PointStruct(*p2)
1512 if isinstance( p3, list ): p3 = PointStruct(*p3)
1514 aMeasurements = self.CreateMeasurements()
1515 angle = aMeasurements.Angle(p1,p2,p3)
1516 aMeasurements.UnRegister()
1521 pass # end of class smeshBuilder
1524 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1525 """Registering the new proxy for SMESH.SMESH_Gen"""
1528 def New( instance=None, instanceGeom=None):
1530 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1531 interface to create or load meshes.
1536 salome.salome_init()
1537 from salome.smesh import smeshBuilder
1538 smesh = smeshBuilder.New()
1541 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1542 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1544 :class:`smeshBuilder` instance
1549 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1551 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1556 smeshInst = smeshBuilder()
1557 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1558 smeshInst.init_smesh(instanceGeom)
1562 # Public class: Mesh
1563 # ==================
1566 class Mesh(metaclass = MeshMeta):
1568 This class allows defining and managing a mesh.
1569 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1570 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1571 new nodes and elements and by changing the existing entities), to get information
1572 about a mesh and to export a mesh in different formats.
1579 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1584 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1585 sets the GUI name of this mesh to *name*.
1588 smeshpyD: an instance of smeshBuilder class
1589 geompyD: an instance of geomBuilder class
1590 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1591 name: Study name of the mesh
1594 self.smeshpyD = smeshpyD
1595 self.geompyD = geompyD
1600 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1603 # publish geom of mesh (issue 0021122)
1604 if not self.geom.GetStudyEntry():
1608 geo_name = name + " shape"
1610 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1611 geompyD.addToStudy( self.geom, geo_name )
1612 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1614 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1617 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1619 self.smeshpyD.SetName(self.mesh, name)
1621 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1624 self.geom = self.mesh.GetShapeToMesh()
1626 self.editor = self.mesh.GetMeshEditor()
1627 self.functors = [None] * SMESH.FT_Undefined._v
1629 # set self to algoCreator's
1630 for attrName in dir(self):
1631 attr = getattr( self, attrName )
1632 if isinstance( attr, algoCreator ):
1633 setattr( self, attrName, attr.copy( self ))
1640 Destructor. Clean-up resources
1643 #self.mesh.UnRegister()
1647 def SetMesh(self, theMesh):
1649 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1652 theMesh: a :class:`SMESH.SMESH_Mesh` object
1654 # do not call Register() as this prevents mesh servant deletion at closing study
1655 #if self.mesh: self.mesh.UnRegister()
1658 #self.mesh.Register()
1659 self.geom = self.mesh.GetShapeToMesh()
1663 if salome.sg.hasDesktop():
1664 so = salome.ObjectToSObject( self.geom )
1665 comp = so.GetFatherComponent()
1666 if comp.ComponentDataType() == "SHAPERSTUDY":
1667 import shaperBuilder
1668 self.geompyD = shaperBuilder.New()
1671 if not self.geompyD:
1672 self.geompyD = self.geom.GetGen()
1677 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1680 a :class:`SMESH.SMESH_Mesh` object
1685 def GetEngine(self):
1687 Return a smeshBuilder instance created this mesh
1689 return self.smeshpyD
1691 def GetGeomEngine(self):
1693 Return a geomBuilder instance
1699 Get the name of the mesh
1702 the name of the mesh as a string
1705 name = GetName(self.GetMesh())
1708 def SetName(self, name):
1710 Set a name to the mesh
1713 name: a new name of the mesh
1716 self.smeshpyD.SetName(self.GetMesh(), name)
1718 def GetSubMesh(self, geom, name):
1720 Get a sub-mesh object associated to a *geom* geometrical object.
1723 geom: a geometrical object (shape)
1724 name: a name for the sub-mesh in the Object Browser
1727 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1728 which lies on the given shape
1731 A sub-mesh is implicitly created when a sub-shape is specified at
1732 creating an algorithm, for example::
1734 algo1D = mesh.Segment(geom=Edge_1)
1736 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1737 The created sub-mesh can be retrieved from the algorithm::
1739 submesh = algo1D.GetSubMesh()
1742 AssureGeomPublished( self, geom, name )
1743 submesh = self.mesh.GetSubMesh( geom, name )
1748 Return the shape associated to the mesh
1756 def SetShape(self, geom):
1758 Associate the given shape to the mesh (entails the recreation of the mesh)
1761 geom: the shape to be meshed (GEOM_Object)
1764 self.mesh = self.smeshpyD.CreateMesh(geom)
1766 def HasShapeToMesh(self):
1768 Return ``True`` if this mesh is based on geometry
1770 return self.mesh.HasShapeToMesh()
1774 Load mesh from the study after opening the study
1778 def IsReadyToCompute(self, theSubObject):
1780 Return true if the hypotheses are defined well
1783 theSubObject: a sub-shape of a mesh shape
1789 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1791 def GetAlgoState(self, theSubObject):
1793 Return errors of hypotheses definition.
1794 The list of errors is empty if everything is OK.
1797 theSubObject: a sub-shape of a mesh shape
1803 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1805 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1807 Return a geometrical object on which the given element was built.
1808 The returned geometrical object, if not nil, is either found in the
1809 study or published by this method with the given name
1812 theElementID: the id of the mesh element
1813 theGeomName: the user-defined name of the geometrical object
1816 GEOM.GEOM_Object instance
1819 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1821 def MeshDimension(self):
1823 Return the mesh dimension depending on the dimension of the underlying shape
1824 or, if the mesh is not based on any shape, basing on deimension of elements
1827 mesh dimension as an integer value [0,3]
1830 if self.mesh.HasShapeToMesh():
1831 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1832 if len( shells ) > 0 :
1834 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1836 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1841 if self.NbVolumes() > 0: return 3
1842 if self.NbFaces() > 0: return 2
1843 if self.NbEdges() > 0: return 1
1846 def Evaluate(self, geom=0):
1848 Evaluate size of prospective mesh on a shape
1851 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1852 To know predicted number of e.g. edges, inquire it this way::
1854 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1857 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1859 geom = self.mesh.GetShapeToMesh()
1862 return self.smeshpyD.Evaluate(self.mesh, geom)
1865 def Compute(self, geom=0, discardModifs=False, refresh=False):
1867 Compute the mesh and return the status of the computation
1870 geom: geomtrical shape on which mesh data should be computed
1871 discardModifs: if True and the mesh has been edited since
1872 a last total re-compute and that may prevent successful partial re-compute,
1873 then the mesh is cleaned before Compute()
1874 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1880 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1881 geom = self.mesh.GetShapeToMesh()
1884 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1886 ok = self.smeshpyD.Compute(self.mesh, geom)
1887 except SALOME.SALOME_Exception as ex:
1888 print("Mesh computation failed, exception caught:")
1889 print(" ", ex.details.text)
1892 print("Mesh computation failed, exception caught:")
1893 traceback.print_exc()
1897 # Treat compute errors
1898 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1900 for err in computeErrors:
1901 if self.mesh.HasShapeToMesh():
1902 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1904 stdErrors = ["OK", #COMPERR_OK
1905 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1906 "std::exception", #COMPERR_STD_EXCEPTION
1907 "OCC exception", #COMPERR_OCC_EXCEPTION
1908 "..", #COMPERR_SLM_EXCEPTION
1909 "Unknown exception", #COMPERR_EXCEPTION
1910 "Memory allocation problem", #COMPERR_MEMORY_PB
1911 "Algorithm failed", #COMPERR_ALGO_FAILED
1912 "Unexpected geometry", #COMPERR_BAD_SHAPE
1913 "Warning", #COMPERR_WARNING
1914 "Computation cancelled",#COMPERR_CANCELED
1915 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1917 if err.code < len(stdErrors): errText = stdErrors[err.code]
1919 errText = "code %s" % -err.code
1920 if errText: errText += ". "
1921 errText += err.comment
1922 if allReasons: allReasons += "\n"
1924 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1926 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1930 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1932 if err.isGlobalAlgo:
1940 reason = '%s %sD algorithm is missing' % (glob, dim)
1941 elif err.state == HYP_MISSING:
1942 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1943 % (glob, dim, name, dim))
1944 elif err.state == HYP_NOTCONFORM:
1945 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1946 elif err.state == HYP_BAD_PARAMETER:
1947 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1948 % ( glob, dim, name ))
1949 elif err.state == HYP_BAD_GEOMETRY:
1950 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1951 'geometry' % ( glob, dim, name ))
1952 elif err.state == HYP_HIDDEN_ALGO:
1953 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1954 'algorithm of upper dimension generating %sD mesh'
1955 % ( glob, dim, name, glob, dim ))
1957 reason = ("For unknown reason. "
1958 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1960 if allReasons: allReasons += "\n"
1961 allReasons += "- " + reason
1963 if not ok or allReasons != "":
1964 msg = '"' + GetName(self.mesh) + '"'
1965 if ok: msg += " has been computed with warnings"
1966 else: msg += " has not been computed"
1967 if allReasons != "": msg += ":"
1973 if salome.sg.hasDesktop():
1974 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1975 if refresh: salome.sg.updateObjBrowser()
1979 def GetComputeErrors(self, shape=0 ):
1981 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1985 shape = self.mesh.GetShapeToMesh()
1986 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1988 def GetSubShapeName(self, subShapeID ):
1990 Return a name of a sub-shape by its ID.
1991 Possible variants (for *subShapeID* == 3):
1993 - **"Face_12"** - published sub-shape
1994 - **FACE #3** - not published sub-shape
1995 - **sub-shape #3** - invalid sub-shape ID
1996 - **#3** - error in this function
1999 subShapeID: a unique ID of a sub-shape
2002 a string describing the sub-shape
2006 if not self.mesh.HasShapeToMesh():
2010 mainIOR = salome.orb.object_to_string( self.GetShape() )
2012 mainSO = s.FindObjectIOR(mainIOR)
2015 shapeText = '"%s"' % mainSO.GetName()
2016 subIt = s.NewChildIterator(mainSO)
2018 subSO = subIt.Value()
2020 obj = subSO.GetObject()
2021 if not obj: continue
2022 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2025 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2028 if ids == subShapeID:
2029 shapeText = '"%s"' % subSO.GetName()
2032 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2034 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2036 shapeText = 'sub-shape #%s' % (subShapeID)
2038 shapeText = "#%s" % (subShapeID)
2041 def GetFailedShapes(self, publish=False):
2043 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2044 error of an algorithm
2047 publish: if *True*, the returned groups will be published in the study
2050 a list of GEOM groups each named after a failed algorithm
2055 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2056 for err in computeErrors:
2057 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2058 if not shape: continue
2059 if err.algoName in algo2shapes:
2060 algo2shapes[ err.algoName ].append( shape )
2062 algo2shapes[ err.algoName ] = [ shape ]
2066 for algoName, shapes in list(algo2shapes.items()):
2068 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2069 otherTypeShapes = []
2071 group = self.geompyD.CreateGroup( self.geom, groupType )
2072 for shape in shapes:
2073 if shape.GetShapeType() == shapes[0].GetShapeType():
2074 sameTypeShapes.append( shape )
2076 otherTypeShapes.append( shape )
2077 self.geompyD.UnionList( group, sameTypeShapes )
2079 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2081 group.SetName( algoName )
2082 groups.append( group )
2083 shapes = otherTypeShapes
2086 for group in groups:
2087 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2090 def GetMeshOrder(self):
2092 Return sub-mesh objects list in meshing order
2095 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2098 return self.mesh.GetMeshOrder()
2100 def SetMeshOrder(self, submeshes):
2102 Set priority of sub-meshes. It works in two ways:
2104 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2105 *several dimensions*, it sets the order in which the sub-meshes are computed.
2106 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2107 when looking for meshing parameters to apply to a sub-shape. To impose the
2108 order in which sub-meshes with uni-dimensional algorithms are computed,
2109 call **submesh.Compute()** in a desired order.
2112 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2114 Warning: the method is for setting the order for all sub-meshes at once:
2115 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2118 return self.mesh.SetMeshOrder(submeshes)
2120 def Clear(self, refresh=False):
2122 Remove all nodes and elements generated on geometry. Imported elements remain.
2125 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2129 if ( salome.sg.hasDesktop() ):
2130 if refresh: salome.sg.updateObjBrowser()
2132 def ClearSubMesh(self, geomId, refresh=False):
2134 Remove all nodes and elements of indicated shape
2137 geomId: the ID of a sub-shape to remove elements on
2138 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2141 self.mesh.ClearSubMesh(geomId)
2142 if salome.sg.hasDesktop():
2143 if refresh: salome.sg.updateObjBrowser()
2145 def AutomaticTetrahedralization(self, fineness=0):
2147 Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron
2150 fineness: [0.0,1.0] defines mesh fineness
2156 dim = self.MeshDimension()
2158 self.RemoveGlobalHypotheses()
2159 self.Segment().AutomaticLength(fineness)
2161 self.Triangle().LengthFromEdges()
2166 return self.Compute()
2168 def AutomaticHexahedralization(self, fineness=0):
2170 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2173 fineness: [0.0, 1.0] defines mesh fineness
2179 dim = self.MeshDimension()
2180 # assign the hypotheses
2181 self.RemoveGlobalHypotheses()
2182 self.Segment().AutomaticLength(fineness)
2189 return self.Compute()
2191 def AddHypothesis(self, hyp, geom=0):
2196 hyp: a hypothesis to assign
2197 geom: a subhape of mesh geometry
2200 :class:`SMESH.Hypothesis_Status`
2203 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2204 hyp, geom = geom, hyp
2205 if isinstance( hyp, Mesh_Algorithm ):
2206 hyp = hyp.GetAlgorithm()
2211 geom = self.mesh.GetShapeToMesh()
2214 if self.mesh.HasShapeToMesh():
2215 hyp_type = hyp.GetName()
2216 lib_name = hyp.GetLibName()
2217 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2218 # if checkAll and geom:
2219 # checkAll = geom.GetType() == 37
2221 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2223 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2224 status = self.mesh.AddHypothesis(geom, hyp)
2226 status = HYP_BAD_GEOMETRY, ""
2227 hyp_name = GetName( hyp )
2230 geom_name = geom.GetName()
2231 isAlgo = hyp._narrow( SMESH_Algo )
2232 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2235 def IsUsedHypothesis(self, hyp, geom):
2237 Return True if an algorithm or hypothesis is assigned to a given shape
2240 hyp: an algorithm or hypothesis to check
2241 geom: a subhape of mesh geometry
2247 if not hyp: # or not geom
2249 if isinstance( hyp, Mesh_Algorithm ):
2250 hyp = hyp.GetAlgorithm()
2252 hyps = self.GetHypothesisList(geom)
2254 if h.GetId() == hyp.GetId():
2258 def RemoveHypothesis(self, hyp, geom=0):
2260 Unassign a hypothesis
2263 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2264 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2267 :class:`SMESH.Hypothesis_Status`
2272 if isinstance( hyp, Mesh_Algorithm ):
2273 hyp = hyp.GetAlgorithm()
2279 if self.IsUsedHypothesis( hyp, shape ):
2280 return self.mesh.RemoveHypothesis( shape, hyp )
2281 hypName = GetName( hyp )
2282 geoName = GetName( shape )
2283 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2286 def GetHypothesisList(self, geom):
2288 Get the list of hypotheses added on a geometry
2291 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2294 the sequence of :class:`SMESH.SMESH_Hypothesis`
2297 return self.mesh.GetHypothesisList( geom )
2299 def RemoveGlobalHypotheses(self):
2301 Remove all global hypotheses
2304 current_hyps = self.mesh.GetHypothesisList( self.geom )
2305 for hyp in current_hyps:
2306 self.mesh.RemoveHypothesis( self.geom, hyp )
2310 def ExportMEDCoupling(self, *args, **kwargs):
2312 Export the mesh in a memory representation.
2315 auto_groups (boolean): parameter for creating/not creating
2316 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2317 the typical use is auto_groups=False.
2318 overwrite (boolean): parameter for overwriting/not overwriting the file
2319 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2320 to export instead of the mesh
2321 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2323 - 1D if all mesh nodes lie on OX coordinate axis, or
2324 - 2D if all mesh nodes lie on XOY coordinate plane, or
2325 - 3D in the rest cases.
2327 If *autoDimension* is *False*, the space dimension is always 3.
2328 fields: list of GEOM fields defined on the shape to mesh.
2329 geomAssocFields: each character of this string means a need to export a
2330 corresponding field; correspondence between fields and characters
2333 - 'v' stands for "_vertices_" field;
2334 - 'e' stands for "_edges_" field;
2335 - 'f' stands for "_faces_" field;
2336 - 's' stands for "_solids_" field.
2338 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2339 close to zero within a given tolerance, the coordinate is set to zero.
2340 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2341 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2343 auto_groups = args[0] if len(args) > 0 else False
2344 meshPart = args[1] if len(args) > 1 else None
2345 autoDimension = args[2] if len(args) > 2 else True
2346 fields = args[3] if len(args) > 3 else []
2347 geomAssocFields = args[4] if len(args) > 4 else ''
2348 z_tolerance = args[5] if len(args) > 5 else -1.
2349 saveNumbers = args[6] if len(args) > 6 else True
2350 # process keywords arguments
2351 auto_groups = kwargs.get("auto_groups", auto_groups)
2352 meshPart = kwargs.get("meshPart", meshPart)
2353 autoDimension = kwargs.get("autoDimension", autoDimension)
2354 fields = kwargs.get("fields", fields)
2355 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2356 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2357 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2359 # invoke engine's function
2360 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2361 unRegister = genObjUnRegister()
2362 if isinstance( meshPart, list ):
2363 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2364 unRegister.set( meshPart )
2366 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2367 self.mesh.SetParameters(Parameters)
2369 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2370 fields, geomAssocFields, z_tolerance,
2373 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2374 return medcoupling.MEDFileData.New(dab)
2376 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2378 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2379 return medcoupling.MEDFileMesh.New(dab)
2381 def ExportMED(self, *args, **kwargs):
2383 Export the mesh in a file in MED format
2384 allowing to overwrite the file if it exists or add the exported data to its contents
2387 fileName: is the file name
2388 auto_groups (boolean): parameter for creating/not creating
2389 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2390 the typical use is auto_groups=False.
2391 version (int): define the version (xy, where version is x.y.z) of MED file format.
2392 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2393 The rules of compatibility to write a mesh in an older version than
2394 the current version depend on the current version. For instance,
2395 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2396 or 3.2.1 or 3.3.1 formats.
2397 If the version is equal to -1, the version is not changed (default).
2398 overwrite (boolean): parameter for overwriting/not overwriting the file
2399 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2400 to export instead of the mesh
2401 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2403 - 1D if all mesh nodes lie on OX coordinate axis, or
2404 - 2D if all mesh nodes lie on XOY coordinate plane, or
2405 - 3D in the rest cases.
2407 If *autoDimension* is *False*, the space dimension is always 3.
2408 fields: list of GEOM fields defined on the shape to mesh.
2409 geomAssocFields: each character of this string means a need to export a
2410 corresponding field; correspondence between fields and characters
2413 - 'v' stands for "_vertices_" field;
2414 - 'e' stands for "_edges_" field;
2415 - 'f' stands for "_faces_" field;
2416 - 's' stands for "_solids_" field.
2418 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2419 close to zero within a given tolerance, the coordinate is set to zero.
2420 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2421 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2423 # process positional arguments
2424 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2426 auto_groups = args[1] if len(args) > 1 else False
2427 version = args[2] if len(args) > 2 else -1
2428 overwrite = args[3] if len(args) > 3 else True
2429 meshPart = args[4] if len(args) > 4 else None
2430 autoDimension = args[5] if len(args) > 5 else True
2431 fields = args[6] if len(args) > 6 else []
2432 geomAssocFields = args[7] if len(args) > 7 else ''
2433 z_tolerance = args[8] if len(args) > 8 else -1.
2434 saveNumbers = args[9] if len(args) > 9 else True
2435 # process keywords arguments
2436 auto_groups = kwargs.get("auto_groups", auto_groups)
2437 version = kwargs.get("version", version)
2438 version = kwargs.get("minor", version)
2439 overwrite = kwargs.get("overwrite", overwrite)
2440 meshPart = kwargs.get("meshPart", meshPart)
2441 autoDimension = kwargs.get("autoDimension", autoDimension)
2442 fields = kwargs.get("fields", fields)
2443 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2444 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2445 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2447 if isinstance( meshPart, Mesh):
2448 meshPart = meshPart.GetMesh()
2450 # invoke engine's function
2451 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2452 unRegister = genObjUnRegister()
2453 if isinstance( meshPart, list ):
2454 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2455 unRegister.set( meshPart )
2457 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2458 self.mesh.SetParameters(Parameters)
2460 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2461 version, overwrite, autoDimension,
2462 fields, geomAssocFields, z_tolerance, saveNumbers )
2464 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2466 def ExportDAT(self, f, meshPart=None, renumber=True):
2468 Export the mesh in a file in DAT format
2472 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2473 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2476 if meshPart or not renumber:
2477 unRegister = genObjUnRegister()
2478 if isinstance( meshPart, list ):
2479 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2480 unRegister.set( meshPart )
2481 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2483 self.mesh.ExportDAT( f, renumber )
2485 def ExportUNV(self, f, meshPart=None, renumber=True):
2487 Export the mesh in a file in UNV format
2491 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2492 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2495 if meshPart or not renumber:
2496 unRegister = genObjUnRegister()
2497 if isinstance( meshPart, list ):
2498 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2499 unRegister.set( meshPart )
2500 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2502 self.mesh.ExportUNV( f, renumber )
2504 def ExportSTL(self, f, ascii=1, meshPart=None):
2506 Export the mesh in a file in STL format
2510 ascii: defines the file encoding
2511 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2515 unRegister = genObjUnRegister()
2516 if isinstance( meshPart, list ):
2517 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2518 unRegister.set( meshPart )
2519 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2521 self.mesh.ExportSTL(f, ascii)
2523 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2525 Export the mesh in a file in CGNS format
2529 overwrite: boolean parameter for overwriting/not overwriting the file
2530 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2531 groupElemsByType: if True all elements of same entity type are exported at ones,
2532 else elements are exported in order of their IDs which can cause creation
2533 of multiple cgns sections
2536 unRegister = genObjUnRegister()
2537 if isinstance( meshPart, list ):
2538 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2539 unRegister.set( meshPart )
2540 if isinstance( meshPart, Mesh ):
2541 meshPart = meshPart.mesh
2543 meshPart = self.mesh
2544 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2546 def ExportGMF(self, f, meshPart=None):
2548 Export the mesh in a file in GMF format.
2549 GMF files must have .mesh extension for the ASCII format and .meshb for
2550 the bynary format. Other extensions are not allowed.
2554 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2557 unRegister = genObjUnRegister()
2558 if isinstance( meshPart, list ):
2559 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2560 unRegister.set( meshPart )
2561 if isinstance( meshPart, Mesh ):
2562 meshPart = meshPart.mesh
2564 meshPart = self.mesh
2565 self.mesh.ExportGMF(meshPart, f, True)
2567 def ExportToMED(self, *args, **kwargs):
2569 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2570 Export the mesh in a file in MED format
2571 allowing to overwrite the file if it exists or add the exported data to its contents
2574 fileName: the file name
2575 opt (boolean): parameter for creating/not creating
2576 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2577 overwrite: boolean parameter for overwriting/not overwriting the file
2578 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2580 - 1D if all mesh nodes lie on OX coordinate axis, or
2581 - 2D if all mesh nodes lie on XOY coordinate plane, or
2582 - 3D in the rest cases.
2584 If **autoDimension** is *False*, the space dimension is always 3.
2587 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2588 # process positional arguments
2589 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2591 auto_groups = args[1] if len(args) > 1 else False
2592 overwrite = args[2] if len(args) > 2 else True
2593 autoDimension = args[3] if len(args) > 3 else True
2594 # process keywords arguments
2595 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2596 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2597 overwrite = kwargs.get("overwrite", overwrite)
2598 autoDimension = kwargs.get("autoDimension", autoDimension)
2600 # invoke engine's function
2601 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2603 def ExportToMEDX(self, *args, **kwargs):
2605 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2606 Export the mesh in a file in MED format
2609 fileName: the file name
2610 opt (boolean): parameter for creating/not creating
2611 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2612 overwrite: boolean parameter for overwriting/not overwriting the file
2613 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2615 - 1D if all mesh nodes lie on OX coordinate axis, or
2616 - 2D if all mesh nodes lie on XOY coordinate plane, or
2617 - 3D in the rest cases.
2619 If **autoDimension** is *False*, the space dimension is always 3.
2622 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2623 # process positional arguments
2624 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2626 auto_groups = args[1] if len(args) > 1 else False
2627 overwrite = args[2] if len(args) > 2 else True
2628 autoDimension = args[3] if len(args) > 3 else True
2629 # process keywords arguments
2630 auto_groups = kwargs.get("auto_groups", auto_groups)
2631 overwrite = kwargs.get("overwrite", overwrite)
2632 autoDimension = kwargs.get("autoDimension", autoDimension)
2634 # invoke engine's function
2635 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2639 def Append(self, meshes, uniteIdenticalGroups = True,
2640 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2642 Append given meshes into this mesh.
2643 All groups of input meshes will be created in this mesh.
2646 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2647 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2648 mergeNodesAndElements: if True, equal nodes and elements are merged
2649 mergeTolerance: tolerance for merging nodes
2650 allGroups: forces creation of groups corresponding to every input mesh
2652 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2653 mergeNodesAndElements, mergeTolerance, allGroups,
2654 meshToAppendTo = self.GetMesh() )
2656 # Operations with groups:
2657 # ----------------------
2658 def CreateEmptyGroup(self, elementType, name):
2660 Create an empty standalone mesh group
2663 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2664 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2665 name: the name of the mesh group
2668 :class:`SMESH.SMESH_Group`
2671 return self.mesh.CreateGroup(elementType, name)
2673 def Group(self, grp, name=""):
2675 Create a mesh group based on the geometric object *grp*
2676 and give it a *name*.
2677 If *name* is not defined the name of the geometric group is used
2680 Works like :meth:`GroupOnGeom`.
2683 grp: a geometric group, a vertex, an edge, a face or a solid
2684 name: the name of the mesh group
2687 :class:`SMESH.SMESH_GroupOnGeom`
2690 return self.GroupOnGeom(grp, name)
2692 def GroupOnGeom(self, grp, name="", typ=None):
2694 Create a mesh group based on the geometrical object *grp*
2695 and give it a *name*.
2696 if *name* is not defined the name of the geometric group is used
2699 grp: a geometrical group, a vertex, an edge, a face or a solid
2700 name: the name of the mesh group
2701 typ: the type of elements in the group; either of
2702 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2703 automatically detected by the type of the geometry
2706 :class:`SMESH.SMESH_GroupOnGeom`
2709 AssureGeomPublished( self, grp, name )
2711 name = grp.GetName()
2713 typ = self._groupTypeFromShape( grp )
2714 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2716 def _groupTypeFromShape( self, shape ):
2718 Pivate method to get a type of group on geometry
2720 tgeo = str(shape.GetShapeType())
2721 if tgeo == "VERTEX":
2723 elif tgeo == "EDGE" or tgeo == "WIRE":
2725 elif tgeo == "FACE" or tgeo == "SHELL":
2727 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2729 elif tgeo == "COMPOUND":
2731 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2733 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2734 # simplification of access in geomBuilder: omniORB.registerObjref
2735 from SHAPERSTUDY_utils import getEngine
2738 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2740 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2741 return self._groupTypeFromShape( sub[0] )
2743 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2746 def GroupOnFilter(self, typ, name, filter):
2748 Create a mesh group with given *name* based on the *filter*.
2749 It is a special type of group dynamically updating it's contents during
2753 typ: the type of elements in the group; either of
2754 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2755 name: the name of the mesh group
2756 filter (SMESH.Filter): the filter defining group contents
2759 :class:`SMESH.SMESH_GroupOnFilter`
2762 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2764 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2766 Create a mesh group by the given ids of elements
2769 groupName: the name of the mesh group
2770 elementType: the type of elements in the group; either of
2771 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2772 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2775 :class:`SMESH.SMESH_Group`
2778 group = self.mesh.CreateGroup(elementType, groupName)
2779 if isinstance( elemIDs, Mesh ):
2780 elemIDs = elemIDs.GetMesh()
2781 if hasattr( elemIDs, "GetIDs" ):
2782 if hasattr( elemIDs, "SetMesh" ):
2783 elemIDs.SetMesh( self.GetMesh() )
2784 group.AddFrom( elemIDs )
2792 CritType=FT_Undefined,
2795 UnaryOp=FT_Undefined,
2798 Create a mesh group by the given conditions
2801 groupName: the name of the mesh group
2802 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2803 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2804 Note that the items starting from FT_LessThan are not suitable for CritType.
2805 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2806 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2807 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2808 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2809 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2812 :class:`SMESH.SMESH_GroupOnFilter`
2815 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2816 group = self.MakeGroupByCriterion(groupName, aCriterion)
2819 def MakeGroupByCriterion(self, groupName, Criterion):
2821 Create a mesh group by the given criterion
2824 groupName: the name of the mesh group
2825 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2828 :class:`SMESH.SMESH_GroupOnFilter`
2831 :meth:`smeshBuilder.GetCriterion`
2834 return self.MakeGroupByCriteria( groupName, [Criterion] )
2836 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2838 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2841 groupName: the name of the mesh group
2842 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2843 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2846 :class:`SMESH.SMESH_GroupOnFilter`
2849 :meth:`smeshBuilder.GetCriterion`
2852 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2853 group = self.MakeGroupByFilter(groupName, aFilter)
2856 def MakeGroupByFilter(self, groupName, theFilter):
2858 Create a mesh group by the given filter
2861 groupName (string): the name of the mesh group
2862 theFilter (SMESH.Filter): the filter
2865 :class:`SMESH.SMESH_GroupOnFilter`
2868 :meth:`smeshBuilder.GetFilter`
2871 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2872 #theFilter.SetMesh( self.mesh )
2873 #group.AddFrom( theFilter )
2874 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2877 def RemoveGroup(self, group):
2882 group (SMESH.SMESH_GroupBase): group to remove
2885 self.mesh.RemoveGroup(group)
2887 def RemoveGroupWithContents(self, group):
2889 Remove a group with its contents
2892 group (SMESH.SMESH_GroupBase): group to remove
2895 This operation can create gaps in numeration of nodes or elements.
2896 Call :meth:`RenumberElements` to remove the gaps.
2899 self.mesh.RemoveGroupWithContents(group)
2901 def GetGroups(self, elemType = SMESH.ALL):
2903 Get the list of groups existing in the mesh in the order of creation
2904 (starting from the oldest one)
2907 elemType (SMESH.ElementType): type of elements the groups contain;
2908 by default groups of elements of all types are returned
2911 a list of :class:`SMESH.SMESH_GroupBase`
2914 groups = self.mesh.GetGroups()
2915 if elemType == SMESH.ALL:
2919 if g.GetType() == elemType:
2920 typedGroups.append( g )
2927 Get the number of groups existing in the mesh
2930 the quantity of groups as an integer value
2933 return self.mesh.NbGroups()
2935 def GetGroupNames(self):
2937 Get the list of names of groups existing in the mesh
2943 groups = self.GetGroups()
2945 for group in groups:
2946 names.append(group.GetName())
2949 def GetGroupByName(self, name, elemType = None):
2951 Find groups by name and type
2954 name (string): name of the group of interest
2955 elemType (SMESH.ElementType): type of elements the groups contain;
2956 by default one group of any type is returned;
2957 if elemType == SMESH.ALL then all groups of any type are returned
2960 a list of :class:`SMESH.SMESH_GroupBase`
2964 for group in self.GetGroups():
2965 if group.GetName() == name:
2966 if elemType is None:
2968 if ( elemType == SMESH.ALL or
2969 group.GetType() == elemType ):
2970 groups.append( group )
2973 def UnionGroups(self, group1, group2, name):
2975 Produce a union of two groups.
2976 A new group is created. All mesh elements that are
2977 present in the initial groups are added to the new one
2980 group1 (SMESH.SMESH_GroupBase): a group
2981 group2 (SMESH.SMESH_GroupBase): another group
2984 instance of :class:`SMESH.SMESH_Group`
2987 return self.mesh.UnionGroups(group1, group2, name)
2989 def UnionListOfGroups(self, groups, name):
2991 Produce a union list of groups.
2992 New group is created. All mesh elements that are present in
2993 initial groups are added to the new one
2996 groups: list of :class:`SMESH.SMESH_GroupBase`
2999 instance of :class:`SMESH.SMESH_Group`
3001 return self.mesh.UnionListOfGroups(groups, name)
3003 def IntersectGroups(self, group1, group2, name):
3005 Prodice an intersection of two groups.
3006 A new group is created. All mesh elements that are common
3007 for the two initial groups are added to the new one.
3010 group1 (SMESH.SMESH_GroupBase): a group
3011 group2 (SMESH.SMESH_GroupBase): another group
3014 instance of :class:`SMESH.SMESH_Group`
3017 return self.mesh.IntersectGroups(group1, group2, name)
3019 def IntersectListOfGroups(self, groups, name):
3021 Produce an intersection of groups.
3022 New group is created. All mesh elements that are present in all
3023 initial groups simultaneously are added to the new one
3026 groups: a list of :class:`SMESH.SMESH_GroupBase`
3029 instance of :class:`SMESH.SMESH_Group`
3031 return self.mesh.IntersectListOfGroups(groups, name)
3033 def CutGroups(self, main_group, tool_group, name):
3035 Produce a cut of two groups.
3036 A new group is created. All mesh elements that are present in
3037 the main group but are not present in the tool group are added to the new one
3040 main_group (SMESH.SMESH_GroupBase): a group to cut from
3041 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3044 an instance of :class:`SMESH.SMESH_Group`
3047 return self.mesh.CutGroups(main_group, tool_group, name)
3049 def CutListOfGroups(self, main_groups, tool_groups, name):
3051 Produce a cut of groups.
3052 A new group is created. All mesh elements that are present in main groups
3053 but do not present in tool groups are added to the new one
3056 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3057 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3060 an instance of :class:`SMESH.SMESH_Group`
3063 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3065 def CreateDimGroup(self, groups, elemType, name,
3066 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3068 Create a standalone group of entities basing on nodes of other groups.
3071 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3072 elemType: a type of elements to include to the new group; either of
3073 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3074 name: a name of the new group.
3075 nbCommonNodes: a criterion of inclusion of an element to the new group
3076 basing on number of element nodes common with reference *groups*.
3077 Meaning of possible values are:
3079 - SMESH.ALL_NODES - include if all nodes are common,
3080 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3081 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3082 - SMEHS.MAJORITY - include if half of nodes or more are common.
3083 underlyingOnly: if *True* (default), an element is included to the
3084 new group provided that it is based on nodes of an element of *groups*;
3085 in this case the reference *groups* are supposed to be of higher dimension
3086 than *elemType*, which can be useful for example to get all faces lying on
3087 volumes of the reference *groups*.
3090 an instance of :class:`SMESH.SMESH_Group`
3093 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3095 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3097 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3099 Distribute all faces of the mesh among groups using sharp edges and optionally
3100 existing 1D elements as group boundaries.
3103 sharpAngle: edge is considered sharp if an angle between normals of
3104 adjacent faces is more than \a sharpAngle in degrees.
3105 createEdges (boolean): to create 1D elements for detected sharp edges.
3106 useExistingEdges (boolean): to use existing edges as group boundaries
3108 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3110 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3111 self.mesh.SetParameters(Parameters)
3112 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3114 def ConvertToStandalone(self, group):
3116 Convert group on geom into standalone group
3119 return self.mesh.ConvertToStandalone(group)
3121 # Get some info about mesh:
3122 # ------------------------
3124 def GetLog(self, clearAfterGet):
3126 Return the log of nodes and elements added or removed
3127 since the previous clear of the log.
3130 clearAfterGet: log is emptied after Get (safe if concurrents access)
3133 list of SMESH.log_block structures { commandType, number, coords, indexes }
3136 return self.mesh.GetLog(clearAfterGet)
3140 Clear the log of nodes and elements added or removed since the previous
3141 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3144 self.mesh.ClearLog()
3146 def SetAutoColor(self, theAutoColor):
3148 Toggle auto color mode on the object.
3149 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3152 theAutoColor (boolean): the flag which toggles auto color mode.
3155 self.mesh.SetAutoColor(theAutoColor)
3157 def GetAutoColor(self):
3159 Get flag of object auto color mode.
3165 return self.mesh.GetAutoColor()
3172 integer value, which is the internal Id of the mesh
3175 return self.mesh.GetId()
3177 def HasDuplicatedGroupNamesMED(self):
3179 Check the group names for duplications.
3180 Consider the maximum group name length stored in MED file.
3186 return self.mesh.HasDuplicatedGroupNamesMED()
3188 def GetMeshEditor(self):
3190 Obtain the mesh editor tool
3193 an instance of :class:`SMESH.SMESH_MeshEditor`
3198 def GetIDSource(self, ids, elemType = SMESH.ALL):
3200 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3201 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3205 elemType: type of elements; this parameter is used to distinguish
3206 IDs of nodes from IDs of elements; by default ids are treated as
3207 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3210 an instance of :class:`SMESH.SMESH_IDSource`
3213 call UnRegister() for the returned object as soon as it is no more useful::
3215 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3216 mesh.DoSomething( idSrc )
3220 if isinstance( ids, int ):
3222 return self.editor.MakeIDSource(ids, elemType)
3225 # Get information about mesh contents:
3226 # ------------------------------------
3228 def GetMeshInfo(self, obj = None):
3230 Get the mesh statistic.
3233 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3236 if not obj: obj = self.mesh
3237 return self.smeshpyD.GetMeshInfo(obj)
3241 Return the number of nodes in the mesh
3247 return self.mesh.NbNodes()
3249 def NbElements(self):
3251 Return the number of elements in the mesh
3257 return self.mesh.NbElements()
3259 def Nb0DElements(self):
3261 Return the number of 0d elements in the mesh
3267 return self.mesh.Nb0DElements()
3271 Return the number of ball discrete elements in the mesh
3277 return self.mesh.NbBalls()
3281 Return the number of edges in the mesh
3287 return self.mesh.NbEdges()
3289 def NbEdgesOfOrder(self, elementOrder):
3291 Return the number of edges with the given order in the mesh
3294 elementOrder: the order of elements
3295 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3301 return self.mesh.NbEdgesOfOrder(elementOrder)
3305 Return the number of faces in the mesh
3311 return self.mesh.NbFaces()
3313 def NbFacesOfOrder(self, elementOrder):
3315 Return the number of faces with the given order in the mesh
3318 elementOrder: the order of elements
3319 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3325 return self.mesh.NbFacesOfOrder(elementOrder)
3327 def NbTriangles(self):
3329 Return the number of triangles in the mesh
3335 return self.mesh.NbTriangles()
3337 def NbTrianglesOfOrder(self, elementOrder):
3339 Return the number of triangles with the given order in the mesh
3342 elementOrder: is the order of elements
3343 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3349 return self.mesh.NbTrianglesOfOrder(elementOrder)
3351 def NbBiQuadTriangles(self):
3353 Return the number of biquadratic triangles in the mesh
3359 return self.mesh.NbBiQuadTriangles()
3361 def NbQuadrangles(self):
3363 Return the number of quadrangles in the mesh
3369 return self.mesh.NbQuadrangles()
3371 def NbQuadranglesOfOrder(self, elementOrder):
3373 Return the number of quadrangles with the given order in the mesh
3376 elementOrder: the order of elements
3377 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3383 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3385 def NbBiQuadQuadrangles(self):
3387 Return the number of biquadratic quadrangles in the mesh
3393 return self.mesh.NbBiQuadQuadrangles()
3395 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3397 Return the number of polygons of given order in the mesh
3400 elementOrder: the order of elements
3401 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3407 return self.mesh.NbPolygonsOfOrder(elementOrder)
3409 def NbVolumes(self):
3411 Return the number of volumes in the mesh
3417 return self.mesh.NbVolumes()
3420 def NbVolumesOfOrder(self, elementOrder):
3422 Return the number of volumes with the given order in the mesh
3425 elementOrder: the order of elements
3426 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3432 return self.mesh.NbVolumesOfOrder(elementOrder)
3436 Return the number of tetrahedrons in the mesh
3442 return self.mesh.NbTetras()
3444 def NbTetrasOfOrder(self, elementOrder):
3446 Return the number of tetrahedrons with the given order in the mesh
3449 elementOrder: the order of elements
3450 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3456 return self.mesh.NbTetrasOfOrder(elementOrder)
3460 Return the number of hexahedrons in the mesh
3466 return self.mesh.NbHexas()
3468 def NbHexasOfOrder(self, elementOrder):
3470 Return the number of hexahedrons with the given order in the mesh
3473 elementOrder: the order of elements
3474 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3480 return self.mesh.NbHexasOfOrder(elementOrder)
3482 def NbTriQuadraticHexas(self):
3484 Return the number of triquadratic hexahedrons in the mesh
3490 return self.mesh.NbTriQuadraticHexas()
3492 def NbPyramids(self):
3494 Return the number of pyramids in the mesh
3500 return self.mesh.NbPyramids()
3502 def NbPyramidsOfOrder(self, elementOrder):
3504 Return the number of pyramids with the given order in the mesh
3507 elementOrder: the order of elements
3508 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3514 return self.mesh.NbPyramidsOfOrder(elementOrder)
3518 Return the number of prisms in the mesh
3524 return self.mesh.NbPrisms()
3526 def NbPrismsOfOrder(self, elementOrder):
3528 Return the number of prisms with the given order in the mesh
3531 elementOrder: the order of elements
3532 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3538 return self.mesh.NbPrismsOfOrder(elementOrder)
3540 def NbHexagonalPrisms(self):
3542 Return the number of hexagonal prisms in the mesh
3548 return self.mesh.NbHexagonalPrisms()
3550 def NbPolyhedrons(self):
3552 Return the number of polyhedrons in the mesh
3558 return self.mesh.NbPolyhedrons()
3560 def NbSubMesh(self):
3562 Return the number of submeshes in the mesh
3568 return self.mesh.NbSubMesh()
3570 def GetElementsId(self):
3572 Return the list of all mesh elements IDs
3575 the list of integer values
3578 :meth:`GetElementsByType`
3581 return self.mesh.GetElementsId()
3583 def GetElementsByType(self, elementType):
3585 Return the list of IDs of mesh elements with the given type
3588 elementType (SMESH.ElementType): the required type of elements
3591 list of integer values
3594 return self.mesh.GetElementsByType(elementType)
3596 def GetNodesId(self):
3598 Return the list of mesh nodes IDs
3601 the list of integer values
3604 return self.mesh.GetNodesId()
3606 # Get the information about mesh elements:
3607 # ------------------------------------
3609 def GetElementType(self, id, iselem=True):
3611 Return the type of mesh element or node
3614 the value from :class:`SMESH.ElementType` enumeration.
3615 Return SMESH.ALL if element or node with the given ID does not exist
3618 return self.mesh.GetElementType(id, iselem)
3620 def GetElementGeomType(self, id):
3622 Return the geometric type of mesh element
3625 the value from :class:`SMESH.EntityType` enumeration.
3628 return self.mesh.GetElementGeomType(id)
3630 def GetElementShape(self, id):
3632 Return the shape type of mesh element
3635 the value from :class:`SMESH.GeometryType` enumeration.
3638 return self.mesh.GetElementShape(id)
3640 def GetSubMeshElementsId(self, Shape):
3642 Return the list of sub-mesh elements IDs
3645 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3646 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3649 list of integer values
3652 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3653 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3656 return self.mesh.GetSubMeshElementsId(ShapeID)
3658 def GetSubMeshNodesId(self, Shape, all):
3660 Return the list of sub-mesh nodes IDs
3663 Shape: a geom object (sub-shape).
3664 *Shape* must be the sub-shape of a :meth:`GetShape`
3665 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3668 list of integer values
3671 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3672 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3675 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3677 def GetSubMeshElementType(self, Shape):
3679 Return type of elements on given shape
3682 Shape: a geom object (sub-shape).
3683 *Shape* must be a sub-shape of a ShapeToMesh()
3686 :class:`SMESH.ElementType`
3689 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3690 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3693 return self.mesh.GetSubMeshElementType(ShapeID)
3697 Get the mesh description
3703 return self.mesh.Dump()
3706 # Get the information about nodes and elements of a mesh by its IDs:
3707 # -----------------------------------------------------------
3709 def GetNodeXYZ(self, id):
3711 Get XYZ coordinates of a node.
3712 If there is no node for the given ID - return an empty list
3715 list of float values
3718 return self.mesh.GetNodeXYZ(id)
3720 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3722 Return list of IDs of inverse elements for the given node.
3723 If there is no node for the given ID - return an empty list
3727 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3730 list of integer values
3733 return self.mesh.GetNodeInverseElements(id,elemType)
3735 def GetNodePosition(self,NodeID):
3737 Return the position of a node on the shape
3740 :class:`SMESH.NodePosition`
3743 return self.mesh.GetNodePosition(NodeID)
3745 def GetElementPosition(self,ElemID):
3747 Return the position of an element on the shape
3750 :class:`SMESH.ElementPosition`
3753 return self.mesh.GetElementPosition(ElemID)
3755 def GetShapeID(self, id):
3757 Return the ID of the shape, on which the given node was generated.
3760 an integer value > 0 or -1 if there is no node for the given
3761 ID or the node is not assigned to any geometry
3764 return self.mesh.GetShapeID(id)
3766 def GetShapeIDForElem(self,id):
3768 Return the ID of the shape, on which the given element was generated.
3771 an integer value > 0 or -1 if there is no element for the given
3772 ID or the element is not assigned to any geometry
3775 return self.mesh.GetShapeIDForElem(id)
3777 def GetElemNbNodes(self, id):
3779 Return the number of nodes of the given element
3782 an integer value > 0 or -1 if there is no element for the given ID
3785 return self.mesh.GetElemNbNodes(id)
3787 def GetElemNode(self, id, index):
3789 Return the node ID the given (zero based) index for the given element.
3791 * If there is no element for the given ID - return -1.
3792 * If there is no node for the given index - return -2.
3795 id (int): element ID
3796 index (int): node index within the element
3799 an integer value (ID)
3802 :meth:`GetElemNodes`
3805 return self.mesh.GetElemNode(id, index)
3807 def GetElemNodes(self, id):
3809 Return the IDs of nodes of the given element
3812 a list of integer values
3815 return self.mesh.GetElemNodes(id)
3817 def IsMediumNode(self, elementID, nodeID):
3819 Return true if the given node is the medium node in the given quadratic element
3822 return self.mesh.IsMediumNode(elementID, nodeID)
3824 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3826 Return true if the given node is the medium node in one of quadratic elements
3829 nodeID: ID of the node
3830 elementType: the type of elements to check a state of the node, either of
3831 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3834 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3836 def ElemNbEdges(self, id):
3838 Return the number of edges for the given element
3841 return self.mesh.ElemNbEdges(id)
3843 def ElemNbFaces(self, id):
3845 Return the number of faces for the given element
3848 return self.mesh.ElemNbFaces(id)
3850 def GetElemFaceNodes(self,elemId, faceIndex):
3852 Return nodes of given face (counted from zero) for given volumic element.
3855 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3857 def GetFaceNormal(self, faceId, normalized=False):
3859 Return three components of normal of given mesh face
3860 (or an empty array in KO case)
3863 return self.mesh.GetFaceNormal(faceId,normalized)
3865 def FindElementByNodes(self, nodes):
3867 Return an element based on all given nodes.
3870 return self.mesh.FindElementByNodes(nodes)
3872 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3874 Return elements including all given nodes.
3877 return self.mesh.GetElementsByNodes( nodes, elemType )
3879 def IsPoly(self, id):
3881 Return true if the given element is a polygon
3884 return self.mesh.IsPoly(id)
3886 def IsQuadratic(self, id):
3888 Return true if the given element is quadratic
3891 return self.mesh.IsQuadratic(id)
3893 def GetBallDiameter(self, id):
3895 Return diameter of a ball discrete element or zero in case of an invalid *id*
3898 return self.mesh.GetBallDiameter(id)
3900 def BaryCenter(self, id):
3902 Return XYZ coordinates of the barycenter of the given element.
3903 If there is no element for the given ID - return an empty list
3906 a list of three double values
3909 :meth:`smeshBuilder.GetGravityCenter`
3912 return self.mesh.BaryCenter(id)
3914 def GetIdsFromFilter(self, filter, meshParts=[] ):
3916 Pass mesh elements through the given filter and return IDs of fitting elements
3919 filter: :class:`SMESH.Filter`
3920 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3926 :meth:`SMESH.Filter.GetIDs`
3927 :meth:`SMESH.Filter.GetElementsIdFromParts`
3930 filter.SetMesh( self.mesh )
3933 if isinstance( meshParts, Mesh ):
3934 filter.SetMesh( meshParts.GetMesh() )
3935 return theFilter.GetIDs()
3936 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3937 meshParts = [ meshParts ]
3938 return filter.GetElementsIdFromParts( meshParts )
3940 return filter.GetIDs()
3942 # Get mesh measurements information:
3943 # ------------------------------------
3945 def GetFreeBorders(self):
3947 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3948 Return a list of special structures (borders).
3951 a list of :class:`SMESH.FreeEdges.Border`
3954 aFilterMgr = self.smeshpyD.CreateFilterManager()
3955 aPredicate = aFilterMgr.CreateFreeEdges()
3956 aPredicate.SetMesh(self.mesh)
3957 aBorders = aPredicate.GetBorders()
3958 aFilterMgr.UnRegister()
3961 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3963 Get minimum distance between two nodes, elements or distance to the origin
3966 id1: first node/element id
3967 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3968 isElem1: *True* if *id1* is element id, *False* if it is node id
3969 isElem2: *True* if *id2* is element id, *False* if it is node id
3972 minimum distance value
3974 :meth:`GetMinDistance`
3977 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3978 return aMeasure.value
3980 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3982 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3985 id1: first node/element id
3986 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3987 isElem1: *True* if *id1* is element id, *False* if it is node id
3988 isElem2: *True* if *id2* is element id, *False* if it is node id
3991 :class:`SMESH.Measure` structure
3997 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3999 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
4002 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
4004 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4009 aMeasurements = self.smeshpyD.CreateMeasurements()
4010 aMeasure = aMeasurements.MinDistance(id1, id2)
4011 genObjUnRegister([aMeasurements,id1, id2])
4014 def BoundingBox(self, objects=None, isElem=False):
4016 Get bounding box of the specified object(s)
4019 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4020 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4021 *False* specifies that *objects* are nodes
4024 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4027 :meth:`GetBoundingBox()`
4030 result = self.GetBoundingBox(objects, isElem)
4034 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4037 def GetBoundingBox(self, objects=None, isElem=False):
4039 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4042 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4043 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4044 False means that *objects* are nodes
4047 :class:`SMESH.Measure` structure
4050 :meth:`BoundingBox()`
4054 objects = [self.mesh]
4055 elif isinstance(objects, tuple):
4056 objects = list(objects)
4057 if not isinstance(objects, list):
4059 if len(objects) > 0 and isinstance(objects[0], int):
4062 unRegister = genObjUnRegister()
4064 if isinstance(o, Mesh):
4065 srclist.append(o.mesh)
4066 elif hasattr(o, "_narrow"):
4067 src = o._narrow(SMESH.SMESH_IDSource)
4068 if src: srclist.append(src)
4070 elif isinstance(o, list):
4072 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4074 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4075 unRegister.set( srclist[-1] )
4078 aMeasurements = self.smeshpyD.CreateMeasurements()
4079 unRegister.set( aMeasurements )
4080 aMeasure = aMeasurements.BoundingBox(srclist)
4083 # Mesh edition (SMESH_MeshEditor functionality):
4084 # ---------------------------------------------
4086 def RemoveElements(self, IDsOfElements):
4088 Remove the elements from the mesh by ids
4091 IDsOfElements: is a list of ids of elements to remove
4097 This operation can create gaps in numeration of elements.
4098 Call :meth:`RenumberElements` to remove the gaps.
4101 return self.editor.RemoveElements(IDsOfElements)
4103 def RemoveNodes(self, IDsOfNodes):
4105 Remove nodes from mesh by ids
4108 IDsOfNodes: is a list of ids of nodes to remove
4114 This operation can create gaps in numeration of nodes.
4115 Call :meth:`RenumberElements` to remove the gaps.
4118 return self.editor.RemoveNodes(IDsOfNodes)
4120 def RemoveNodeWithReconnection(self, nodeID ):
4122 Remove a node along with changing surrounding faces to cover a hole.
4125 nodeID: ID of node to remove
4128 return self.editor.RemoveNodeWithReconnection( nodeID )
4130 def RemoveOrphanNodes(self):
4132 Remove all orphan (free) nodes from mesh
4135 number of the removed nodes
4138 This operation can create gaps in numeration of nodes.
4139 Call :meth:`RenumberElements` to remove the gaps.
4142 return self.editor.RemoveOrphanNodes()
4144 def AddNode(self, x, y, z):
4146 Add a node to the mesh by coordinates
4152 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4153 if hasVars: self.mesh.SetParameters(Parameters)
4154 return self.editor.AddNode( x, y, z)
4156 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4158 Create a 0D element on a node with given number.
4161 IDOfNode: the ID of node for creation of the element.
4162 DuplicateElements: to add one more 0D element to a node or not
4165 ID of the new 0D element
4168 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4170 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4172 Create 0D elements on all nodes of the given elements except those
4173 nodes on which a 0D element already exists.
4176 theObject: an object on whose nodes 0D elements will be created.
4177 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4178 theGroupName: optional name of a group to add 0D elements created
4179 and/or found on nodes of *theObject*.
4180 DuplicateElements: to add one more 0D element to a node or not
4183 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4184 IDs of new and/or found 0D elements. IDs of 0D elements
4185 can be retrieved from the returned object by
4186 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4189 unRegister = genObjUnRegister()
4190 if isinstance( theObject, Mesh ):
4191 theObject = theObject.GetMesh()
4192 elif isinstance( theObject, list ):
4193 theObject = self.GetIDSource( theObject, SMESH.ALL )
4194 unRegister.set( theObject )
4195 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4197 def AddBall(self, IDOfNode, diameter):
4199 Create a ball element on a node with given ID.
4202 IDOfNode: the ID of node for creation of the element.
4203 diameter: the bal diameter.
4206 ID of the new ball element
4209 return self.editor.AddBall( IDOfNode, diameter )
4211 def AddEdge(self, IDsOfNodes):
4213 Create a linear or quadratic edge (this is determined
4214 by the number of given nodes).
4217 IDsOfNodes: list of node IDs for creation of the element.
4218 The order of nodes in this list should correspond to
4219 the :ref:`connectivity convention <connectivity_page>`.
4225 return self.editor.AddEdge(IDsOfNodes)
4227 def AddFace(self, IDsOfNodes):
4229 Create a linear or quadratic face (this is determined
4230 by the number of given nodes).
4233 IDsOfNodes: list of node IDs for creation of the element.
4234 The order of nodes in this list should correspond to
4235 the :ref:`connectivity convention <connectivity_page>`.
4241 return self.editor.AddFace(IDsOfNodes)
4243 def AddPolygonalFace(self, IdsOfNodes):
4245 Add a polygonal face defined by a list of node IDs
4248 IdsOfNodes: the list of node IDs for creation of the element.
4254 return self.editor.AddPolygonalFace(IdsOfNodes)
4256 def AddQuadPolygonalFace(self, IdsOfNodes):
4258 Add a quadratic polygonal face defined by a list of node IDs
4261 IdsOfNodes: the list of node IDs for creation of the element;
4262 corner nodes follow first.
4268 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4270 def AddVolume(self, IDsOfNodes):
4272 Create both simple and quadratic volume (this is determined
4273 by the number of given nodes).
4276 IDsOfNodes: list of node IDs for creation of the element.
4277 The order of nodes in this list should correspond to
4278 the :ref:`connectivity convention <connectivity_page>`.
4281 ID of the new volumic element
4284 return self.editor.AddVolume(IDsOfNodes)
4286 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4288 Create a volume of many faces, giving nodes for each face.
4291 IdsOfNodes: list of node IDs for volume creation, face by face.
4292 Quantities: list of integer values, Quantities[i]
4293 gives the quantity of nodes in face number i.
4296 ID of the new volumic element
4299 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4301 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4303 Create a volume of many faces, giving the IDs of the existing faces.
4306 The created volume will refer only to the nodes
4307 of the given faces, not to the faces themselves.
4310 IdsOfFaces: the list of face IDs for volume creation.
4313 ID of the new volumic element
4316 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4319 def SetNodeOnVertex(self, NodeID, Vertex):
4321 Bind a node to a vertex
4325 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4328 True if succeed else raises an exception
4331 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4332 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4336 self.editor.SetNodeOnVertex(NodeID, VertexID)
4337 except SALOME.SALOME_Exception as inst:
4338 raise ValueError(inst.details.text)
4342 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4344 Store the node position on an edge
4348 Edge: an edge (GEOM.GEOM_Object) or edge ID
4349 paramOnEdge: a parameter on the edge where the node is located
4352 True if succeed else raises an exception
4355 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4356 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4360 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4361 except SALOME.SALOME_Exception as inst:
4362 raise ValueError(inst.details.text)
4365 def SetNodeOnFace(self, NodeID, Face, u, v):
4367 Store node position on a face
4371 Face: a face (GEOM.GEOM_Object) or face ID
4372 u: U parameter on the face where the node is located
4373 v: V parameter on the face where the node is located
4376 True if succeed else raises an exception
4379 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4380 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4384 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4385 except SALOME.SALOME_Exception as inst:
4386 raise ValueError(inst.details.text)
4389 def SetNodeInVolume(self, NodeID, Solid):
4391 Bind a node to a solid
4395 Solid: a solid (GEOM.GEOM_Object) or solid ID
4398 True if succeed else raises an exception
4401 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4402 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4406 self.editor.SetNodeInVolume(NodeID, SolidID)
4407 except SALOME.SALOME_Exception as inst:
4408 raise ValueError(inst.details.text)
4411 def SetMeshElementOnShape(self, ElementID, Shape):
4413 Bind an element to a shape
4416 ElementID: an element ID
4417 Shape: a shape (GEOM.GEOM_Object) or shape ID
4420 True if succeed else raises an exception
4423 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4424 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4428 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4429 except SALOME.SALOME_Exception as inst:
4430 raise ValueError(inst.details.text)
4434 def MoveNode(self, NodeID, x, y, z):
4436 Move the node with the given id
4439 NodeID: the id of the node
4440 x: a new X coordinate
4441 y: a new Y coordinate
4442 z: a new Z coordinate
4445 True if succeed else False
4448 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4449 if hasVars: self.mesh.SetParameters(Parameters)
4450 return self.editor.MoveNode(NodeID, x, y, z)
4452 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4454 Find the node closest to a point and moves it to a point location
4457 x: the X coordinate of a point
4458 y: the Y coordinate of a point
4459 z: the Z coordinate of a point
4460 NodeID: if specified (>0), the node with this ID is moved,
4461 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4464 the ID of a moved node
4467 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4468 if hasVars: self.mesh.SetParameters(Parameters)
4469 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4471 def FindNodeClosestTo(self, x, y, z):
4473 Find the node closest to a point
4476 x: the X coordinate of a point
4477 y: the Y coordinate of a point
4478 z: the Z coordinate of a point
4484 return self.editor.FindNodeClosestTo(x, y, z)
4486 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4488 Find the elements where a point lays IN or ON
4491 x,y,z (float): coordinates of the point
4492 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4493 means elements of any type excluding nodes, discrete and 0D elements.
4494 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4497 list of IDs of found elements
4500 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4502 return self.editor.FindElementsByPoint(x, y, z, elementType)
4504 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4506 Project a point to a mesh object.
4507 Return ID of an element of given type where the given point is projected
4508 and coordinates of the projection point.
4509 In the case if nothing found, return -1 and []
4511 if isinstance( meshObject, Mesh ):
4512 meshObject = meshObject.GetMesh()
4514 meshObject = self.GetMesh()
4515 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4517 def GetPointState(self, x, y, z):
4519 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4520 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4521 UNKNOWN state means that either mesh is wrong or the analysis fails.
4524 return self.editor.GetPointState(x, y, z)
4526 def IsManifold(self):
4528 Check if a 2D mesh is manifold
4531 return self.editor.IsManifold()
4533 def IsCoherentOrientation2D(self):
4535 Check if orientation of 2D elements is coherent
4538 return self.editor.IsCoherentOrientation2D()
4540 def Get1DBranches( self, edges, startNode = 0 ):
4542 Partition given 1D elements into groups of contiguous edges.
4543 A node where number of meeting edges != 2 is a group end.
4544 An optional startNode is used to orient groups it belongs to.
4547 A list of edge groups and a list of corresponding node groups,
4548 where the group is a list of IDs of edges or nodes, like follows
4549 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4550 If a group is closed, the first and last nodes of the group are same.
4552 if isinstance( edges, Mesh ):
4553 edges = edges.GetMesh()
4554 unRegister = genObjUnRegister()
4555 if isinstance( edges, list ):
4556 edges = self.GetIDSource( edges, SMESH.EDGE )
4557 unRegister.set( edges )
4558 return self.editor.Get1DBranches( edges, startNode )
4560 def FindSharpEdges( self, angle, addExisting=False ):
4562 Return sharp edges of faces and non-manifold ones.
4563 Optionally add existing edges.
4566 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4567 addExisting: to return existing edges (1D elements) as well
4570 list of FaceEdge structures
4572 angle = ParseParameters( angle )[0]
4573 return self.editor.FindSharpEdges( angle, addExisting )
4575 def MeshToPassThroughAPoint(self, x, y, z):
4577 Find the node closest to a point and moves it to a point location
4580 x: the X coordinate of a point
4581 y: the Y coordinate of a point
4582 z: the Z coordinate of a point
4585 the ID of a moved node
4588 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4590 def InverseDiag(self, NodeID1, NodeID2):
4592 Replace two neighbour triangles sharing Node1-Node2 link
4593 with the triangles built on the same 4 nodes but having other common link.
4596 NodeID1: the ID of the first node
4597 NodeID2: the ID of the second node
4600 False if proper faces were not found
4602 return self.editor.InverseDiag(NodeID1, NodeID2)
4604 def DeleteDiag(self, NodeID1, NodeID2):
4606 Replace two neighbour triangles sharing *Node1-Node2* link
4607 with a quadrangle built on the same 4 nodes.
4610 NodeID1: ID of the first node
4611 NodeID2: ID of the second node
4614 False if proper faces were not found
4617 This operation can create gaps in numeration of elements.
4618 Call :meth:`RenumberElements` to remove the gaps.
4621 return self.editor.DeleteDiag(NodeID1, NodeID2)
4623 def AddNodeOnSegment(self, Node1, Node2, position = 0.5):
4625 Replace each triangle bound by Node1-Node2 segment with
4626 two triangles by connecting a node made on the link with a node
4627 opposite to the link.
4630 Node1: ID of the first node
4631 Node2: ID of the second node
4632 position: location [0,1] of the new node on the segment
4634 return self.editor.AddNodeOnSegment(Node1, Node2, position)
4636 def AddNodeOnFace(self, face, x, y, z):
4638 Split a face into triangles by adding a new node onto the face
4639 and connecting the new node with face nodes
4642 face: ID of the face
4643 x,y,z: coordinates of the new node
4645 return self.editor.AddNodeOnFace(face, x, y, z)
4647 def Reorient(self, IDsOfElements=None):
4649 Reorient elements by ids
4652 IDsOfElements: if undefined reorients all mesh elements
4655 True if succeed else False
4658 if IDsOfElements == None:
4659 IDsOfElements = self.GetElementsId()
4660 return self.editor.Reorient(IDsOfElements)
4662 def ReorientObject(self, theObject):
4664 Reorient all elements of the object
4667 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4670 True if succeed else False
4673 if ( isinstance( theObject, Mesh )):
4674 theObject = theObject.GetMesh()
4675 return self.editor.ReorientObject(theObject)
4677 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4679 Reorient faces contained in *the2DObject*.
4682 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4683 theDirection: a desired direction of normal of *theFace*.
4684 It can be either a GEOM vector or a list of coordinates [x,y,z].
4685 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4686 compared with theDirection. It can be either ID of face or a point
4687 by which the face will be found. The point can be given as either
4688 a GEOM vertex or a list of point coordinates.
4691 number of reoriented faces
4694 unRegister = genObjUnRegister()
4696 if isinstance( the2DObject, Mesh ):
4697 the2DObject = the2DObject.GetMesh()
4698 if isinstance( the2DObject, list ):
4699 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4700 unRegister.set( the2DObject )
4701 # check theDirection
4702 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4703 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4704 if isinstance( theDirection, list ):
4705 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4706 # prepare theFace and thePoint
4707 theFace = theFaceOrPoint
4708 thePoint = PointStruct(0,0,0)
4709 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4710 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4712 if isinstance( theFaceOrPoint, list ):
4713 thePoint = PointStruct( *theFaceOrPoint )
4715 if isinstance( theFaceOrPoint, PointStruct ):
4716 thePoint = theFaceOrPoint
4718 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4720 def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4722 Reorient faces contained in a list of *objectFaces*
4723 equally to faces contained in a list of *referenceFaces*.
4726 objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4727 referenceFaces: list of :class:`sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding reference faces. It can be empty, then any face in *objectFaces* is used as the reference.
4730 number of reoriented faces.
4732 if not isinstance( objectFaces, list ):
4733 objectFaces = [ objectFaces ]
4734 for i,obj2D in enumerate( objectFaces ):
4735 if isinstance( obj2D, Mesh ):
4736 objectFaces[i] = obj2D.GetMesh()
4737 if not isinstance( referenceFaces, list ):
4738 referenceFaces = [ referenceFaces ]
4740 return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4743 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4745 Reorient faces according to adjacent volumes.
4748 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4749 either IDs of faces or face groups.
4750 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4751 theOutsideNormal: to orient faces to have their normals
4752 pointing either *outside* or *inside* the adjacent volumes.
4755 number of reoriented faces.
4758 unRegister = genObjUnRegister()
4760 if not isinstance( the2DObject, list ):
4761 the2DObject = [ the2DObject ]
4762 elif the2DObject and isinstance( the2DObject[0], int ):
4763 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4764 unRegister.set( the2DObject )
4765 the2DObject = [ the2DObject ]
4766 for i,obj2D in enumerate( the2DObject ):
4767 if isinstance( obj2D, Mesh ):
4768 the2DObject[i] = obj2D.GetMesh()
4769 if isinstance( obj2D, list ):
4770 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4771 unRegister.set( the2DObject[i] )
4773 if isinstance( the3DObject, Mesh ):
4774 the3DObject = the3DObject.GetMesh()
4775 if isinstance( the3DObject, list ):
4776 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4777 unRegister.set( the3DObject )
4778 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4780 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4782 Fuse the neighbouring triangles into quadrangles.
4785 IDsOfElements: The triangles to be fused.
4786 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4787 applied to possible quadrangles to choose a neighbour to fuse with.
4788 Note that not all items of :class:`SMESH.FunctorType` corresponds
4789 to numerical functors.
4790 MaxAngle: is the maximum angle between element normals at which the fusion
4791 is still performed; theMaxAngle is measured in radians.
4792 Also it could be a name of variable which defines angle in degrees.
4795 True in case of success, False otherwise.
4798 This operation can create gaps in numeration of elements.
4799 Call :meth:`RenumberElements` to remove the gaps.
4802 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4803 self.mesh.SetParameters(Parameters)
4804 if not IDsOfElements:
4805 IDsOfElements = self.GetElementsId()
4806 Functor = self.smeshpyD.GetFunctor(theCriterion)
4807 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4809 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4811 Fuse the neighbouring triangles of the object into quadrangles
4814 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4815 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4816 applied to possible quadrangles to choose a neighbour to fuse with.
4817 Note that not all items of :class:`SMESH.FunctorType` corresponds
4818 to numerical functors.
4819 MaxAngle: a max angle between element normals at which the fusion
4820 is still performed; theMaxAngle is measured in radians.
4823 True in case of success, False otherwise.
4826 This operation can create gaps in numeration of elements.
4827 Call :meth:`RenumberElements` to remove the gaps.
4830 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4831 self.mesh.SetParameters(Parameters)
4832 if isinstance( theObject, Mesh ):
4833 theObject = theObject.GetMesh()
4834 Functor = self.smeshpyD.GetFunctor(theCriterion)
4835 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4837 def QuadToTri (self, IDsOfElements, theCriterion = None):
4839 Split quadrangles into triangles.
4842 IDsOfElements: the faces to be splitted.
4843 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4844 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4845 value, then quadrangles will be split by the smallest diagonal.
4846 Note that not all items of :class:`SMESH.FunctorType` corresponds
4847 to numerical functors.
4850 True in case of success, False otherwise.
4853 This operation can create gaps in numeration of elements.
4854 Call :meth:`RenumberElements` to remove the gaps.
4856 if IDsOfElements == []:
4857 IDsOfElements = self.GetElementsId()
4858 if theCriterion is None:
4859 theCriterion = FT_MaxElementLength2D
4860 Functor = self.smeshpyD.GetFunctor(theCriterion)
4861 return self.editor.QuadToTri(IDsOfElements, Functor)
4863 def QuadToTriObject (self, theObject, theCriterion = None):
4865 Split quadrangles into triangles.
4868 theObject: the object from which the list of elements is taken,
4869 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4870 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4871 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4872 value, then quadrangles will be split by the smallest diagonal.
4873 Note that not all items of :class:`SMESH.FunctorType` corresponds
4874 to numerical functors.
4877 True in case of success, False otherwise.
4880 This operation can create gaps in numeration of elements.
4881 Call :meth:`RenumberElements` to remove the gaps.
4883 if ( isinstance( theObject, Mesh )):
4884 theObject = theObject.GetMesh()
4885 if theCriterion is None:
4886 theCriterion = FT_MaxElementLength2D
4887 Functor = self.smeshpyD.GetFunctor(theCriterion)
4888 return self.editor.QuadToTriObject(theObject, Functor)
4890 def QuadTo4Tri (self, theElements=[]):
4892 Split each of given quadrangles into 4 triangles. A node is added at the center of
4896 theElements: the faces to be splitted. This can be either
4897 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4898 or a list of face IDs. By default all quadrangles are split
4901 This operation can create gaps in numeration of elements.
4902 Call :meth:`RenumberElements` to remove the gaps.
4904 unRegister = genObjUnRegister()
4905 if isinstance( theElements, Mesh ):
4906 theElements = theElements.mesh
4907 elif not theElements:
4908 theElements = self.mesh
4909 elif isinstance( theElements, list ):
4910 theElements = self.GetIDSource( theElements, SMESH.FACE )
4911 unRegister.set( theElements )
4912 return self.editor.QuadTo4Tri( theElements )
4914 def SplitQuad (self, IDsOfElements, Diag13):
4916 Split quadrangles into triangles.
4919 IDsOfElements: the faces to be splitted
4920 Diag13 (boolean): is used to choose a diagonal for splitting.
4923 True in case of success, False otherwise.
4926 This operation can create gaps in numeration of elements.
4927 Call :meth:`RenumberElements` to remove the gaps.
4929 if IDsOfElements == []:
4930 IDsOfElements = self.GetElementsId()
4931 return self.editor.SplitQuad(IDsOfElements, Diag13)
4933 def SplitQuadObject (self, theObject, Diag13):
4935 Split quadrangles into triangles.
4938 theObject: the object from which the list of elements is taken,
4939 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4940 Diag13 (boolean): is used to choose a diagonal for splitting.
4943 True in case of success, False otherwise.
4946 This operation can create gaps in numeration of elements.
4947 Call :meth:`RenumberElements` to remove the gaps.
4949 if ( isinstance( theObject, Mesh )):
4950 theObject = theObject.GetMesh()
4951 return self.editor.SplitQuadObject(theObject, Diag13)
4953 def BestSplit (self, IDOfQuad, theCriterion):
4955 Find a better splitting of the given quadrangle.
4958 IDOfQuad: the ID of the quadrangle to be splitted.
4959 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4960 choose a diagonal for splitting.
4961 Note that not all items of :class:`SMESH.FunctorType` corresponds
4962 to numerical functors.
4965 * 1 if 1-3 diagonal is better,
4966 * 2 if 2-4 diagonal is better,
4967 * 0 if error occurs.
4970 This operation can create gaps in numeration of elements.
4971 Call :meth:`RenumberElements` to remove the gaps.
4973 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4975 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4977 Split volumic elements into tetrahedrons
4980 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4981 method: flags passing splitting method:
4982 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4983 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4986 This operation can create gaps in numeration of elements.
4987 Call :meth:`RenumberElements` to remove the gaps.
4989 unRegister = genObjUnRegister()
4990 if isinstance( elems, Mesh ):
4991 elems = elems.GetMesh()
4992 if ( isinstance( elems, list )):
4993 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4994 unRegister.set( elems )
4995 self.editor.SplitVolumesIntoTetra(elems, method)
4998 def SplitBiQuadraticIntoLinear(self, elems=None):
5000 Split bi-quadratic elements into linear ones without creation of additional nodes:
5002 - bi-quadratic triangle will be split into 3 linear quadrangles;
5003 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
5004 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
5006 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
5007 will be split in order to keep the mesh conformal.
5010 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
5011 if None (default), all bi-quadratic elements will be split
5014 This operation can create gaps in numeration of elements.
5015 Call :meth:`RenumberElements` to remove the gaps.
5017 unRegister = genObjUnRegister()
5018 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
5019 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
5020 unRegister.set( elems )
5022 elems = [ self.GetMesh() ]
5023 if isinstance( elems, Mesh ):
5024 elems = [ elems.GetMesh() ]
5025 if not isinstance( elems, list ):
5027 self.editor.SplitBiQuadraticIntoLinear( elems )
5029 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
5030 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
5032 Split hexahedra into prisms
5035 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5036 startHexPoint: a point used to find a hexahedron for which *facetNormal*
5037 gives a normal vector defining facets to split into triangles.
5038 *startHexPoint* can be either a triple of coordinates or a vertex.
5039 facetNormal: a normal to a facet to split into triangles of a
5040 hexahedron found by *startHexPoint*.
5041 *facetNormal* can be either a triple of coordinates or an edge.
5042 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
5043 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
5044 allDomains: if :code:`False`, only hexahedra adjacent to one closest
5045 to *startHexPoint* are split, else *startHexPoint*
5046 is used to find the facet to split in all domains present in *elems*.
5049 This operation can create gaps in numeration of elements.
5050 Call :meth:`RenumberElements` to remove the gaps.
5053 unRegister = genObjUnRegister()
5054 if isinstance( elems, Mesh ):
5055 elems = elems.GetMesh()
5056 if ( isinstance( elems, list )):
5057 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5058 unRegister.set( elems )
5061 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5062 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5063 elif isinstance( startHexPoint, list ):
5064 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5067 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5068 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5069 elif isinstance( facetNormal, list ):
5070 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5073 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5075 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5077 def SplitQuadsNearTriangularFacets(self):
5079 Split quadrangle faces near triangular facets of volumes
5082 This operation can create gaps in numeration of elements.
5083 Call :meth:`RenumberElements` to remove the gaps.
5085 faces_array = self.GetElementsByType(SMESH.FACE)
5086 for face_id in faces_array:
5087 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5088 quad_nodes = self.mesh.GetElemNodes(face_id)
5089 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5090 isVolumeFound = False
5091 for node1_elem in node1_elems:
5092 if not isVolumeFound:
5093 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5094 nb_nodes = self.GetElemNbNodes(node1_elem)
5095 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5096 volume_elem = node1_elem
5097 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5098 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5099 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5100 isVolumeFound = True
5101 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5102 self.SplitQuad([face_id], False) # diagonal 2-4
5103 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5104 isVolumeFound = True
5105 self.SplitQuad([face_id], True) # diagonal 1-3
5106 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5107 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5108 isVolumeFound = True
5109 self.SplitQuad([face_id], True) # diagonal 1-3
5111 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5113 Split hexahedrons into tetrahedrons.
5115 This operation uses :doc:`pattern_mapping` functionality for splitting.
5118 theObject: the object from which the list of hexahedrons is taken;
5119 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5120 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5121 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5122 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5123 key-point will be mapped into *theNode001*-th node of each volume.
5124 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5127 True in case of success, False otherwise.
5130 This operation can create gaps in numeration of elements.
5131 Call :meth:`RenumberElements` to remove the gaps.
5139 # (0,0,1) 4.---------.7 * |
5146 # (0,0,0) 0.---------.3
5147 pattern_tetra = "!!! Nb of points: \n 8 \n\
5157 !!! Indices of points of 6 tetras: \n\
5165 pattern = self.smeshpyD.GetPattern()
5166 isDone = pattern.LoadFromFile(pattern_tetra)
5168 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5171 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5172 isDone = pattern.MakeMesh(self.mesh, False, False)
5173 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5175 # split quafrangle faces near triangular facets of volumes
5176 self.SplitQuadsNearTriangularFacets()
5180 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5182 Split hexahedrons into prisms.
5184 Uses the :doc:`pattern_mapping` functionality for splitting.
5187 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5188 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5189 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5190 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5191 will be mapped into the *theNode001* -th node of each volume.
5192 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5195 True in case of success, False otherwise.
5198 This operation can create gaps in numeration of elements.
5199 Call :meth:`RenumberElements` to remove the gaps.
5201 # Pattern: 5.---------.6
5206 # (0,0,1) 4.---------.7 |
5213 # (0,0,0) 0.---------.3
5214 pattern_prism = "!!! Nb of points: \n 8 \n\
5224 !!! Indices of points of 2 prisms: \n\
5228 pattern = self.smeshpyD.GetPattern()
5229 isDone = pattern.LoadFromFile(pattern_prism)
5231 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5234 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5235 isDone = pattern.MakeMesh(self.mesh, False, False)
5236 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5238 # Split quafrangle faces near triangular facets of volumes
5239 self.SplitQuadsNearTriangularFacets()
5243 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5244 MaxNbOfIterations, MaxAspectRatio, Method):
5249 IDsOfElements: the list if ids of elements to smooth
5250 IDsOfFixedNodes: the list of ids of fixed nodes.
5251 Note that nodes built on edges and boundary nodes are always fixed.
5252 MaxNbOfIterations: the maximum number of iterations
5253 MaxAspectRatio: varies in range [1.0, inf]
5254 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5255 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5258 True in case of success, False otherwise.
5261 if IDsOfElements == []:
5262 IDsOfElements = self.GetElementsId()
5263 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5264 self.mesh.SetParameters(Parameters)
5265 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5266 MaxNbOfIterations, MaxAspectRatio, Method)
5268 def SmoothObject(self, theObject, IDsOfFixedNodes,
5269 MaxNbOfIterations, MaxAspectRatio, Method):
5271 Smooth elements which belong to the given object
5274 theObject: the object to smooth
5275 IDsOfFixedNodes: the list of ids of fixed nodes.
5276 Note that nodes built on edges and boundary nodes are always fixed.
5277 MaxNbOfIterations: the maximum number of iterations
5278 MaxAspectRatio: varies in range [1.0, inf]
5279 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5280 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5283 True in case of success, False otherwise.
5286 if ( isinstance( theObject, Mesh )):
5287 theObject = theObject.GetMesh()
5288 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5289 MaxNbOfIterations, MaxAspectRatio, Method)
5291 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5292 MaxNbOfIterations, MaxAspectRatio, Method):
5294 Parametrically smooth the given elements
5297 IDsOfElements: the list if ids of elements to smooth
5298 IDsOfFixedNodes: the list of ids of fixed nodes.
5299 Note that nodes built on edges and boundary nodes are always fixed.
5300 MaxNbOfIterations: the maximum number of iterations
5301 MaxAspectRatio: varies in range [1.0, inf]
5302 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5303 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5306 True in case of success, False otherwise.
5309 if IDsOfElements == []:
5310 IDsOfElements = self.GetElementsId()
5311 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5312 self.mesh.SetParameters(Parameters)
5313 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5314 MaxNbOfIterations, MaxAspectRatio, Method)
5316 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5317 MaxNbOfIterations, MaxAspectRatio, Method):
5319 Parametrically smooth the elements which belong to the given object
5322 theObject: the object to smooth
5323 IDsOfFixedNodes: the list of ids of fixed nodes.
5324 Note that nodes built on edges and boundary nodes are always fixed.
5325 MaxNbOfIterations: the maximum number of iterations
5326 MaxAspectRatio: varies in range [1.0, inf]
5327 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5328 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5331 True in case of success, False otherwise.
5334 if ( isinstance( theObject, Mesh )):
5335 theObject = theObject.GetMesh()
5336 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5337 MaxNbOfIterations, MaxAspectRatio, Method)
5339 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5341 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5342 them with quadratic with the same id.
5345 theForce3d: method of new node creation:
5347 * False - the medium node lies at the geometrical entity from which the mesh element is built
5348 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5349 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5350 theToBiQuad: If True, converts the mesh to bi-quadratic
5353 :class:`SMESH.ComputeError` which can hold a warning
5356 If *theSubMesh* is provided, the mesh can become non-conformal
5359 This operation can create gaps in numeration of nodes or elements.
5360 Call :meth:`RenumberElements` to remove the gaps.
5363 if isinstance( theSubMesh, Mesh ):
5364 theSubMesh = theSubMesh.mesh
5366 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5369 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5371 self.editor.ConvertToQuadratic(theForce3d)
5372 error = self.editor.GetLastError()
5373 if error and error.comment:
5374 print(error.comment)
5377 def ConvertFromQuadratic(self, theSubMesh=None):
5379 Convert the mesh from quadratic to ordinary,
5380 deletes old quadratic elements,
5381 replacing them with ordinary mesh elements with the same id.
5384 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5387 If *theSubMesh* is provided, the mesh can become non-conformal
5390 This operation can create gaps in numeration of nodes or elements.
5391 Call :meth:`RenumberElements` to remove the gaps.
5395 self.editor.ConvertFromQuadraticObject(theSubMesh)
5397 return self.editor.ConvertFromQuadratic()
5399 def Make2DMeshFrom3D(self):
5401 Create 2D mesh as skin on boundary faces of a 3D mesh
5404 True if operation has been completed successfully, False otherwise
5407 return self.editor.Make2DMeshFrom3D()
5409 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5410 toCopyElements=False, toCopyExistingBondary=False):
5412 Create missing boundary elements
5415 elements: elements whose boundary is to be checked:
5416 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5417 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5418 dimension: defines type of boundary elements to create, either of
5419 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5420 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5421 groupName: a name of group to store created boundary elements in,
5422 "" means not to create the group
5423 meshName: a name of new mesh to store created boundary elements in,
5424 "" means not to create the new mesh
5425 toCopyElements: if True, the checked elements will be copied into
5426 the new mesh else only boundary elements will be copied into the new mesh
5427 toCopyExistingBondary: if True, not only new but also pre-existing
5428 boundary elements will be copied into the new mesh
5431 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5434 unRegister = genObjUnRegister()
5435 if isinstance( elements, Mesh ):
5436 elements = elements.GetMesh()
5437 if ( isinstance( elements, list )):
5438 elemType = SMESH.ALL
5439 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5440 elements = self.editor.MakeIDSource(elements, elemType)
5441 unRegister.set( elements )
5442 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5443 toCopyElements,toCopyExistingBondary)
5444 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5447 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5448 toCopyAll=False, groups=[]):
5450 Create missing boundary elements around either the whole mesh or
5454 dimension: defines type of boundary elements to create, either of
5455 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5456 groupName: a name of group to store all boundary elements in,
5457 "" means not to create the group
5458 meshName: a name of a new mesh, which is a copy of the initial
5459 mesh + created boundary elements; "" means not to create the new mesh
5460 toCopyAll: if True, the whole initial mesh will be copied into
5461 the new mesh else only boundary elements will be copied into the new mesh
5462 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5465 tuple( long, mesh, group )
5466 - long - number of added boundary elements
5467 - mesh - the :class:`Mesh` where elements were added to
5468 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5471 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5473 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5474 return nb, mesh, group
5476 def RenumberNodes(self):
5478 Renumber mesh nodes to remove unused node IDs
5480 self.editor.RenumberNodes()
5482 def RenumberElements(self):
5484 Renumber mesh elements to remove unused element IDs
5486 self.editor.RenumberElements()
5488 def _getIdSourceList(self, arg, idType, unRegister):
5490 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5492 if arg and isinstance( arg, list ):
5493 if isinstance( arg[0], int ):
5494 arg = self.GetIDSource( arg, idType )
5495 unRegister.set( arg )
5496 elif isinstance( arg[0], Mesh ):
5497 arg[0] = arg[0].GetMesh()
5498 elif isinstance( arg, Mesh ):
5500 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5504 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5505 MakeGroups=False, TotalAngle=False):
5507 Generate new elements by rotation of the given elements and nodes around the axis
5510 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5511 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5512 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5513 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5514 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5515 which defines angle in degrees
5516 NbOfSteps: the number of steps
5517 Tolerance: tolerance
5518 MakeGroups: forces the generation of new groups from existing ones
5519 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5520 of all steps, else - size of each step
5523 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5526 unRegister = genObjUnRegister()
5527 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5528 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5529 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5531 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5532 Axis = self.smeshpyD.GetAxisStruct( Axis )
5533 if isinstance( Axis, list ):
5534 Axis = SMESH.AxisStruct( *Axis )
5536 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5537 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5538 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5539 self.mesh.SetParameters(Parameters)
5540 if TotalAngle and NbOfSteps:
5541 AngleInRadians /= NbOfSteps
5542 return self.editor.RotationSweepObjects( nodes, edges, faces,
5543 Axis, AngleInRadians,
5544 NbOfSteps, Tolerance, MakeGroups)
5546 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5547 MakeGroups=False, TotalAngle=False):
5549 Generate new elements by rotation of the elements around the axis
5552 IDsOfElements: the list of ids of elements to sweep
5553 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5554 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5555 NbOfSteps: the number of steps
5556 Tolerance: tolerance
5557 MakeGroups: forces the generation of new groups from existing ones
5558 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5559 of all steps, else - size of each step
5562 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5565 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5566 AngleInRadians, NbOfSteps, Tolerance,
5567 MakeGroups, TotalAngle)
5569 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5570 MakeGroups=False, TotalAngle=False):
5572 Generate new elements by rotation of the elements of object around the axis
5573 theObject object which elements should be sweeped.
5574 It can be a mesh, a sub mesh or a group.
5577 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5578 AngleInRadians: the angle of Rotation
5579 NbOfSteps: number of steps
5580 Tolerance: tolerance
5581 MakeGroups: forces the generation of new groups from existing ones
5582 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5583 of all steps, else - size of each step
5586 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5589 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5590 AngleInRadians, NbOfSteps, Tolerance,
5591 MakeGroups, TotalAngle )
5593 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5594 MakeGroups=False, TotalAngle=False):
5596 Generate new elements by rotation of the elements of object around the axis
5597 theObject object which elements should be sweeped.
5598 It can be a mesh, a sub mesh or a group.
5601 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5602 AngleInRadians: the angle of Rotation
5603 NbOfSteps: number of steps
5604 Tolerance: tolerance
5605 MakeGroups: forces the generation of new groups from existing ones
5606 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5607 of all steps, else - size of each step
5610 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5611 empty list otherwise
5614 return self.RotationSweepObjects([],theObject,[], Axis,
5615 AngleInRadians, NbOfSteps, Tolerance,
5616 MakeGroups, TotalAngle)
5618 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5619 MakeGroups=False, TotalAngle=False):
5621 Generate new elements by rotation of the elements of object around the axis
5622 theObject object which elements should be sweeped.
5623 It can be a mesh, a sub mesh or a group.
5626 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5627 AngleInRadians: the angle of Rotation
5628 NbOfSteps: number of steps
5629 Tolerance: tolerance
5630 MakeGroups: forces the generation of new groups from existing ones
5631 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5632 of all steps, else - size of each step
5635 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5638 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5639 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5641 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5642 scaleFactors=[], linearVariation=False, basePoint=[],
5643 angles=[], anglesVariation=False):
5645 Generate new elements by extrusion of the given elements and nodes
5648 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5649 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5650 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5651 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5652 the direction and value of extrusion for one step (the total extrusion
5653 length will be NbOfSteps * ||StepVector||)
5654 NbOfSteps: the number of steps
5655 MakeGroups: forces the generation of new groups from existing ones
5656 scaleFactors: optional scale factors to apply during extrusion
5657 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5658 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5659 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5660 nodes and elements being extruded is used as the scaling center.
5663 - a list of tree components of the point or
5666 angles: list of angles in radians. Nodes at each extrusion step are rotated
5667 around *basePoint*, additionally to previous steps.
5668 anglesVariation: forces the computation of rotation angles as linear
5669 variation of the given *angles* along path steps
5671 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5673 Example: :ref:`tui_extrusion`
5675 unRegister = genObjUnRegister()
5676 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5677 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5678 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5680 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5681 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5682 if isinstance( StepVector, list ):
5683 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5685 if isinstance( basePoint, int):
5686 xyz = self.GetNodeXYZ( basePoint )
5688 raise RuntimeError("Invalid node ID: %s" % basePoint)
5690 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5691 basePoint = self.geompyD.PointCoordinates( basePoint )
5693 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5694 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5695 angles,angleParameters,hasVars = ParseAngles(angles)
5696 Parameters = StepVector.PS.parameters + var_separator + \
5697 Parameters + var_separator + \
5698 scaleParameters + var_separator + angleParameters
5699 self.mesh.SetParameters(Parameters)
5701 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5702 StepVector, NbOfSteps, MakeGroups,
5703 scaleFactors, linearVariation, basePoint,
5704 angles, anglesVariation )
5707 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5709 Generate new elements by extrusion of the elements with given ids
5712 IDsOfElements: the list of ids of elements or nodes for extrusion
5713 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5714 the direction and value of extrusion for one step (the total extrusion
5715 length will be NbOfSteps * ||StepVector||)
5716 NbOfSteps: the number of steps
5717 MakeGroups: forces the generation of new groups from existing ones
5718 IsNodes: is True if elements with given ids are nodes
5721 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5723 Example: :ref:`tui_extrusion`
5726 if IsNodes: n = IDsOfElements
5727 else : e,f, = IDsOfElements,IDsOfElements
5728 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5730 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5731 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5733 Generate new elements by extrusion along the normal to a discretized surface or wire
5736 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5737 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5738 StepSize: length of one extrusion step (the total extrusion
5739 length will be *NbOfSteps* *StepSize*).
5740 NbOfSteps: number of extrusion steps.
5741 ByAverageNormal: if True each node is translated by *StepSize*
5742 along the average of the normal vectors to the faces sharing the node;
5743 else each node is translated along the same average normal till
5744 intersection with the plane got by translation of the face sharing
5745 the node along its own normal by *StepSize*.
5746 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5747 for every node of *Elements*.
5748 MakeGroups: forces generation of new groups from existing ones.
5749 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5750 is not yet implemented. This parameter is used if *Elements* contains
5751 both faces and edges, i.e. *Elements* is a Mesh.
5754 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5755 empty list otherwise.
5756 Example: :ref:`tui_extrusion`
5759 unRegister = genObjUnRegister()
5760 if isinstance( Elements, Mesh ):
5761 Elements = [ Elements.GetMesh() ]
5762 if isinstance( Elements, list ):
5764 raise RuntimeError("Elements empty!")
5765 if isinstance( Elements[0], Mesh ):
5766 Elements = [ Elements[0].GetMesh() ]
5767 if isinstance( Elements[0], int ):
5768 Elements = self.GetIDSource( Elements, SMESH.ALL )
5769 unRegister.set( Elements )
5770 if not isinstance( Elements, list ):
5771 Elements = [ Elements ]
5772 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5773 self.mesh.SetParameters(Parameters)
5774 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5775 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5777 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5779 Generate new elements by extrusion of the elements or nodes which belong to the object
5782 theObject: the object whose elements or nodes should be processed.
5783 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5784 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5785 the direction and value of extrusion for one step (the total extrusion
5786 length will be NbOfSteps * ||StepVector||)
5787 NbOfSteps: the number of steps
5788 MakeGroups: forces the generation of new groups from existing ones
5789 IsNodes: is True if elements to extrude are nodes
5792 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5793 Example: :ref:`tui_extrusion`
5797 if IsNodes: n = theObject
5798 else : e,f, = theObject,theObject
5799 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5801 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5803 Generate new elements by extrusion of edges which belong to the object
5806 theObject: object whose 1D elements should be processed.
5807 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5808 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5809 the direction and value of extrusion for one step (the total extrusion
5810 length will be NbOfSteps * ||StepVector||)
5811 NbOfSteps: the number of steps
5812 MakeGroups: to generate new groups from existing ones
5815 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5816 Example: :ref:`tui_extrusion`
5819 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5821 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5823 Generate new elements by extrusion of faces which belong to the object
5826 theObject: object whose 2D elements should be processed.
5827 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5828 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5829 the direction and value of extrusion for one step (the total extrusion
5830 length will be NbOfSteps * ||StepVector||)
5831 NbOfSteps: the number of steps
5832 MakeGroups: forces the generation of new groups from existing ones
5835 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5836 Example: :ref:`tui_extrusion`
5839 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5841 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5842 ExtrFlags, SewTolerance, MakeGroups=False):
5844 Generate new elements by extrusion of the elements with given ids
5847 IDsOfElements: is ids of elements
5848 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5849 the direction and value of extrusion for one step (the total extrusion
5850 length will be NbOfSteps * ||StepVector||)
5851 NbOfSteps: the number of steps
5852 ExtrFlags: sets flags for extrusion
5853 SewTolerance: uses for comparing locations of nodes if flag
5854 EXTRUSION_FLAG_SEW is set
5855 MakeGroups: forces the generation of new groups from existing ones
5858 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5861 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5862 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5863 if isinstance( StepVector, list ):
5864 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5865 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5866 ExtrFlags, SewTolerance, MakeGroups)
5868 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5869 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5870 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5871 ScaleFactors=[], ScalesVariation=False):
5873 Generate new elements by extrusion of the given elements and nodes along the path.
5874 The path of extrusion must be a meshed edge.
5877 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5878 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5879 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5880 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5881 PathShape: optional shape (edge or wire) which defines the sub-mesh of the mesh defined by *PathObject* if the mesh contains not only path segments, else it can be None
5882 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5883 HasAngles: not used obsolete
5884 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5885 around *basePoint*, additionally to previous steps.
5886 LinearVariation: forces the computation of rotation angles as linear
5887 variation of the given Angles along path steps
5888 HasRefPoint: allows using the reference point
5889 RefPoint: optional scaling and rotation center (mass center of the extruded
5890 elements by default). The User can specify any point as the Reference Point.
5891 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5892 MakeGroups: forces the generation of new groups from existing ones
5893 ScaleFactors: optional scale factors to apply during extrusion
5894 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5895 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5898 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5899 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5900 Example: :ref:`tui_extrusion_along_path`
5903 unRegister = genObjUnRegister()
5904 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5905 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5906 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5908 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5909 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5910 if isinstance( RefPoint, list ):
5911 if not RefPoint: RefPoint = [0,0,0]
5912 RefPoint = SMESH.PointStruct( *RefPoint )
5913 if isinstance( PathObject, Mesh ):
5914 PathObject = PathObject.GetMesh()
5915 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5916 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5917 Parameters = AnglesParameters + var_separator + \
5918 RefPoint.parameters + var_separator + ScalesParameters
5919 self.mesh.SetParameters(Parameters)
5920 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5921 PathObject, PathShape, NodeStart,
5922 HasAngles, Angles, LinearVariation,
5923 HasRefPoint, RefPoint, MakeGroups,
5924 ScaleFactors, ScalesVariation)
5926 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5927 HasAngles=False, Angles=[], LinearVariation=False,
5928 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5929 ElemType=SMESH.FACE):
5931 Generate new elements by extrusion of the given elements.
5932 The path of extrusion must be a meshed edge.
5935 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5936 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5937 NodeStart: the start node from Path. Defines the direction of extrusion
5938 HasAngles: not used obsolete
5939 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5940 around *basePoint*, additionally to previous steps.
5941 LinearVariation: forces the computation of rotation angles as linear
5942 variation of the given Angles along path steps
5943 HasRefPoint: allows using the reference point
5944 RefPoint: the reference point around which the elements are rotated (the mass
5945 center of the elements by default).
5946 The User can specify any point as the Reference Point.
5947 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5948 MakeGroups: forces the generation of new groups from existing ones
5949 ElemType: type of elements for extrusion (if param Base is a mesh)
5952 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5953 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5954 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5956 Example: :ref:`tui_extrusion_along_path`
5960 if ElemType == SMESH.NODE: n = Base
5961 if ElemType == SMESH.EDGE: e = Base
5962 if ElemType == SMESH.FACE: f = Base
5963 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5964 HasAngles, Angles, LinearVariation,
5965 HasRefPoint, RefPoint, MakeGroups)
5966 if MakeGroups: return gr,er
5969 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5970 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5971 MakeGroups=False, LinearVariation=False):
5973 Generate new elements by extrusion of the given elements.
5974 The path of extrusion must be a meshed edge.
5977 IDsOfElements: ids of elements
5978 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5979 PathShape: shape (edge) defines the sub-mesh for the path
5980 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5981 HasAngles: not used obsolete
5982 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5983 around *basePoint*, additionally to previous steps.
5984 HasRefPoint: allows using the reference point
5985 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5986 The User can specify any point as the Reference Point.
5987 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5988 MakeGroups: forces the generation of new groups from existing ones
5989 LinearVariation: forces the computation of rotation angles as linear
5990 variation of the given Angles along path steps
5993 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5994 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5995 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5996 Example: :ref:`tui_extrusion_along_path`
5999 if not IDsOfElements:
6000 IDsOfElements = [ self.GetMesh() ]
6001 n,e,f = [],IDsOfElements,IDsOfElements
6002 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
6003 NodeStart, HasAngles, Angles,
6005 HasRefPoint, RefPoint, MakeGroups)
6006 if MakeGroups: return gr,er
6009 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
6010 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6011 MakeGroups=False, LinearVariation=False):
6013 Generate new elements by extrusion of the elements which belong to the object.
6014 The path of extrusion must be a meshed edge.
6017 theObject: the object whose elements should be processed.
6018 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6019 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6020 PathShape: shape (edge) defines the sub-mesh for the path
6021 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6022 HasAngles: not used obsolete
6023 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6024 around *basePoint*, additionally to previous steps.
6025 HasRefPoint: allows using the reference point
6026 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6027 The User can specify any point as the Reference Point.
6028 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6029 MakeGroups: forces the generation of new groups from existing ones
6030 LinearVariation: forces the computation of rotation angles as linear
6031 variation of the given Angles along path steps
6034 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6035 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6036 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6037 Example: :ref:`tui_extrusion_along_path`
6040 n,e,f = [],theObject,theObject
6041 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6042 HasAngles, Angles, LinearVariation,
6043 HasRefPoint, RefPoint, MakeGroups)
6044 if MakeGroups: return gr,er
6047 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
6048 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6049 MakeGroups=False, LinearVariation=False):
6051 Generate new elements by extrusion of mesh segments which belong to the object.
6052 The path of extrusion must be a meshed edge.
6055 theObject: the object whose 1D elements should be processed.
6056 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6057 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6058 PathShape: shape (edge) defines the sub-mesh for the path
6059 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6060 HasAngles: not used obsolete
6061 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6062 around *basePoint*, additionally to previous steps.
6063 HasRefPoint: allows using the reference point
6064 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6065 The User can specify any point as the Reference Point.
6066 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6067 MakeGroups: forces the generation of new groups from existing ones
6068 LinearVariation: forces the computation of rotation angles as linear
6069 variation of the given Angles along path steps
6072 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6073 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6074 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6075 Example: :ref:`tui_extrusion_along_path`
6078 n,e,f = [],theObject,[]
6079 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6080 HasAngles, Angles, LinearVariation,
6081 HasRefPoint, RefPoint, MakeGroups)
6082 if MakeGroups: return gr,er
6085 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6086 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6087 MakeGroups=False, LinearVariation=False):
6089 Generate new elements by extrusion of faces which belong to the object.
6090 The path of extrusion must be a meshed edge.
6093 theObject: the object whose 2D elements should be processed.
6094 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6095 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6096 PathShape: shape (edge) defines the sub-mesh for the path
6097 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6098 HasAngles: not used obsolete
6099 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6100 around *basePoint*, additionally to previous steps.
6101 HasRefPoint: allows using the reference point
6102 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6103 The User can specify any point as the Reference Point.
6104 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6105 MakeGroups: forces the generation of new groups from existing ones
6106 LinearVariation: forces the computation of rotation angles as linear
6107 variation of the given Angles along path steps
6110 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6111 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6112 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6113 Example: :ref:`tui_extrusion_along_path`
6116 n,e,f = [],[],theObject
6117 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6118 HasAngles, Angles, LinearVariation,
6119 HasRefPoint, RefPoint, MakeGroups)
6120 if MakeGroups: return gr,er
6123 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6125 Create a symmetrical copy of mesh elements
6128 IDsOfElements: list of elements ids
6129 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6130 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6131 If the *Mirror* is a geom object this parameter is unnecessary
6132 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6133 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6136 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6139 if IDsOfElements == []:
6140 IDsOfElements = self.GetElementsId()
6141 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6142 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6143 theMirrorType = Mirror._mirrorType
6145 self.mesh.SetParameters(Mirror.parameters)
6146 if Copy and MakeGroups:
6147 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6148 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6151 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6153 Create a new mesh by a symmetrical copy of mesh elements
6156 IDsOfElements: the list of elements ids
6157 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6158 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6159 If the *Mirror* is a geom object this parameter is unnecessary
6160 MakeGroups: to generate new groups from existing ones
6161 NewMeshName: a name of the new mesh to create
6164 instance of class :class:`Mesh`
6167 if IDsOfElements == []:
6168 IDsOfElements = self.GetElementsId()
6169 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6170 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6171 theMirrorType = Mirror._mirrorType
6173 self.mesh.SetParameters(Mirror.parameters)
6174 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6175 MakeGroups, NewMeshName)
6176 return Mesh(self.smeshpyD,self.geompyD,mesh)
6178 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6180 Create a symmetrical copy of the object
6183 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6184 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6185 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6186 If the *Mirror* is a geom object this parameter is unnecessary
6187 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6188 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6191 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6194 if ( isinstance( theObject, Mesh )):
6195 theObject = theObject.GetMesh()
6196 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6197 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6198 theMirrorType = Mirror._mirrorType
6200 self.mesh.SetParameters(Mirror.parameters)
6201 if Copy and MakeGroups:
6202 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6203 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6206 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6208 Create a new mesh by a symmetrical copy of the object
6211 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6212 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6213 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6214 If the *Mirror* is a geom object this parameter is unnecessary
6215 MakeGroups: forces the generation of new groups from existing ones
6216 NewMeshName: the name of the new mesh to create
6219 instance of class :class:`Mesh`
6222 if ( isinstance( theObject, Mesh )):
6223 theObject = theObject.GetMesh()
6224 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6225 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6226 theMirrorType = Mirror._mirrorType
6228 self.mesh.SetParameters(Mirror.parameters)
6229 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6230 MakeGroups, NewMeshName)
6231 return Mesh( self.smeshpyD,self.geompyD,mesh )
6233 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6235 Translate the elements
6238 IDsOfElements: list of elements ids
6239 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6240 Copy: allows copying the translated elements
6241 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6244 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6247 if IDsOfElements == []:
6248 IDsOfElements = self.GetElementsId()
6249 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6250 Vector = self.smeshpyD.GetDirStruct(Vector)
6251 if isinstance( Vector, list ):
6252 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6253 self.mesh.SetParameters(Vector.PS.parameters)
6254 if Copy and MakeGroups:
6255 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6256 self.editor.Translate(IDsOfElements, Vector, Copy)
6259 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6261 Create a new mesh of translated elements
6264 IDsOfElements: list of elements ids
6265 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6266 MakeGroups: forces the generation of new groups from existing ones
6267 NewMeshName: the name of the newly created mesh
6270 instance of class :class:`Mesh`
6273 if IDsOfElements == []:
6274 IDsOfElements = self.GetElementsId()
6275 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6276 Vector = self.smeshpyD.GetDirStruct(Vector)
6277 if isinstance( Vector, list ):
6278 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6279 self.mesh.SetParameters(Vector.PS.parameters)
6280 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6281 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6283 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6285 Translate the object
6288 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6289 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6290 Copy: allows copying the translated elements
6291 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6294 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6297 if ( isinstance( theObject, Mesh )):
6298 theObject = theObject.GetMesh()
6299 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6300 Vector = self.smeshpyD.GetDirStruct(Vector)
6301 if isinstance( Vector, list ):
6302 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6303 self.mesh.SetParameters(Vector.PS.parameters)
6304 if Copy and MakeGroups:
6305 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6306 self.editor.TranslateObject(theObject, Vector, Copy)
6309 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6311 Create a new mesh from the translated object
6314 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6315 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6316 MakeGroups: forces the generation of new groups from existing ones
6317 NewMeshName: the name of the newly created mesh
6320 instance of class :class:`Mesh`
6323 if isinstance( theObject, Mesh ):
6324 theObject = theObject.GetMesh()
6325 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6326 Vector = self.smeshpyD.GetDirStruct(Vector)
6327 if isinstance( Vector, list ):
6328 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6329 self.mesh.SetParameters(Vector.PS.parameters)
6330 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6331 return Mesh( self.smeshpyD, self.geompyD, mesh )
6335 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6340 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6341 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6342 theScaleFact: list of 1-3 scale factors for axises
6343 Copy: allows copying the translated elements
6344 MakeGroups: forces the generation of new groups from existing
6348 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6349 empty list otherwise
6351 unRegister = genObjUnRegister()
6352 if ( isinstance( theObject, Mesh )):
6353 theObject = theObject.GetMesh()
6354 if ( isinstance( theObject, list )):
6355 theObject = self.GetIDSource(theObject, SMESH.ALL)
6356 unRegister.set( theObject )
6357 if ( isinstance( thePoint, list )):
6358 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6359 if ( isinstance( theScaleFact, float )):
6360 theScaleFact = [theScaleFact]
6361 if ( isinstance( theScaleFact, int )):
6362 theScaleFact = [ float(theScaleFact)]
6364 self.mesh.SetParameters(thePoint.parameters)
6366 if Copy and MakeGroups:
6367 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6368 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6371 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6373 Create a new mesh from the translated object
6376 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6377 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6378 theScaleFact: list of 1-3 scale factors for axises
6379 MakeGroups: forces the generation of new groups from existing ones
6380 NewMeshName: the name of the newly created mesh
6383 instance of class :class:`Mesh`
6385 unRegister = genObjUnRegister()
6386 if (isinstance(theObject, Mesh)):
6387 theObject = theObject.GetMesh()
6388 if ( isinstance( theObject, list )):
6389 theObject = self.GetIDSource(theObject,SMESH.ALL)
6390 unRegister.set( theObject )
6391 if ( isinstance( thePoint, list )):
6392 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6393 if ( isinstance( theScaleFact, float )):
6394 theScaleFact = [theScaleFact]
6395 if ( isinstance( theScaleFact, int )):
6396 theScaleFact = [ float(theScaleFact)]
6398 self.mesh.SetParameters(thePoint.parameters)
6399 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6400 MakeGroups, NewMeshName)
6401 return Mesh( self.smeshpyD, self.geompyD, mesh )
6405 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6410 IDsOfElements: list of elements ids
6411 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6412 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6413 Copy: allows copying the rotated elements
6414 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6417 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6421 if IDsOfElements == []:
6422 IDsOfElements = self.GetElementsId()
6423 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6424 Axis = self.smeshpyD.GetAxisStruct(Axis)
6425 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6426 Parameters = Axis.parameters + var_separator + Parameters
6427 self.mesh.SetParameters(Parameters)
6428 if Copy and MakeGroups:
6429 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6430 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6433 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6435 Create a new mesh of rotated elements
6438 IDsOfElements: list of element ids
6439 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6440 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6441 MakeGroups: forces the generation of new groups from existing ones
6442 NewMeshName: the name of the newly created mesh
6445 instance of class :class:`Mesh`
6448 if IDsOfElements == []:
6449 IDsOfElements = self.GetElementsId()
6450 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6451 Axis = self.smeshpyD.GetAxisStruct(Axis)
6452 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6453 Parameters = Axis.parameters + var_separator + Parameters
6454 self.mesh.SetParameters(Parameters)
6455 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6456 MakeGroups, NewMeshName)
6457 return Mesh( self.smeshpyD, self.geompyD, mesh )
6459 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6464 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6465 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6466 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6467 Copy: allows copying the rotated elements
6468 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6471 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6474 if (isinstance(theObject, Mesh)):
6475 theObject = theObject.GetMesh()
6476 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6477 Axis = self.smeshpyD.GetAxisStruct(Axis)
6478 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6479 Parameters = Axis.parameters + ":" + Parameters
6480 self.mesh.SetParameters(Parameters)
6481 if Copy and MakeGroups:
6482 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6483 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6486 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6488 Create a new mesh from the rotated object
6491 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6492 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6493 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6494 MakeGroups: forces the generation of new groups from existing ones
6495 NewMeshName: the name of the newly created mesh
6498 instance of class :class:`Mesh`
6501 if (isinstance( theObject, Mesh )):
6502 theObject = theObject.GetMesh()
6503 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6504 Axis = self.smeshpyD.GetAxisStruct(Axis)
6505 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6506 Parameters = Axis.parameters + ":" + Parameters
6507 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6508 MakeGroups, NewMeshName)
6509 self.mesh.SetParameters(Parameters)
6510 return Mesh( self.smeshpyD, self.geompyD, mesh )
6512 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6514 Create an offset mesh from the given 2D object
6517 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6518 theValue (float): signed offset size
6519 MakeGroups (boolean): forces the generation of new groups from existing ones
6520 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6521 False means to remove original elements.
6522 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6525 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6528 if isinstance( theObject, Mesh ):
6529 theObject = theObject.GetMesh()
6530 theValue,Parameters,hasVars = ParseParameters(Value)
6531 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6532 self.mesh.SetParameters(Parameters)
6534 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6537 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6539 Find groups of adjacent nodes within Tolerance.
6542 Tolerance (float): the value of tolerance
6543 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6544 corner and medium nodes in separate groups thus preventing
6545 their further merge.
6548 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6551 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6553 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6554 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6556 Find groups of adjacent nodes within Tolerance.
6559 Tolerance: the value of tolerance
6560 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6561 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6562 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6563 corner and medium nodes in separate groups thus preventing
6564 their further merge.
6567 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6570 unRegister = genObjUnRegister()
6571 if not isinstance( SubMeshOrGroup, list ):
6572 SubMeshOrGroup = [ SubMeshOrGroup ]
6573 for i,obj in enumerate( SubMeshOrGroup ):
6574 if isinstance( obj, Mesh ):
6575 SubMeshOrGroup = [ obj.GetMesh() ]
6577 if isinstance( obj, int ):
6578 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6579 unRegister.set( SubMeshOrGroup )
6582 if not isinstance( exceptNodes, list ):
6583 exceptNodes = [ exceptNodes ]
6584 if exceptNodes and isinstance( exceptNodes[0], int ):
6585 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6586 unRegister.set( exceptNodes )
6588 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6589 exceptNodes, SeparateCornerAndMediumNodes)
6591 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6596 GroupsOfNodes: a list of groups of nodes IDs for merging.
6597 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6598 in all elements and mesh groups by nodes 1 and 25 correspondingly
6599 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6600 If *NodesToKeep* does not include a node to keep for some group to merge,
6601 then the first node in the group is kept.
6602 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6606 This operation can create gaps in numeration of nodes or elements.
6607 Call :meth:`RenumberElements` to remove the gaps.
6609 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6611 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6613 Find the elements built on the same nodes.
6616 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6617 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6621 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6624 unRegister = genObjUnRegister()
6625 if MeshOrSubMeshOrGroup is None:
6626 MeshOrSubMeshOrGroup = [ self.mesh ]
6627 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6628 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6629 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6630 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6631 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6632 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6633 unRegister.set( MeshOrSubMeshOrGroup )
6634 for item in MeshOrSubMeshOrGroup:
6635 if isinstance( item, Mesh ):
6636 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6638 if not isinstance( exceptElements, list ):
6639 exceptElements = [ exceptElements ]
6640 if exceptElements and isinstance( exceptElements[0], int ):
6641 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6642 unRegister.set( exceptElements )
6644 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6646 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6648 Merge elements in each given group.
6651 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6652 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6653 replaced in all mesh groups by elements 1 and 25)
6654 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6655 If *ElementsToKeep* does not include an element to keep for some group to merge,
6656 then the first element in the group is kept.
6659 This operation can create gaps in numeration of elements.
6660 Call :meth:`RenumberElements` to remove the gaps.
6663 unRegister = genObjUnRegister()
6665 if not isinstance( ElementsToKeep, list ):
6666 ElementsToKeep = [ ElementsToKeep ]
6667 if isinstance( ElementsToKeep[0], int ):
6668 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6669 unRegister.set( ElementsToKeep )
6671 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6673 def MergeEqualElements(self):
6675 Leave one element and remove all other elements built on the same nodes.
6678 This operation can create gaps in numeration of elements.
6679 Call :meth:`RenumberElements` to remove the gaps.
6682 self.editor.MergeEqualElements()
6684 def FindFreeBorders(self, ClosedOnly=True):
6686 Returns all or only closed free borders
6689 list of SMESH.FreeBorder's
6692 return self.editor.FindFreeBorders( ClosedOnly )
6694 def FillHole(self, holeNodes, groupName=""):
6696 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6699 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6700 must describe all sequential nodes of the hole border. The first and the last
6701 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6702 groupName (string): name of a group to add new faces
6704 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6708 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6709 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6710 if not isinstance( holeNodes, SMESH.FreeBorder ):
6711 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6712 return self.editor.FillHole( holeNodes, groupName )
6714 def FindCoincidentFreeBorders (self, tolerance=0.):
6716 Return groups of FreeBorder's coincident within the given tolerance.
6719 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6720 size of elements adjacent to free borders being compared is used.
6723 SMESH.CoincidentFreeBorders structure
6726 return self.editor.FindCoincidentFreeBorders( tolerance )
6728 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6730 Sew FreeBorder's of each group
6733 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6734 where each enclosed list contains node IDs of a group of coincident free
6735 borders such that each consequent triple of IDs within a group describes
6736 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6737 last node of a border.
6738 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6739 groups of coincident free borders, each group including two borders.
6740 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6741 polygons if a node of opposite border falls on a face edge, else such
6742 faces are split into several ones.
6743 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6744 polyhedra if a node of opposite border falls on a volume edge, else such
6745 volumes, if any, remain intact and the mesh becomes non-conformal.
6748 a number of successfully sewed groups
6751 This operation can create gaps in numeration of nodes or elements.
6752 Call :meth:`RenumberElements` to remove the gaps.
6755 if freeBorders and isinstance( freeBorders, list ):
6756 # construct SMESH.CoincidentFreeBorders
6757 if isinstance( freeBorders[0], int ):
6758 freeBorders = [freeBorders]
6760 coincidentGroups = []
6761 for nodeList in freeBorders:
6762 if not nodeList or len( nodeList ) % 3:
6763 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6766 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6767 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6768 nodeList = nodeList[3:]
6770 coincidentGroups.append( group )
6772 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6774 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6776 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6777 FirstNodeID2, SecondNodeID2, LastNodeID2,
6778 CreatePolygons, CreatePolyedrs):
6783 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6786 This operation can create gaps in numeration of nodes or elements.
6787 Call :meth:`RenumberElements` to remove the gaps.
6790 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6791 FirstNodeID2, SecondNodeID2, LastNodeID2,
6792 CreatePolygons, CreatePolyedrs)
6794 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6795 FirstNodeID2, SecondNodeID2):
6797 Sew conform free borders
6800 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6803 This operation can create gaps in numeration of elements.
6804 Call :meth:`RenumberElements` to remove the gaps.
6807 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6808 FirstNodeID2, SecondNodeID2)
6810 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6811 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6816 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6819 This operation can create gaps in numeration of elements.
6820 Call :meth:`RenumberElements` to remove the gaps.
6823 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6824 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6826 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6827 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6828 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6830 Sew two sides of a mesh. The nodes belonging to Side1 are
6831 merged with the nodes of elements of Side2.
6832 The number of elements in theSide1 and in theSide2 must be
6833 equal and they should have similar nodal connectivity.
6834 The nodes to merge should belong to side borders and
6835 the first node should be linked to the second.
6838 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6841 This operation can create gaps in numeration of nodes.
6842 Call :meth:`RenumberElements` to remove the gaps.
6845 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6846 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6847 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6849 def ChangeElemNodes(self, ide, newIDs):
6851 Set new nodes for the given element. Number of nodes should be kept.
6858 False if the number of nodes does not correspond to the type of element
6861 return self.editor.ChangeElemNodes(ide, newIDs)
6863 def GetLastCreatedNodes(self):
6865 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6866 created, this method return the list of their IDs.
6867 If new nodes were not created - return empty list
6870 the list of integer values (can be empty)
6873 return self.editor.GetLastCreatedNodes()
6875 def GetLastCreatedElems(self):
6877 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6878 created this method return the list of their IDs.
6879 If new elements were not created - return empty list
6882 the list of integer values (can be empty)
6885 return self.editor.GetLastCreatedElems()
6887 def ClearLastCreated(self):
6889 Forget what nodes and elements were created by the last mesh edition operation
6892 self.editor.ClearLastCreated()
6894 def DoubleElements(self, theElements, theGroupName=""):
6896 Create duplicates of given elements, i.e. create new elements based on the
6897 same nodes as the given ones.
6900 theElements: container of elements to duplicate. It can be a
6901 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6902 or a list of element IDs. If *theElements* is
6903 a :class:`Mesh`, elements of highest dimension are duplicated
6904 theGroupName: a name of group to contain the generated elements.
6905 If a group with such a name already exists, the new elements
6906 are added to the existing group, else a new group is created.
6907 If *theGroupName* is empty, new elements are not added
6911 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6912 None if *theGroupName* == "".
6915 unRegister = genObjUnRegister()
6916 if isinstance( theElements, Mesh ):
6917 theElements = theElements.mesh
6918 elif isinstance( theElements, list ):
6919 theElements = self.GetIDSource( theElements, SMESH.ALL )
6920 unRegister.set( theElements )
6921 return self.editor.DoubleElements(theElements, theGroupName)
6923 def DoubleNodes(self, theNodes, theModifiedElems):
6925 Create a hole in a mesh by doubling the nodes of some particular elements
6928 theNodes: IDs of nodes to be doubled
6929 theModifiedElems: IDs of elements to be updated by the new (doubled)
6930 nodes. If list of element identifiers is empty then nodes are doubled but
6931 they not assigned to elements
6934 True if operation has been completed successfully, False otherwise
6937 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6939 def DoubleNode(self, theNodeId, theModifiedElems):
6941 Create a hole in a mesh by doubling the nodes of some particular elements.
6942 This method provided for convenience works as :meth:`DoubleNodes`.
6945 theNodeId: IDs of node to double
6946 theModifiedElems: IDs of elements to update
6949 True if operation has been completed successfully, False otherwise
6952 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6954 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6956 Create a hole in a mesh by doubling the nodes of some particular elements.
6957 This method provided for convenience works as :meth:`DoubleNodes`.
6960 theNodes: group of nodes to double.
6961 theModifiedElems: group of elements to update.
6962 theMakeGroup: forces the generation of a group containing new nodes.
6965 True or a created group if operation has been completed successfully,
6966 False or None otherwise
6970 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6971 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6973 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6975 Create a hole in a mesh by doubling the nodes of some particular elements.
6976 This method provided for convenience works as :meth:`DoubleNodes`.
6979 theNodes: list of groups of nodes to double.
6980 theModifiedElems: list of groups of elements to update.
6981 theMakeGroup: forces the generation of a group containing new nodes.
6984 True if operation has been completed successfully, False otherwise
6988 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6989 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6991 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6993 Create a hole in a mesh by doubling the nodes of some particular elements
6996 theElems: the list of elements (edges or faces) to replicate.
6997 The nodes for duplication could be found from these elements
6998 theNodesNot: list of nodes NOT to replicate
6999 theAffectedElems: the list of elements (cells and edges) to which the
7000 replicated nodes should be associated to
7003 True if operation has been completed successfully, False otherwise
7006 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
7008 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
7010 Create a hole in a mesh by doubling the nodes of some particular elements
7013 theElems: the list of elements (edges or faces) to replicate.
7014 The nodes for duplication could be found from these elements
7015 theNodesNot: list of nodes NOT to replicate
7016 theShape: shape to detect affected elements (element which geometric center
7017 located on or inside shape).
7018 The replicated nodes should be associated to affected elements.
7021 True if operation has been completed successfully, False otherwise
7024 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
7026 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
7027 theMakeGroup=False, theMakeNodeGroup=False):
7029 Create a hole in a mesh by doubling the nodes of some particular elements.
7030 This method provided for convenience works as :meth:`DoubleNodes`.
7033 theElems: group of of elements (edges or faces) to replicate.
7034 theNodesNot: group of nodes NOT to replicate.
7035 theAffectedElems: group of elements to which the replicated nodes
7036 should be associated to.
7037 theMakeGroup: forces the generation of a group containing new elements.
7038 theMakeNodeGroup: forces the generation of a group containing new nodes.
7041 True or created groups (one or two) if operation has been completed successfully,
7042 False or None otherwise
7045 if theMakeGroup or theMakeNodeGroup:
7046 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
7048 theMakeGroup, theMakeNodeGroup)
7049 if theMakeGroup and theMakeNodeGroup:
7052 return twoGroups[ int(theMakeNodeGroup) ]
7053 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7055 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7057 Create a hole in a mesh by doubling the nodes of some particular elements.
7058 This method provided for convenience works as :meth:`DoubleNodes`.
7061 theElems: group of of elements (edges or faces) to replicate
7062 theNodesNot: group of nodes not to replicate
7063 theShape: shape to detect affected elements (element which geometric center
7064 located on or inside shape).
7065 The replicated nodes should be associated to affected elements
7068 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7070 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7071 theMakeGroup=False, theMakeNodeGroup=False):
7073 Create a hole in a mesh by doubling the nodes of some particular elements.
7074 This method provided for convenience works as :meth:`DoubleNodes`.
7077 theElems: list of groups of elements (edges or faces) to replicate
7078 theNodesNot: list of groups of nodes NOT to replicate
7079 theAffectedElems: group of elements to which the replicated nodes
7080 should be associated to
7081 theMakeGroup: forces generation of a group containing new elements.
7082 theMakeNodeGroup: forces generation of a group containing new nodes
7085 True or created groups (one or two) if operation has been completed successfully,
7086 False or None otherwise
7089 if theMakeGroup or theMakeNodeGroup:
7090 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7092 theMakeGroup, theMakeNodeGroup)
7093 if theMakeGroup and theMakeNodeGroup:
7096 return twoGroups[ int(theMakeNodeGroup) ]
7097 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7099 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7101 Create a hole in a mesh by doubling the nodes of some particular elements.
7102 This method provided for convenience works as :meth:`DoubleNodes`.
7105 theElems: list of groups of elements (edges or faces) to replicate
7106 theNodesNot: list of groups of nodes NOT to replicate
7107 theShape: shape to detect affected elements (element which geometric center
7108 located on or inside shape).
7109 The replicated nodes should be associated to affected elements
7112 True if operation has been completed successfully, False otherwise
7115 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7117 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7119 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7120 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7123 theElems: list of groups of nodes or elements (edges or faces) to replicate
7124 theNodesNot: list of groups of nodes NOT to replicate
7125 theShape: shape to detect affected elements (element which geometric center
7126 located on or inside shape).
7127 The replicated nodes should be associated to affected elements
7130 groups of affected elements in order: volumes, faces, edges
7133 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7135 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7138 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7139 The list of groups must describe a partition of the mesh volumes.
7140 The nodes of the internal faces at the boundaries of the groups are doubled.
7141 In option, the internal faces are replaced by flat elements.
7142 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7145 theDomains: list of groups of volumes
7146 createJointElems: if True, create the elements
7147 onAllBoundaries: if True, the nodes and elements are also created on
7148 the boundary between *theDomains* and the rest mesh
7151 True if operation has been completed successfully, False otherwise
7154 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7156 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7158 Double nodes on some external faces and create flat elements.
7159 Flat elements are mainly used by some types of mechanic calculations.
7161 Each group of the list must be constituted of faces.
7162 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7165 theGroupsOfFaces: list of groups of faces
7168 True if operation has been completed successfully, False otherwise
7171 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7173 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7175 Identify all the elements around a geom shape, get the faces delimiting the hole
7177 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7179 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7181 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7182 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7183 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7184 If there are several paths connecting a pair of points, the shortest path is
7185 selected by the module. Position of the cutting plane is defined by the two
7186 points and an optional vector lying on the plane specified by a PolySegment.
7187 By default the vector is defined by Mesh module as following. A middle point
7188 of the two given points is computed. The middle point is projected to the mesh.
7189 The vector goes from the middle point to the projection point. In case of planar
7190 mesh, the vector is normal to the mesh.
7192 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7195 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7196 groupName: optional name of a group where created mesh segments will be added.
7199 editor = self.editor
7201 editor = self.mesh.GetMeshEditPreviewer()
7202 segmentsRes = editor.MakePolyLine( segments, groupName )
7203 for i, seg in enumerate( segmentsRes ):
7204 segments[i].vector = seg.vector
7206 return editor.GetPreviewData()
7209 def MakeSlot(self, segmentGroup, width ):
7211 Create a slot of given width around given 1D elements lying on a triangle mesh.
7212 The slot is constructed by cutting faces by cylindrical surfaces made
7213 around each segment. Segments are expected to be created by MakePolyLine().
7216 FaceEdge's located at the slot boundary
7218 return self.editor.MakeSlot( segmentGroup, width )
7220 def GetFunctor(self, funcType ):
7222 Return a cached numerical functor by its type.
7225 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7226 Note that not all items correspond to numerical functors.
7229 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7232 fn = self.functors[ funcType._v ]
7234 fn = self.smeshpyD.GetFunctor(funcType)
7235 fn.SetMesh(self.mesh)
7236 self.functors[ funcType._v ] = fn
7239 def FunctorValue(self, funcType, elemId, isElem=True):
7241 Return value of a functor for a given element
7244 funcType: an item of :class:`SMESH.FunctorType` enum.
7245 elemId: element or node ID
7246 isElem: *elemId* is ID of element or node
7249 the functor value or zero in case of invalid arguments
7252 fn = self.GetFunctor( funcType )
7253 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7254 val = fn.GetValue(elemId)
7259 def GetLength(self, elemId=None):
7261 Get length of given 1D elements or of all 1D mesh elements
7264 elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum length of all 1D elements will be calculated.
7267 Sum of lengths of given elements
7272 length = self.smeshpyD.GetLength(self)
7273 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7274 length = self.smeshpyD.GetLength(elemId)
7277 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7279 length += self.smeshpyD.GetLength(obj)
7280 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7281 unRegister = genObjUnRegister()
7282 obj = self.GetIDSource( elemId )
7283 unRegister.set( obj )
7284 length = self.smeshpyD.GetLength( obj )
7286 length = self.FunctorValue(SMESH.FT_Length, elemId)
7289 def GetArea(self, elemId=None):
7291 Get area of given 2D elements or of all 2D mesh elements
7294 elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum area of all 2D elements will be calculated.
7297 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7302 area = self.smeshpyD.GetArea(self)
7303 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7304 area = self.smeshpyD.GetArea(elemId)
7307 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7309 area += self.smeshpyD.GetArea(obj)
7310 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7311 unRegister = genObjUnRegister()
7312 obj = self.GetIDSource( elemId )
7313 unRegister.set( obj )
7314 area = self.smeshpyD.GetArea( obj )
7316 area = self.FunctorValue(SMESH.FT_Area, elemId)
7319 def GetVolume(self, elemId=None):
7321 Get volume of given 3D elements or of all 3D mesh elements
7324 elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum volume of all 3D elements will be calculated.
7327 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7332 volume= self.smeshpyD.GetVolume(self)
7333 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7334 volume= self.smeshpyD.GetVolume(elemId)
7337 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7339 volume+= self.smeshpyD.GetVolume(obj)
7340 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7341 unRegister = genObjUnRegister()
7342 obj = self.GetIDSource( elemId )
7343 unRegister.set( obj )
7344 volume= self.smeshpyD.GetVolume( obj )
7346 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7349 def GetAngle(self, node1, node2, node3 ):
7351 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7354 node1,node2,node3: IDs of the three nodes
7357 Angle in radians [0,PI]. -1 if failure case.
7359 p1 = self.GetNodeXYZ( node1 )
7360 p2 = self.GetNodeXYZ( node2 )
7361 p3 = self.GetNodeXYZ( node3 )
7362 if p1 and p2 and p3:
7363 return self.smeshpyD.GetAngle( p1,p2,p3 )
7367 def GetMaxElementLength(self, elemId):
7369 Get maximum element length.
7372 elemId: mesh element ID
7375 element's maximum length value
7378 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7379 ftype = SMESH.FT_MaxElementLength3D
7381 ftype = SMESH.FT_MaxElementLength2D
7382 return self.FunctorValue(ftype, elemId)
7384 def GetAspectRatio(self, elemId):
7386 Get aspect ratio of 2D or 3D element.
7389 elemId: mesh element ID
7392 element's aspect ratio value
7395 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7396 ftype = SMESH.FT_AspectRatio3D
7398 ftype = SMESH.FT_AspectRatio
7399 return self.FunctorValue(ftype, elemId)
7401 def GetWarping(self, elemId):
7403 Get warping angle of 2D element.
7406 elemId: mesh element ID
7409 element's warping angle value
7412 return self.FunctorValue(SMESH.FT_Warping, elemId)
7414 def GetMinimumAngle(self, elemId):
7416 Get minimum angle of 2D element.
7419 elemId: mesh element ID
7422 element's minimum angle value
7425 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7427 def GetTaper(self, elemId):
7429 Get taper of 2D element.
7432 elemId: mesh element ID
7435 element's taper value
7438 return self.FunctorValue(SMESH.FT_Taper, elemId)
7440 def GetSkew(self, elemId):
7442 Get skew of 2D element.
7445 elemId: mesh element ID
7448 element's skew value
7451 return self.FunctorValue(SMESH.FT_Skew, elemId)
7453 def GetMinMax(self, funType, meshPart=None):
7455 Return minimal and maximal value of a given functor.
7458 funType (SMESH.FunctorType): a functor type.
7459 Note that not all items of :class:`SMESH.FunctorType` corresponds
7460 to numerical functors.
7461 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7467 unRegister = genObjUnRegister()
7468 if isinstance( meshPart, list ):
7469 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7470 unRegister.set( meshPart )
7471 if isinstance( meshPart, Mesh ):
7472 meshPart = meshPart.mesh
7473 fun = self.GetFunctor( funType )
7476 if hasattr( meshPart, "SetMesh" ):
7477 meshPart.SetMesh( self.mesh ) # set mesh to filter
7478 hist = fun.GetLocalHistogram( 1, False, meshPart )
7480 hist = fun.GetHistogram( 1, False )
7482 return hist[0].min, hist[0].max
7485 pass # end of Mesh class
7488 class meshProxy(SMESH._objref_SMESH_Mesh):
7490 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7491 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7493 def __init__(self,*args):
7494 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7495 def __deepcopy__(self, memo=None):
7496 new = self.__class__(self)
7498 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7499 if len( args ) == 3:
7500 args += SMESH.ALL_NODES, True
7501 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7502 def ExportToMEDX(self, *args): # function removed
7503 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7504 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7505 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7506 def ExportToMED(self, *args): # function removed
7507 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7508 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7510 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7512 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7513 def ExportPartToMED(self, *args): # 'version' parameter removed
7514 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7515 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7516 def ExportMED(self, *args): # signature of method changed
7517 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7519 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7521 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7522 def ExportUNV(self, *args): # renumber arg added
7523 if len( args ) == 1:
7525 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
7526 def ExportDAT(self, *args): # renumber arg added
7527 if len( args ) == 1:
7529 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
7531 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7534 class submeshProxy(SMESH._objref_SMESH_subMesh):
7537 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7539 def __init__(self,*args):
7540 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7542 def __deepcopy__(self, memo=None):
7543 new = self.__class__(self)
7546 def Compute(self,refresh=False):
7548 Compute the sub-mesh and return the status of the computation
7551 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7556 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7557 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7561 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7563 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7565 if salome.sg.hasDesktop():
7566 if refresh: salome.sg.updateObjBrowser()
7571 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7574 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7576 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7577 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7580 def __init__(self,*args):
7581 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7583 def __getattr__(self, name ): # method called if an attribute not found
7584 if not self.mesh: # look for name() method in Mesh class
7585 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7586 if hasattr( self.mesh, name ):
7587 return getattr( self.mesh, name )
7588 if name == "ExtrusionAlongPathObjX":
7589 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7590 print("meshEditor: attribute '%s' NOT FOUND" % name)
7592 def __deepcopy__(self, memo=None):
7593 new = self.__class__(self)
7595 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7596 if len( args ) == 1: args += False,
7597 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7598 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7599 if len( args ) == 2: args += False,
7600 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7601 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7602 if len( args ) == 1:
7603 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7604 NodesToKeep = args[1]
7605 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7606 unRegister = genObjUnRegister()
7608 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7609 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7610 if not isinstance( NodesToKeep, list ):
7611 NodesToKeep = [ NodesToKeep ]
7612 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7614 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7616 class Pattern(SMESH._objref_SMESH_Pattern):
7618 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7619 variables in some methods
7622 def LoadFromFile(self, patternTextOrFile ):
7623 text = patternTextOrFile
7624 if os.path.exists( text ):
7625 text = open( patternTextOrFile ).read()
7627 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7629 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7630 decrFun = lambda i: i-1
7631 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7632 theMesh.SetParameters(Parameters)
7633 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7635 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7636 decrFun = lambda i: i-1
7637 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7638 theMesh.SetParameters(Parameters)
7639 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7641 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7642 if isinstance( mesh, Mesh ):
7643 mesh = mesh.GetMesh()
7644 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7646 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7648 Registering the new proxy for Pattern
7653 Private class used to bind methods creating algorithms to the class Mesh
7656 def __init__(self, method):
7658 self.defaultAlgoType = ""
7659 self.algoTypeToClass = {}
7660 self.method = method
7662 def add(self, algoClass):
7664 Store a python class of algorithm
7666 if inspect.isclass(algoClass) and \
7667 hasattr( algoClass, "algoType"):
7668 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7669 if not self.defaultAlgoType and \
7670 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7671 self.defaultAlgoType = algoClass.algoType
7672 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7674 def copy(self, mesh):
7676 Create a copy of self and assign mesh to the copy
7679 other = algoCreator( self.method )
7680 other.defaultAlgoType = self.defaultAlgoType
7681 other.algoTypeToClass = self.algoTypeToClass
7685 def __call__(self,algo="",geom=0,*args):
7687 Create an instance of algorithm
7691 if isinstance( algo, str ):
7693 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7694 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7699 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7701 elif not algoType and isinstance( geom, str ):
7706 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7708 elif isinstance( arg, str ) and not algoType:
7711 import traceback, sys
7712 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7713 sys.stderr.write( msg + '\n' )
7714 tb = traceback.extract_stack(None,2)
7715 traceback.print_list( [tb[0]] )
7717 algoType = self.defaultAlgoType
7718 if not algoType and self.algoTypeToClass:
7719 algoType = sorted( self.algoTypeToClass.keys() )[0]
7720 if algoType in self.algoTypeToClass:
7721 #print("Create algo",algoType)
7722 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7723 raise RuntimeError( "No class found for algo type %s" % algoType)
7726 class hypMethodWrapper:
7728 Private class used to substitute and store variable parameters of hypotheses.
7731 def __init__(self, hyp, method):
7733 self.method = method
7734 #print("REBIND:", method.__name__)
7737 def __call__(self,*args):
7739 call a method of hypothesis with calling SetVarParameter() before
7743 return self.method( self.hyp, *args ) # hypothesis method with no args
7745 #print("MethWrapper.__call__", self.method.__name__, args)
7747 parsed = ParseParameters(*args) # replace variables with their values
7748 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7749 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7750 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7751 # maybe there is a replaced string arg which is not variable
7752 result = self.method( self.hyp, *args )
7753 except ValueError as detail: # raised by ParseParameters()
7755 result = self.method( self.hyp, *args )
7756 except omniORB.CORBA.BAD_PARAM:
7757 raise ValueError(detail) # wrong variable name
7762 class genObjUnRegister:
7764 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7767 def __init__(self, genObj=None):
7768 self.genObjList = []
7772 def set(self, genObj):
7773 "Store one or a list of of SALOME.GenericObj'es"
7774 if isinstance( genObj, list ):
7775 self.genObjList.extend( genObj )
7777 self.genObjList.append( genObj )
7781 for genObj in self.genObjList:
7782 if genObj and hasattr( genObj, "UnRegister" ):
7785 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7787 Bind methods creating mesher plug-ins to the Mesh class
7790 # print("pluginName: ", pluginName)
7791 pluginBuilderName = pluginName + "Builder"
7793 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7794 except Exception as e:
7795 from salome_utils import verbose
7796 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7798 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7799 plugin = eval( pluginBuilderName )
7800 # print(" plugin:" , str(plugin))
7802 # add methods creating algorithms to Mesh
7803 for k in dir( plugin ):
7804 if k[0] == '_': continue
7805 algo = getattr( plugin, k )
7806 #print(" algo:", str(algo))
7807 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7808 #print(" meshMethod:" , str(algo.meshMethod))
7809 if not hasattr( Mesh, algo.meshMethod ):
7810 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7812 _mmethod = getattr( Mesh, algo.meshMethod )
7813 if hasattr( _mmethod, "add" ):