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`
790 if isinstance( mesh, Mesh ):
791 meshPart = mesh.GetMesh()
792 mesh = SMESH._objref_SMESH_Gen.CreateDualMesh(self, mesh, meshName)
793 return Mesh(self, self.geompyD, mesh)
796 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
798 Create a mesh by copying a part of another mesh.
801 meshPart: a part of mesh to copy, either
802 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
803 To copy nodes or elements not forming any mesh object,
804 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
805 meshName: a name of the new mesh
806 toCopyGroups: to create in the new mesh groups the copied elements belongs to
807 toKeepIDs: to preserve order of the copied elements or not
810 an instance of class :class:`Mesh`
813 if isinstance( meshPart, Mesh ):
814 meshPart = meshPart.GetMesh()
815 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
816 return Mesh(self, self.geompyD, mesh)
818 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
819 toReuseHypotheses=True, toCopyElements=True):
821 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
822 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
823 To facilitate and speed up the operation, consider using
824 "Set presentation parameters and sub-shapes from arguments" option in
825 a dialog of geometrical operation used to create the new geometry.
828 sourceMesh: the mesh to copy definition of.
829 newGeom: the new geometry.
830 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
831 toCopyGroups: to create groups in the new mesh.
832 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
833 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
836 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
837 *invalidEntries* are study entries of objects whose
838 counterparts are not found in the *newGeom*, followed by entries
839 of mesh sub-objects that are invalid because they depend on a not found
842 if isinstance( sourceMesh, Mesh ):
843 sourceMesh = sourceMesh.GetMesh()
845 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
846 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
850 return ( ok, Mesh(self, self.geompyD, newMesh),
851 newGroups, newSubMeshes, newHypotheses, invalidEntries )
853 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
855 Return IDs of sub-shapes
858 theMainObject (GEOM.GEOM_Object): a shape
859 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
861 the list of integer values
864 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
866 def GetPattern(self):
868 Create a pattern mapper.
871 an instance of :class:`SMESH.SMESH_Pattern`
873 :ref:`Example of Patterns usage <tui_pattern_mapping>`
876 return SMESH._objref_SMESH_Gen.GetPattern(self)
878 def SetBoundaryBoxSegmentation(self, nbSegments):
880 Set number of segments per diagonal of boundary box of geometry, by which
881 default segment length of appropriate 1D hypotheses is defined in GUI.
885 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
887 # Filtering. Auxiliary functions:
888 # ------------------------------
890 def GetEmptyCriterion(self):
892 Create an empty criterion
895 :class:`SMESH.Filter.Criterion`
898 Type = self.EnumToLong(FT_Undefined)
899 Compare = self.EnumToLong(FT_Undefined)
903 UnaryOp = self.EnumToLong(FT_Undefined)
904 BinaryOp = self.EnumToLong(FT_Undefined)
907 Precision = -1 ##@1e-07
908 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
909 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
911 def GetCriterion(self,elementType,
913 Compare = FT_EqualTo,
915 UnaryOp=FT_Undefined,
916 BinaryOp=FT_Undefined,
919 Create a criterion by the given parameters
920 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
923 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
924 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
925 Note that the items starting from FT_LessThan are not suitable for *CritType*.
926 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
927 Threshold: the threshold value (range of ids as string, shape, numeric)
928 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
929 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
931 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
932 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
935 :class:`SMESH.Filter.Criterion`
937 Example: :ref:`combining_filters`
940 if not CritType in SMESH.FunctorType._items:
941 raise TypeError("CritType should be of SMESH.FunctorType")
942 aCriterion = self.GetEmptyCriterion()
943 aCriterion.TypeOfElement = elementType
944 aCriterion.Type = self.EnumToLong(CritType)
945 aCriterion.Tolerance = Tolerance
947 aThreshold = Threshold
949 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
950 aCriterion.Compare = self.EnumToLong(Compare)
951 elif Compare == "=" or Compare == "==":
952 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
954 aCriterion.Compare = self.EnumToLong(FT_LessThan)
956 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
957 elif Compare != FT_Undefined:
958 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
961 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
962 FT_BelongToCylinder, FT_LyingOnGeom]:
963 # Check that Threshold is GEOM object
964 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
965 aCriterion.ThresholdStr = GetName(aThreshold)
966 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
967 if not aCriterion.ThresholdID:
968 name = aCriterion.ThresholdStr
970 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
971 geompyD = aThreshold.GetGen()
972 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
973 # or a name of GEOM object
974 elif isinstance( aThreshold, str ):
975 aCriterion.ThresholdStr = aThreshold
977 raise TypeError("The Threshold should be a shape.")
978 if isinstance(UnaryOp,float):
979 aCriterion.Tolerance = UnaryOp
980 UnaryOp = FT_Undefined
982 elif CritType == FT_BelongToMeshGroup:
983 # Check that Threshold is a group
984 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
985 if aThreshold.GetType() != elementType:
986 raise ValueError("Group type mismatches Element type")
987 aCriterion.ThresholdStr = aThreshold.GetName()
988 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
989 study = salome.myStudy
991 so = study.FindObjectIOR( aCriterion.ThresholdID )
995 aCriterion.ThresholdID = entry
997 raise TypeError("The Threshold should be a Mesh Group")
998 elif CritType == FT_RangeOfIds:
999 # Check that Threshold is string
1000 if isinstance(aThreshold, str):
1001 aCriterion.ThresholdStr = aThreshold
1003 raise TypeError("The Threshold should be a string.")
1004 elif CritType == FT_CoplanarFaces:
1005 # Check the Threshold
1006 if isinstance(aThreshold, int):
1007 aCriterion.ThresholdID = str(aThreshold)
1008 elif isinstance(aThreshold, str):
1009 ID = int(aThreshold)
1011 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
1012 aCriterion.ThresholdID = aThreshold
1014 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1015 elif CritType == FT_ConnectedElements:
1016 # Check the Threshold
1017 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1018 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1019 if not aCriterion.ThresholdID:
1020 name = aThreshold.GetName()
1022 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1023 geompyD = aThreshold.GetGen()
1024 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
1025 elif isinstance(aThreshold, int): # node id
1026 aCriterion.Threshold = aThreshold
1027 elif isinstance(aThreshold, list): # 3 point coordinates
1028 if len( aThreshold ) < 3:
1029 raise ValueError("too few point coordinates, must be 3")
1030 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1031 elif isinstance(aThreshold, str):
1032 if aThreshold.isdigit():
1033 aCriterion.Threshold = aThreshold # node id
1035 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1037 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1038 "or a list of point coordinates and not '%s'"%aThreshold)
1039 elif CritType == FT_ElemGeomType:
1040 # Check the Threshold
1042 aCriterion.Threshold = self.EnumToLong(aThreshold)
1043 assert( aThreshold in SMESH.GeometryType._items )
1045 if isinstance(aThreshold, int):
1046 aCriterion.Threshold = aThreshold
1048 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1051 elif CritType == FT_EntityType:
1052 # Check the Threshold
1054 aCriterion.Threshold = self.EnumToLong(aThreshold)
1055 assert( aThreshold in SMESH.EntityType._items )
1057 if isinstance(aThreshold, int):
1058 aCriterion.Threshold = aThreshold
1060 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1064 elif CritType == FT_GroupColor:
1065 # Check the Threshold
1067 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1069 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1071 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1072 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1073 FT_BareBorderFace, FT_BareBorderVolume,
1074 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1075 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1076 # At this point the Threshold is unnecessary
1077 if aThreshold == FT_LogicalNOT:
1078 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1079 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1080 aCriterion.BinaryOp = aThreshold
1084 aThreshold = float(aThreshold)
1085 aCriterion.Threshold = aThreshold
1087 raise TypeError("The Threshold should be a number.")
1090 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1091 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1093 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1094 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1096 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1097 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1099 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1100 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1104 def GetFilter(self,elementType,
1105 CritType=FT_Undefined,
1108 UnaryOp=FT_Undefined,
1112 Create a filter with the given parameters
1115 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1116 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1117 Note that the items starting from FT_LessThan are not suitable for CritType.
1118 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1119 Threshold: the threshold value (range of ids as string, shape, numeric)
1120 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1121 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1122 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1123 mesh: the mesh to initialize the filter with
1126 :class:`SMESH.Filter`
1129 See :doc:`Filters usage examples <tui_filters>`
1132 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1133 aFilterMgr = self.CreateFilterManager()
1134 aFilter = aFilterMgr.CreateFilter()
1136 aCriteria.append(aCriterion)
1137 aFilter.SetCriteria(aCriteria)
1139 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1140 else : aFilter.SetMesh( mesh )
1141 aFilterMgr.UnRegister()
1144 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1146 Create a filter from criteria
1149 criteria: a list of :class:`SMESH.Filter.Criterion`
1150 binOp: binary operator used when binary operator of criteria is undefined
1153 :class:`SMESH.Filter`
1156 See :doc:`Filters usage examples <tui_filters>`
1159 for i in range( len( criteria ) - 1 ):
1160 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1161 criteria[i].BinaryOp = self.EnumToLong( binOp )
1162 aFilterMgr = self.CreateFilterManager()
1163 aFilter = aFilterMgr.CreateFilter()
1164 aFilter.SetCriteria(criteria)
1165 aFilterMgr.UnRegister()
1168 def GetFunctor(self,theCriterion):
1170 Create a numerical functor by its type
1173 theCriterion (SMESH.FunctorType): functor type.
1174 Note that not all items correspond to numerical functors.
1177 :class:`SMESH.NumericalFunctor`
1180 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1182 aFilterMgr = self.CreateFilterManager()
1184 if theCriterion == FT_AspectRatio:
1185 functor = aFilterMgr.CreateAspectRatio()
1186 elif theCriterion == FT_AspectRatio3D:
1187 functor = aFilterMgr.CreateAspectRatio3D()
1188 elif theCriterion == FT_Warping:
1189 functor = aFilterMgr.CreateWarping()
1190 elif theCriterion == FT_MinimumAngle:
1191 functor = aFilterMgr.CreateMinimumAngle()
1192 elif theCriterion == FT_Taper:
1193 functor = aFilterMgr.CreateTaper()
1194 elif theCriterion == FT_Skew:
1195 functor = aFilterMgr.CreateSkew()
1196 elif theCriterion == FT_Area:
1197 functor = aFilterMgr.CreateArea()
1198 elif theCriterion == FT_Volume3D:
1199 functor = aFilterMgr.CreateVolume3D()
1200 elif theCriterion == FT_MaxElementLength2D:
1201 functor = aFilterMgr.CreateMaxElementLength2D()
1202 elif theCriterion == FT_MaxElementLength3D:
1203 functor = aFilterMgr.CreateMaxElementLength3D()
1204 elif theCriterion == FT_MultiConnection:
1205 functor = aFilterMgr.CreateMultiConnection()
1206 elif theCriterion == FT_MultiConnection2D:
1207 functor = aFilterMgr.CreateMultiConnection2D()
1208 elif theCriterion == FT_Length:
1209 functor = aFilterMgr.CreateLength()
1210 elif theCriterion == FT_Length2D:
1211 functor = aFilterMgr.CreateLength2D()
1212 elif theCriterion == FT_Length3D:
1213 functor = aFilterMgr.CreateLength3D()
1214 elif theCriterion == FT_Deflection2D:
1215 functor = aFilterMgr.CreateDeflection2D()
1216 elif theCriterion == FT_NodeConnectivityNumber:
1217 functor = aFilterMgr.CreateNodeConnectivityNumber()
1218 elif theCriterion == FT_BallDiameter:
1219 functor = aFilterMgr.CreateBallDiameter()
1221 print("Error: given parameter is not numerical functor type.")
1222 aFilterMgr.UnRegister()
1225 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1230 theHType (string): mesh hypothesis type
1231 theLibName (string): mesh plug-in library name
1234 created hypothesis instance
1236 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1238 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1241 # wrap hypothesis methods
1242 for meth_name in dir( hyp.__class__ ):
1243 if not meth_name.startswith("Get") and \
1244 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1245 method = getattr ( hyp.__class__, meth_name )
1246 if callable(method):
1247 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1251 def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1253 Create hypothesis initialized according to parameters
1256 hypType (string): hypothesis type
1257 libName (string): plug-in library name
1258 mesh: optional mesh by which a hypotheses can initialize self
1259 shape: optional geometry by size of which a hypotheses can initialize self
1260 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1263 created hypothesis instance
1265 if isinstance( mesh, Mesh ):
1266 mesh = mesh.GetMesh()
1267 if isinstance( initParams, (bool,int)):
1268 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1269 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1270 mesh, shape, initParams )
1272 def GetMeshInfo(self, obj):
1274 Get the mesh statistic.
1277 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1280 if isinstance( obj, Mesh ):
1283 if hasattr(obj, "GetMeshInfo"):
1284 values = obj.GetMeshInfo()
1285 for i in range(SMESH.Entity_Last._v):
1286 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1290 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1292 Get minimum distance between two objects
1294 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1295 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1298 src1 (SMESH.SMESH_IDSource): first source object
1299 src2 (SMESH.SMESH_IDSource): second source object
1300 id1 (int): node/element id from the first source
1301 id2 (int): node/element id from the second (or first) source
1302 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1303 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1306 minimum distance value
1309 :meth:`GetMinDistance`
1312 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1316 result = result.value
1319 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1321 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1323 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1324 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1327 src1 (SMESH.SMESH_IDSource): first source object
1328 src2 (SMESH.SMESH_IDSource): second source object
1329 id1 (int): node/element id from the first source
1330 id2 (int): node/element id from the second (or first) source
1331 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1332 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1335 :class:`SMESH.Measure` structure or None if input data is invalid
1340 if isinstance(src1, Mesh): src1 = src1.mesh
1341 if isinstance(src2, Mesh): src2 = src2.mesh
1342 if src2 is None and id2 != 0: src2 = src1
1343 if not hasattr(src1, "_narrow"): return None
1344 src1 = src1._narrow(SMESH.SMESH_IDSource)
1345 if not src1: return None
1346 unRegister = genObjUnRegister()
1349 e = m.GetMeshEditor()
1351 src1 = e.MakeIDSource([id1], SMESH.FACE)
1353 src1 = e.MakeIDSource([id1], SMESH.NODE)
1354 unRegister.set( src1 )
1356 if hasattr(src2, "_narrow"):
1357 src2 = src2._narrow(SMESH.SMESH_IDSource)
1358 if src2 and id2 != 0:
1360 e = m.GetMeshEditor()
1362 src2 = e.MakeIDSource([id2], SMESH.FACE)
1364 src2 = e.MakeIDSource([id2], SMESH.NODE)
1365 unRegister.set( src2 )
1368 aMeasurements = self.CreateMeasurements()
1369 unRegister.set( aMeasurements )
1370 result = aMeasurements.MinDistance(src1, src2)
1373 def BoundingBox(self, objects):
1375 Get bounding box of the specified object(s)
1378 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1381 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1384 :meth:`GetBoundingBox`
1387 result = self.GetBoundingBox(objects)
1391 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1394 def GetBoundingBox(self, objects):
1396 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1399 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1402 :class:`SMESH.Measure` structure
1408 if isinstance(objects, tuple):
1409 objects = list(objects)
1410 if not isinstance(objects, list):
1414 if isinstance(o, Mesh):
1415 srclist.append(o.mesh)
1416 elif hasattr(o, "_narrow"):
1417 src = o._narrow(SMESH.SMESH_IDSource)
1418 if src: srclist.append(src)
1421 aMeasurements = self.CreateMeasurements()
1422 result = aMeasurements.BoundingBox(srclist)
1423 aMeasurements.UnRegister()
1426 def GetLength(self, obj):
1428 Get sum of lengths of all 1D elements in the mesh object.
1431 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1434 sum of lengths of all 1D elements
1437 if isinstance(obj, Mesh): obj = obj.mesh
1438 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1439 aMeasurements = self.CreateMeasurements()
1440 value = aMeasurements.Length(obj)
1441 aMeasurements.UnRegister()
1444 def GetArea(self, obj):
1446 Get sum of areas of all 2D elements in the mesh object.
1449 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1452 sum of areas of all 2D elements
1455 if isinstance(obj, Mesh): obj = obj.mesh
1456 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1457 aMeasurements = self.CreateMeasurements()
1458 value = aMeasurements.Area(obj)
1459 aMeasurements.UnRegister()
1462 def GetVolume(self, obj):
1464 Get sum of volumes of all 3D elements in the mesh object.
1467 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1470 sum of volumes of all 3D elements
1473 if isinstance(obj, Mesh): obj = obj.mesh
1474 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1475 aMeasurements = self.CreateMeasurements()
1476 value = aMeasurements.Volume(obj)
1477 aMeasurements.UnRegister()
1480 def GetGravityCenter(self, obj):
1482 Get gravity center of all nodes of a mesh object.
1485 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1488 Three components of the gravity center (x,y,z)
1491 :meth:`Mesh.BaryCenter`
1493 if isinstance(obj, Mesh): obj = obj.mesh
1494 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1495 aMeasurements = self.CreateMeasurements()
1496 pointStruct = aMeasurements.GravityCenter(obj)
1497 aMeasurements.UnRegister()
1498 return pointStruct.x, pointStruct.y, pointStruct.z
1500 def GetAngle(self, p1, p2, p3 ):
1502 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1505 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1511 if isinstance( p1, list ): p1 = PointStruct(*p1)
1512 if isinstance( p2, list ): p2 = PointStruct(*p2)
1513 if isinstance( p3, list ): p3 = PointStruct(*p3)
1515 aMeasurements = self.CreateMeasurements()
1516 angle = aMeasurements.Angle(p1,p2,p3)
1517 aMeasurements.UnRegister()
1522 pass # end of class smeshBuilder
1525 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1526 """Registering the new proxy for SMESH.SMESH_Gen"""
1529 def New( instance=None, instanceGeom=None):
1531 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1532 interface to create or load meshes.
1537 salome.salome_init()
1538 from salome.smesh import smeshBuilder
1539 smesh = smeshBuilder.New()
1542 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1543 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1545 :class:`smeshBuilder` instance
1550 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1552 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1557 smeshInst = smeshBuilder()
1558 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1559 smeshInst.init_smesh(instanceGeom)
1563 # Public class: Mesh
1564 # ==================
1567 class Mesh(metaclass = MeshMeta):
1569 This class allows defining and managing a mesh.
1570 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1571 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1572 new nodes and elements and by changing the existing entities), to get information
1573 about a mesh and to export a mesh in different formats.
1580 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1585 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1586 sets the GUI name of this mesh to *name*.
1589 smeshpyD: an instance of smeshBuilder class
1590 geompyD: an instance of geomBuilder class
1591 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1592 name: Study name of the mesh
1595 self.smeshpyD = smeshpyD
1596 self.geompyD = geompyD
1601 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1604 # publish geom of mesh (issue 0021122)
1605 if not self.geom.GetStudyEntry():
1609 geo_name = name + " shape"
1611 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1612 geompyD.addToStudy( self.geom, geo_name )
1613 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1615 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1618 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1620 self.smeshpyD.SetName(self.mesh, name)
1622 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1625 self.geom = self.mesh.GetShapeToMesh()
1627 self.editor = self.mesh.GetMeshEditor()
1628 self.functors = [None] * SMESH.FT_Undefined._v
1630 # set self to algoCreator's
1631 for attrName in dir(self):
1632 attr = getattr( self, attrName )
1633 if isinstance( attr, algoCreator ):
1634 setattr( self, attrName, attr.copy( self ))
1641 Destructor. Clean-up resources
1644 #self.mesh.UnRegister()
1648 def SetMesh(self, theMesh):
1650 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1653 theMesh: a :class:`SMESH.SMESH_Mesh` object
1655 # do not call Register() as this prevents mesh servant deletion at closing study
1656 #if self.mesh: self.mesh.UnRegister()
1659 #self.mesh.Register()
1660 self.geom = self.mesh.GetShapeToMesh()
1664 if salome.sg.hasDesktop():
1665 so = salome.ObjectToSObject( self.geom )
1666 comp = so.GetFatherComponent()
1667 if comp.ComponentDataType() == "SHAPERSTUDY":
1668 import shaperBuilder
1669 self.geompyD = shaperBuilder.New()
1672 if not self.geompyD:
1673 self.geompyD = self.geom.GetGen()
1678 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1681 a :class:`SMESH.SMESH_Mesh` object
1686 def GetEngine(self):
1688 Return a smeshBuilder instance created this mesh
1690 return self.smeshpyD
1692 def GetGeomEngine(self):
1694 Return a geomBuilder instance
1700 Get the name of the mesh
1703 the name of the mesh as a string
1706 name = GetName(self.GetMesh())
1709 def SetName(self, name):
1711 Set a name to the mesh
1714 name: a new name of the mesh
1717 self.smeshpyD.SetName(self.GetMesh(), name)
1719 def GetSubMesh(self, geom, name):
1721 Get a sub-mesh object associated to a *geom* geometrical object.
1724 geom: a geometrical object (shape)
1725 name: a name for the sub-mesh in the Object Browser
1728 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1729 which lies on the given shape
1732 A sub-mesh is implicitly created when a sub-shape is specified at
1733 creating an algorithm, for example::
1735 algo1D = mesh.Segment(geom=Edge_1)
1737 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1738 The created sub-mesh can be retrieved from the algorithm::
1740 submesh = algo1D.GetSubMesh()
1743 AssureGeomPublished( self, geom, name )
1744 submesh = self.mesh.GetSubMesh( geom, name )
1749 Return the shape associated to the mesh
1757 def SetShape(self, geom):
1759 Associate the given shape to the mesh (entails the recreation of the mesh)
1762 geom: the shape to be meshed (GEOM_Object)
1765 self.mesh = self.smeshpyD.CreateMesh(geom)
1767 def HasShapeToMesh(self):
1769 Return ``True`` if this mesh is based on geometry
1771 return self.mesh.HasShapeToMesh()
1775 Load mesh from the study after opening the study
1779 def IsReadyToCompute(self, theSubObject):
1781 Return true if the hypotheses are defined well
1784 theSubObject: a sub-shape of a mesh shape
1790 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1792 def GetAlgoState(self, theSubObject):
1794 Return errors of hypotheses definition.
1795 The list of errors is empty if everything is OK.
1798 theSubObject: a sub-shape of a mesh shape
1804 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1806 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1808 Return a geometrical object on which the given element was built.
1809 The returned geometrical object, if not nil, is either found in the
1810 study or published by this method with the given name
1813 theElementID: the id of the mesh element
1814 theGeomName: the user-defined name of the geometrical object
1817 GEOM.GEOM_Object instance
1820 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1822 def MeshDimension(self):
1824 Return the mesh dimension depending on the dimension of the underlying shape
1825 or, if the mesh is not based on any shape, basing on deimension of elements
1828 mesh dimension as an integer value [0,3]
1831 if self.mesh.HasShapeToMesh():
1832 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1833 if len( shells ) > 0 :
1835 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1837 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1842 if self.NbVolumes() > 0: return 3
1843 if self.NbFaces() > 0: return 2
1844 if self.NbEdges() > 0: return 1
1847 def Evaluate(self, geom=0):
1849 Evaluate size of prospective mesh on a shape
1852 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1853 To know predicted number of e.g. edges, inquire it this way::
1855 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1858 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1860 geom = self.mesh.GetShapeToMesh()
1863 return self.smeshpyD.Evaluate(self.mesh, geom)
1866 def Compute(self, geom=0, discardModifs=False, refresh=False):
1868 Compute the mesh and return the status of the computation
1871 geom: geomtrical shape on which mesh data should be computed
1872 discardModifs: if True and the mesh has been edited since
1873 a last total re-compute and that may prevent successful partial re-compute,
1874 then the mesh is cleaned before Compute()
1875 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1881 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1882 geom = self.mesh.GetShapeToMesh()
1885 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1887 ok = self.smeshpyD.Compute(self.mesh, geom)
1888 except SALOME.SALOME_Exception as ex:
1889 print("Mesh computation failed, exception caught:")
1890 print(" ", ex.details.text)
1893 print("Mesh computation failed, exception caught:")
1894 traceback.print_exc()
1898 # Treat compute errors
1899 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1901 for err in computeErrors:
1902 if self.mesh.HasShapeToMesh():
1903 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1905 stdErrors = ["OK", #COMPERR_OK
1906 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1907 "std::exception", #COMPERR_STD_EXCEPTION
1908 "OCC exception", #COMPERR_OCC_EXCEPTION
1909 "..", #COMPERR_SLM_EXCEPTION
1910 "Unknown exception", #COMPERR_EXCEPTION
1911 "Memory allocation problem", #COMPERR_MEMORY_PB
1912 "Algorithm failed", #COMPERR_ALGO_FAILED
1913 "Unexpected geometry", #COMPERR_BAD_SHAPE
1914 "Warning", #COMPERR_WARNING
1915 "Computation cancelled",#COMPERR_CANCELED
1916 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1918 if err.code < len(stdErrors): errText = stdErrors[err.code]
1920 errText = "code %s" % -err.code
1921 if errText: errText += ". "
1922 errText += err.comment
1923 if allReasons: allReasons += "\n"
1925 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1927 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1931 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1933 if err.isGlobalAlgo:
1941 reason = '%s %sD algorithm is missing' % (glob, dim)
1942 elif err.state == HYP_MISSING:
1943 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1944 % (glob, dim, name, dim))
1945 elif err.state == HYP_NOTCONFORM:
1946 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1947 elif err.state == HYP_BAD_PARAMETER:
1948 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1949 % ( glob, dim, name ))
1950 elif err.state == HYP_BAD_GEOMETRY:
1951 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1952 'geometry' % ( glob, dim, name ))
1953 elif err.state == HYP_HIDDEN_ALGO:
1954 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1955 'algorithm of upper dimension generating %sD mesh'
1956 % ( glob, dim, name, glob, dim ))
1958 reason = ("For unknown reason. "
1959 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1961 if allReasons: allReasons += "\n"
1962 allReasons += "- " + reason
1964 if not ok or allReasons != "":
1965 msg = '"' + GetName(self.mesh) + '"'
1966 if ok: msg += " has been computed with warnings"
1967 else: msg += " has not been computed"
1968 if allReasons != "": msg += ":"
1974 if salome.sg.hasDesktop():
1975 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1976 if refresh: salome.sg.updateObjBrowser()
1980 def GetComputeErrors(self, shape=0 ):
1982 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1986 shape = self.mesh.GetShapeToMesh()
1987 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1989 def GetSubShapeName(self, subShapeID ):
1991 Return a name of a sub-shape by its ID.
1992 Possible variants (for *subShapeID* == 3):
1994 - **"Face_12"** - published sub-shape
1995 - **FACE #3** - not published sub-shape
1996 - **sub-shape #3** - invalid sub-shape ID
1997 - **#3** - error in this function
2000 subShapeID: a unique ID of a sub-shape
2003 a string describing the sub-shape
2007 if not self.mesh.HasShapeToMesh():
2011 mainIOR = salome.orb.object_to_string( self.GetShape() )
2013 mainSO = s.FindObjectIOR(mainIOR)
2016 shapeText = '"%s"' % mainSO.GetName()
2017 subIt = s.NewChildIterator(mainSO)
2019 subSO = subIt.Value()
2021 obj = subSO.GetObject()
2022 if not obj: continue
2023 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2026 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2029 if ids == subShapeID:
2030 shapeText = '"%s"' % subSO.GetName()
2033 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2035 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2037 shapeText = 'sub-shape #%s' % (subShapeID)
2039 shapeText = "#%s" % (subShapeID)
2042 def GetFailedShapes(self, publish=False):
2044 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2045 error of an algorithm
2048 publish: if *True*, the returned groups will be published in the study
2051 a list of GEOM groups each named after a failed algorithm
2056 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2057 for err in computeErrors:
2058 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2059 if not shape: continue
2060 if err.algoName in algo2shapes:
2061 algo2shapes[ err.algoName ].append( shape )
2063 algo2shapes[ err.algoName ] = [ shape ]
2067 for algoName, shapes in list(algo2shapes.items()):
2069 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2070 otherTypeShapes = []
2072 group = self.geompyD.CreateGroup( self.geom, groupType )
2073 for shape in shapes:
2074 if shape.GetShapeType() == shapes[0].GetShapeType():
2075 sameTypeShapes.append( shape )
2077 otherTypeShapes.append( shape )
2078 self.geompyD.UnionList( group, sameTypeShapes )
2080 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2082 group.SetName( algoName )
2083 groups.append( group )
2084 shapes = otherTypeShapes
2087 for group in groups:
2088 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2091 def GetMeshOrder(self):
2093 Return sub-mesh objects list in meshing order
2096 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2099 return self.mesh.GetMeshOrder()
2101 def SetMeshOrder(self, submeshes):
2103 Set priority of sub-meshes. It works in two ways:
2105 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2106 *several dimensions*, it sets the order in which the sub-meshes are computed.
2107 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2108 when looking for meshing parameters to apply to a sub-shape. To impose the
2109 order in which sub-meshes with uni-dimensional algorithms are computed,
2110 call **submesh.Compute()** in a desired order.
2113 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2115 Warning: the method is for setting the order for all sub-meshes at once:
2116 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2119 return self.mesh.SetMeshOrder(submeshes)
2121 def Clear(self, refresh=False):
2123 Remove all nodes and elements generated on geometry. Imported elements remain.
2126 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2130 if ( salome.sg.hasDesktop() ):
2131 if refresh: salome.sg.updateObjBrowser()
2133 def ClearSubMesh(self, geomId, refresh=False):
2135 Remove all nodes and elements of indicated shape
2138 geomId: the ID of a sub-shape to remove elements on
2139 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2142 self.mesh.ClearSubMesh(geomId)
2143 if salome.sg.hasDesktop():
2144 if refresh: salome.sg.updateObjBrowser()
2146 def AutomaticTetrahedralization(self, fineness=0):
2148 Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron
2151 fineness: [0.0,1.0] defines mesh fineness
2157 dim = self.MeshDimension()
2159 self.RemoveGlobalHypotheses()
2160 self.Segment().AutomaticLength(fineness)
2162 self.Triangle().LengthFromEdges()
2167 return self.Compute()
2169 def AutomaticHexahedralization(self, fineness=0):
2171 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2174 fineness: [0.0, 1.0] defines mesh fineness
2180 dim = self.MeshDimension()
2181 # assign the hypotheses
2182 self.RemoveGlobalHypotheses()
2183 self.Segment().AutomaticLength(fineness)
2190 return self.Compute()
2192 def AddHypothesis(self, hyp, geom=0):
2197 hyp: a hypothesis to assign
2198 geom: a subhape of mesh geometry
2201 :class:`SMESH.Hypothesis_Status`
2204 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2205 hyp, geom = geom, hyp
2206 if isinstance( hyp, Mesh_Algorithm ):
2207 hyp = hyp.GetAlgorithm()
2212 geom = self.mesh.GetShapeToMesh()
2215 if self.mesh.HasShapeToMesh():
2216 hyp_type = hyp.GetName()
2217 lib_name = hyp.GetLibName()
2218 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2219 # if checkAll and geom:
2220 # checkAll = geom.GetType() == 37
2222 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2224 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2225 status = self.mesh.AddHypothesis(geom, hyp)
2227 status = HYP_BAD_GEOMETRY, ""
2228 hyp_name = GetName( hyp )
2231 geom_name = geom.GetName()
2232 isAlgo = hyp._narrow( SMESH_Algo )
2233 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2236 def IsUsedHypothesis(self, hyp, geom):
2238 Return True if an algorithm or hypothesis is assigned to a given shape
2241 hyp: an algorithm or hypothesis to check
2242 geom: a subhape of mesh geometry
2248 if not hyp: # or not geom
2250 if isinstance( hyp, Mesh_Algorithm ):
2251 hyp = hyp.GetAlgorithm()
2253 hyps = self.GetHypothesisList(geom)
2255 if h.GetId() == hyp.GetId():
2259 def RemoveHypothesis(self, hyp, geom=0):
2261 Unassign a hypothesis
2264 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2265 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2268 :class:`SMESH.Hypothesis_Status`
2273 if isinstance( hyp, Mesh_Algorithm ):
2274 hyp = hyp.GetAlgorithm()
2280 if self.IsUsedHypothesis( hyp, shape ):
2281 return self.mesh.RemoveHypothesis( shape, hyp )
2282 hypName = GetName( hyp )
2283 geoName = GetName( shape )
2284 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2287 def GetHypothesisList(self, geom):
2289 Get the list of hypotheses added on a geometry
2292 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2295 the sequence of :class:`SMESH.SMESH_Hypothesis`
2298 return self.mesh.GetHypothesisList( geom )
2300 def RemoveGlobalHypotheses(self):
2302 Remove all global hypotheses
2305 current_hyps = self.mesh.GetHypothesisList( self.geom )
2306 for hyp in current_hyps:
2307 self.mesh.RemoveHypothesis( self.geom, hyp )
2311 def ExportMEDCoupling(self, *args, **kwargs):
2313 Export the mesh in a memory representation.
2316 auto_groups (boolean): parameter for creating/not creating
2317 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2318 the typical use is auto_groups=False.
2319 overwrite (boolean): parameter for overwriting/not overwriting the file
2320 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2321 to export instead of the mesh
2322 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2324 - 1D if all mesh nodes lie on OX coordinate axis, or
2325 - 2D if all mesh nodes lie on XOY coordinate plane, or
2326 - 3D in the rest cases.
2328 If *autoDimension* is *False*, the space dimension is always 3.
2329 fields: list of GEOM fields defined on the shape to mesh.
2330 geomAssocFields: each character of this string means a need to export a
2331 corresponding field; correspondence between fields and characters
2334 - 'v' stands for "_vertices_" field;
2335 - 'e' stands for "_edges_" field;
2336 - 'f' stands for "_faces_" field;
2337 - 's' stands for "_solids_" field.
2339 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2340 close to zero within a given tolerance, the coordinate is set to zero.
2341 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2342 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2344 auto_groups = args[0] if len(args) > 0 else False
2345 meshPart = args[1] if len(args) > 1 else None
2346 autoDimension = args[2] if len(args) > 2 else True
2347 fields = args[3] if len(args) > 3 else []
2348 geomAssocFields = args[4] if len(args) > 4 else ''
2349 z_tolerance = args[5] if len(args) > 5 else -1.
2350 saveNumbers = args[6] if len(args) > 6 else True
2351 # process keywords arguments
2352 auto_groups = kwargs.get("auto_groups", auto_groups)
2353 meshPart = kwargs.get("meshPart", meshPart)
2354 autoDimension = kwargs.get("autoDimension", autoDimension)
2355 fields = kwargs.get("fields", fields)
2356 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2357 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2358 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2360 # invoke engine's function
2361 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2362 unRegister = genObjUnRegister()
2363 if isinstance( meshPart, list ):
2364 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2365 unRegister.set( meshPart )
2367 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2368 self.mesh.SetParameters(Parameters)
2370 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2371 fields, geomAssocFields, z_tolerance,
2374 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2375 return medcoupling.MEDFileData.New(dab)
2377 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2379 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2380 return medcoupling.MEDFileMesh.New(dab)
2382 def ExportMED(self, *args, **kwargs):
2384 Export the mesh in a file in MED format
2385 allowing to overwrite the file if it exists or add the exported data to its contents
2388 fileName: is the file name
2389 auto_groups (boolean): parameter for creating/not creating
2390 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2391 the typical use is auto_groups=False.
2392 version (int): define the version (xy, where version is x.y.z) of MED file format.
2393 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2394 The rules of compatibility to write a mesh in an older version than
2395 the current version depend on the current version. For instance,
2396 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2397 or 3.2.1 or 3.3.1 formats.
2398 If the version is equal to -1, the version is not changed (default).
2399 overwrite (boolean): parameter for overwriting/not overwriting the file
2400 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2401 to export instead of the mesh
2402 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2404 - 1D if all mesh nodes lie on OX coordinate axis, or
2405 - 2D if all mesh nodes lie on XOY coordinate plane, or
2406 - 3D in the rest cases.
2408 If *autoDimension* is *False*, the space dimension is always 3.
2409 fields: list of GEOM fields defined on the shape to mesh.
2410 geomAssocFields: each character of this string means a need to export a
2411 corresponding field; correspondence between fields and characters
2414 - 'v' stands for "_vertices_" field;
2415 - 'e' stands for "_edges_" field;
2416 - 'f' stands for "_faces_" field;
2417 - 's' stands for "_solids_" field.
2419 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2420 close to zero within a given tolerance, the coordinate is set to zero.
2421 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2422 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2424 # process positional arguments
2425 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2427 auto_groups = args[1] if len(args) > 1 else False
2428 version = args[2] if len(args) > 2 else -1
2429 overwrite = args[3] if len(args) > 3 else True
2430 meshPart = args[4] if len(args) > 4 else None
2431 autoDimension = args[5] if len(args) > 5 else True
2432 fields = args[6] if len(args) > 6 else []
2433 geomAssocFields = args[7] if len(args) > 7 else ''
2434 z_tolerance = args[8] if len(args) > 8 else -1.
2435 saveNumbers = args[9] if len(args) > 9 else True
2436 # process keywords arguments
2437 auto_groups = kwargs.get("auto_groups", auto_groups)
2438 version = kwargs.get("version", version)
2439 version = kwargs.get("minor", version)
2440 overwrite = kwargs.get("overwrite", overwrite)
2441 meshPart = kwargs.get("meshPart", meshPart)
2442 autoDimension = kwargs.get("autoDimension", autoDimension)
2443 fields = kwargs.get("fields", fields)
2444 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2445 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2446 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2448 if isinstance( meshPart, Mesh):
2449 meshPart = meshPart.GetMesh()
2451 # invoke engine's function
2452 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2453 unRegister = genObjUnRegister()
2454 if isinstance( meshPart, list ):
2455 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2456 unRegister.set( meshPart )
2458 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2459 self.mesh.SetParameters(Parameters)
2461 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2462 version, overwrite, autoDimension,
2463 fields, geomAssocFields, z_tolerance, saveNumbers )
2465 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2467 def ExportDAT(self, f, meshPart=None, renumber=True):
2469 Export the mesh in a file in DAT format
2473 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2474 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2477 if meshPart or not renumber:
2478 unRegister = genObjUnRegister()
2479 if isinstance( meshPart, list ):
2480 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2481 unRegister.set( meshPart )
2482 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2484 self.mesh.ExportDAT( f, renumber )
2486 def ExportUNV(self, f, meshPart=None, renumber=True):
2488 Export the mesh in a file in UNV format
2492 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2493 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2496 if meshPart or not renumber:
2497 unRegister = genObjUnRegister()
2498 if isinstance( meshPart, list ):
2499 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2500 unRegister.set( meshPart )
2501 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2503 self.mesh.ExportUNV( f, renumber )
2505 def ExportSTL(self, f, ascii=1, meshPart=None):
2507 Export the mesh in a file in STL format
2511 ascii: defines the file encoding
2512 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2516 unRegister = genObjUnRegister()
2517 if isinstance( meshPart, list ):
2518 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2519 unRegister.set( meshPart )
2520 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2522 self.mesh.ExportSTL(f, ascii)
2524 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2526 Export the mesh in a file in CGNS format
2530 overwrite: boolean parameter for overwriting/not overwriting the file
2531 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2532 groupElemsByType: if True all elements of same entity type are exported at ones,
2533 else elements are exported in order of their IDs which can cause creation
2534 of multiple cgns sections
2537 unRegister = genObjUnRegister()
2538 if isinstance( meshPart, list ):
2539 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2540 unRegister.set( meshPart )
2541 if isinstance( meshPart, Mesh ):
2542 meshPart = meshPart.mesh
2544 meshPart = self.mesh
2545 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2547 def ExportGMF(self, f, meshPart=None):
2549 Export the mesh in a file in GMF format.
2550 GMF files must have .mesh extension for the ASCII format and .meshb for
2551 the bynary format. Other extensions are not allowed.
2555 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2558 unRegister = genObjUnRegister()
2559 if isinstance( meshPart, list ):
2560 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2561 unRegister.set( meshPart )
2562 if isinstance( meshPart, Mesh ):
2563 meshPart = meshPart.mesh
2565 meshPart = self.mesh
2566 self.mesh.ExportGMF(meshPart, f, True)
2568 def ExportToMED(self, *args, **kwargs):
2570 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2571 Export the mesh in a file in MED format
2572 allowing to overwrite the file if it exists or add the exported data to its contents
2575 fileName: the file name
2576 opt (boolean): parameter for creating/not creating
2577 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2578 overwrite: boolean parameter for overwriting/not overwriting the file
2579 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2581 - 1D if all mesh nodes lie on OX coordinate axis, or
2582 - 2D if all mesh nodes lie on XOY coordinate plane, or
2583 - 3D in the rest cases.
2585 If **autoDimension** is *False*, the space dimension is always 3.
2588 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2589 # process positional arguments
2590 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2592 auto_groups = args[1] if len(args) > 1 else False
2593 overwrite = args[2] if len(args) > 2 else True
2594 autoDimension = args[3] if len(args) > 3 else True
2595 # process keywords arguments
2596 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2597 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2598 overwrite = kwargs.get("overwrite", overwrite)
2599 autoDimension = kwargs.get("autoDimension", autoDimension)
2601 # invoke engine's function
2602 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2604 def ExportToMEDX(self, *args, **kwargs):
2606 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2607 Export the mesh in a file in MED format
2610 fileName: the file name
2611 opt (boolean): parameter for creating/not creating
2612 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2613 overwrite: boolean parameter for overwriting/not overwriting the file
2614 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2616 - 1D if all mesh nodes lie on OX coordinate axis, or
2617 - 2D if all mesh nodes lie on XOY coordinate plane, or
2618 - 3D in the rest cases.
2620 If **autoDimension** is *False*, the space dimension is always 3.
2623 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2624 # process positional arguments
2625 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2627 auto_groups = args[1] if len(args) > 1 else False
2628 overwrite = args[2] if len(args) > 2 else True
2629 autoDimension = args[3] if len(args) > 3 else True
2630 # process keywords arguments
2631 auto_groups = kwargs.get("auto_groups", auto_groups)
2632 overwrite = kwargs.get("overwrite", overwrite)
2633 autoDimension = kwargs.get("autoDimension", autoDimension)
2635 # invoke engine's function
2636 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2640 def Append(self, meshes, uniteIdenticalGroups = True,
2641 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2643 Append given meshes into this mesh.
2644 All groups of input meshes will be created in this mesh.
2647 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2648 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2649 mergeNodesAndElements: if True, equal nodes and elements are merged
2650 mergeTolerance: tolerance for merging nodes
2651 allGroups: forces creation of groups corresponding to every input mesh
2653 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2654 mergeNodesAndElements, mergeTolerance, allGroups,
2655 meshToAppendTo = self.GetMesh() )
2657 # Operations with groups:
2658 # ----------------------
2659 def CreateEmptyGroup(self, elementType, name):
2661 Create an empty standalone mesh group
2664 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2665 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2666 name: the name of the mesh group
2669 :class:`SMESH.SMESH_Group`
2672 return self.mesh.CreateGroup(elementType, name)
2674 def Group(self, grp, name=""):
2676 Create a mesh group based on the geometric object *grp*
2677 and give it a *name*.
2678 If *name* is not defined the name of the geometric group is used
2681 Works like :meth:`GroupOnGeom`.
2684 grp: a geometric group, a vertex, an edge, a face or a solid
2685 name: the name of the mesh group
2688 :class:`SMESH.SMESH_GroupOnGeom`
2691 return self.GroupOnGeom(grp, name)
2693 def GroupOnGeom(self, grp, name="", typ=None):
2695 Create a mesh group based on the geometrical object *grp*
2696 and give it a *name*.
2697 if *name* is not defined the name of the geometric group is used
2700 grp: a geometrical group, a vertex, an edge, a face or a solid
2701 name: the name of the mesh group
2702 typ: the type of elements in the group; either of
2703 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2704 automatically detected by the type of the geometry
2707 :class:`SMESH.SMESH_GroupOnGeom`
2710 AssureGeomPublished( self, grp, name )
2712 name = grp.GetName()
2714 typ = self._groupTypeFromShape( grp )
2715 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2717 def _groupTypeFromShape( self, shape ):
2719 Pivate method to get a type of group on geometry
2721 tgeo = str(shape.GetShapeType())
2722 if tgeo == "VERTEX":
2724 elif tgeo == "EDGE" or tgeo == "WIRE":
2726 elif tgeo == "FACE" or tgeo == "SHELL":
2728 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2730 elif tgeo == "COMPOUND":
2732 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2734 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2735 # simplification of access in geomBuilder: omniORB.registerObjref
2736 from SHAPERSTUDY_utils import getEngine
2739 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2741 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2742 return self._groupTypeFromShape( sub[0] )
2744 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2747 def GroupOnFilter(self, typ, name, filter):
2749 Create a mesh group with given *name* based on the *filter*.
2750 It is a special type of group dynamically updating it's contents during
2754 typ: the type of elements in the group; either of
2755 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2756 name: the name of the mesh group
2757 filter (SMESH.Filter): the filter defining group contents
2760 :class:`SMESH.SMESH_GroupOnFilter`
2763 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2765 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2767 Create a mesh group by the given ids of elements
2770 groupName: the name of the mesh group
2771 elementType: the type of elements in the group; either of
2772 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2773 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2776 :class:`SMESH.SMESH_Group`
2779 group = self.mesh.CreateGroup(elementType, groupName)
2780 if isinstance( elemIDs, Mesh ):
2781 elemIDs = elemIDs.GetMesh()
2782 if hasattr( elemIDs, "GetIDs" ):
2783 if hasattr( elemIDs, "SetMesh" ):
2784 elemIDs.SetMesh( self.GetMesh() )
2785 group.AddFrom( elemIDs )
2793 CritType=FT_Undefined,
2796 UnaryOp=FT_Undefined,
2799 Create a mesh group by the given conditions
2802 groupName: the name of the mesh group
2803 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2804 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2805 Note that the items starting from FT_LessThan are not suitable for CritType.
2806 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2807 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2808 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2809 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2810 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2813 :class:`SMESH.SMESH_GroupOnFilter`
2816 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2817 group = self.MakeGroupByCriterion(groupName, aCriterion)
2820 def MakeGroupByCriterion(self, groupName, Criterion):
2822 Create a mesh group by the given criterion
2825 groupName: the name of the mesh group
2826 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2829 :class:`SMESH.SMESH_GroupOnFilter`
2832 :meth:`smeshBuilder.GetCriterion`
2835 return self.MakeGroupByCriteria( groupName, [Criterion] )
2837 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2839 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2842 groupName: the name of the mesh group
2843 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2844 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2847 :class:`SMESH.SMESH_GroupOnFilter`
2850 :meth:`smeshBuilder.GetCriterion`
2853 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2854 group = self.MakeGroupByFilter(groupName, aFilter)
2857 def MakeGroupByFilter(self, groupName, theFilter):
2859 Create a mesh group by the given filter
2862 groupName (string): the name of the mesh group
2863 theFilter (SMESH.Filter): the filter
2866 :class:`SMESH.SMESH_GroupOnFilter`
2869 :meth:`smeshBuilder.GetFilter`
2872 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2873 #theFilter.SetMesh( self.mesh )
2874 #group.AddFrom( theFilter )
2875 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2878 def RemoveGroup(self, group):
2883 group (SMESH.SMESH_GroupBase): group to remove
2886 self.mesh.RemoveGroup(group)
2888 def RemoveGroupWithContents(self, group):
2890 Remove a group with its contents
2893 group (SMESH.SMESH_GroupBase): group to remove
2896 This operation can create gaps in numeration of nodes or elements.
2897 Call :meth:`RenumberElements` to remove the gaps.
2900 self.mesh.RemoveGroupWithContents(group)
2902 def GetGroups(self, elemType = SMESH.ALL):
2904 Get the list of groups existing in the mesh in the order of creation
2905 (starting from the oldest one)
2908 elemType (SMESH.ElementType): type of elements the groups contain;
2909 by default groups of elements of all types are returned
2912 a list of :class:`SMESH.SMESH_GroupBase`
2915 groups = self.mesh.GetGroups()
2916 if elemType == SMESH.ALL:
2920 if g.GetType() == elemType:
2921 typedGroups.append( g )
2928 Get the number of groups existing in the mesh
2931 the quantity of groups as an integer value
2934 return self.mesh.NbGroups()
2936 def GetGroupNames(self):
2938 Get the list of names of groups existing in the mesh
2944 groups = self.GetGroups()
2946 for group in groups:
2947 names.append(group.GetName())
2950 def GetGroupByName(self, name, elemType = None):
2952 Find groups by name and type
2955 name (string): name of the group of interest
2956 elemType (SMESH.ElementType): type of elements the groups contain;
2957 by default one group of any type is returned;
2958 if elemType == SMESH.ALL then all groups of any type are returned
2961 a list of :class:`SMESH.SMESH_GroupBase`
2965 for group in self.GetGroups():
2966 if group.GetName() == name:
2967 if elemType is None:
2969 if ( elemType == SMESH.ALL or
2970 group.GetType() == elemType ):
2971 groups.append( group )
2974 def UnionGroups(self, group1, group2, name):
2976 Produce a union of two groups.
2977 A new group is created. All mesh elements that are
2978 present in the initial groups are added to the new one
2981 group1 (SMESH.SMESH_GroupBase): a group
2982 group2 (SMESH.SMESH_GroupBase): another group
2985 instance of :class:`SMESH.SMESH_Group`
2988 return self.mesh.UnionGroups(group1, group2, name)
2990 def UnionListOfGroups(self, groups, name):
2992 Produce a union list of groups.
2993 New group is created. All mesh elements that are present in
2994 initial groups are added to the new one
2997 groups: list of :class:`SMESH.SMESH_GroupBase`
3000 instance of :class:`SMESH.SMESH_Group`
3002 return self.mesh.UnionListOfGroups(groups, name)
3004 def IntersectGroups(self, group1, group2, name):
3006 Prodice an intersection of two groups.
3007 A new group is created. All mesh elements that are common
3008 for the two initial groups are added to the new one.
3011 group1 (SMESH.SMESH_GroupBase): a group
3012 group2 (SMESH.SMESH_GroupBase): another group
3015 instance of :class:`SMESH.SMESH_Group`
3018 return self.mesh.IntersectGroups(group1, group2, name)
3020 def IntersectListOfGroups(self, groups, name):
3022 Produce an intersection of groups.
3023 New group is created. All mesh elements that are present in all
3024 initial groups simultaneously are added to the new one
3027 groups: a list of :class:`SMESH.SMESH_GroupBase`
3030 instance of :class:`SMESH.SMESH_Group`
3032 return self.mesh.IntersectListOfGroups(groups, name)
3034 def CutGroups(self, main_group, tool_group, name):
3036 Produce a cut of two groups.
3037 A new group is created. All mesh elements that are present in
3038 the main group but are not present in the tool group are added to the new one
3041 main_group (SMESH.SMESH_GroupBase): a group to cut from
3042 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3045 an instance of :class:`SMESH.SMESH_Group`
3048 return self.mesh.CutGroups(main_group, tool_group, name)
3050 def CutListOfGroups(self, main_groups, tool_groups, name):
3052 Produce a cut of groups.
3053 A new group is created. All mesh elements that are present in main groups
3054 but do not present in tool groups are added to the new one
3057 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3058 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3061 an instance of :class:`SMESH.SMESH_Group`
3064 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3066 def CreateDimGroup(self, groups, elemType, name,
3067 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3069 Create a standalone group of entities basing on nodes of other groups.
3072 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3073 elemType: a type of elements to include to the new group; either of
3074 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3075 name: a name of the new group.
3076 nbCommonNodes: a criterion of inclusion of an element to the new group
3077 basing on number of element nodes common with reference *groups*.
3078 Meaning of possible values are:
3080 - SMESH.ALL_NODES - include if all nodes are common,
3081 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3082 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3083 - SMEHS.MAJORITY - include if half of nodes or more are common.
3084 underlyingOnly: if *True* (default), an element is included to the
3085 new group provided that it is based on nodes of an element of *groups*;
3086 in this case the reference *groups* are supposed to be of higher dimension
3087 than *elemType*, which can be useful for example to get all faces lying on
3088 volumes of the reference *groups*.
3091 an instance of :class:`SMESH.SMESH_Group`
3094 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3096 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3098 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3100 Distribute all faces of the mesh among groups using sharp edges and optionally
3101 existing 1D elements as group boundaries.
3104 sharpAngle: edge is considered sharp if an angle between normals of
3105 adjacent faces is more than \a sharpAngle in degrees.
3106 createEdges (boolean): to create 1D elements for detected sharp edges.
3107 useExistingEdges (boolean): to use existing edges as group boundaries
3109 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3111 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3112 self.mesh.SetParameters(Parameters)
3113 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3115 def ConvertToStandalone(self, group):
3117 Convert group on geom into standalone group
3120 return self.mesh.ConvertToStandalone(group)
3122 # Get some info about mesh:
3123 # ------------------------
3125 def GetLog(self, clearAfterGet):
3127 Return the log of nodes and elements added or removed
3128 since the previous clear of the log.
3131 clearAfterGet: log is emptied after Get (safe if concurrents access)
3134 list of SMESH.log_block structures { commandType, number, coords, indexes }
3137 return self.mesh.GetLog(clearAfterGet)
3141 Clear the log of nodes and elements added or removed since the previous
3142 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3145 self.mesh.ClearLog()
3147 def SetAutoColor(self, theAutoColor):
3149 Toggle auto color mode on the object.
3150 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3153 theAutoColor (boolean): the flag which toggles auto color mode.
3156 self.mesh.SetAutoColor(theAutoColor)
3158 def GetAutoColor(self):
3160 Get flag of object auto color mode.
3166 return self.mesh.GetAutoColor()
3173 integer value, which is the internal Id of the mesh
3176 return self.mesh.GetId()
3178 def HasDuplicatedGroupNamesMED(self):
3180 Check the group names for duplications.
3181 Consider the maximum group name length stored in MED file.
3187 return self.mesh.HasDuplicatedGroupNamesMED()
3189 def GetMeshEditor(self):
3191 Obtain the mesh editor tool
3194 an instance of :class:`SMESH.SMESH_MeshEditor`
3199 def GetIDSource(self, ids, elemType = SMESH.ALL):
3201 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3202 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3206 elemType: type of elements; this parameter is used to distinguish
3207 IDs of nodes from IDs of elements; by default ids are treated as
3208 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3211 an instance of :class:`SMESH.SMESH_IDSource`
3214 call UnRegister() for the returned object as soon as it is no more useful::
3216 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3217 mesh.DoSomething( idSrc )
3221 if isinstance( ids, int ):
3223 return self.editor.MakeIDSource(ids, elemType)
3226 # Get information about mesh contents:
3227 # ------------------------------------
3229 def GetMeshInfo(self, obj = None):
3231 Get the mesh statistic.
3234 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3237 if not obj: obj = self.mesh
3238 return self.smeshpyD.GetMeshInfo(obj)
3242 Return the number of nodes in the mesh
3248 return self.mesh.NbNodes()
3250 def NbElements(self):
3252 Return the number of elements in the mesh
3258 return self.mesh.NbElements()
3260 def Nb0DElements(self):
3262 Return the number of 0d elements in the mesh
3268 return self.mesh.Nb0DElements()
3272 Return the number of ball discrete elements in the mesh
3278 return self.mesh.NbBalls()
3282 Return the number of edges in the mesh
3288 return self.mesh.NbEdges()
3290 def NbEdgesOfOrder(self, elementOrder):
3292 Return the number of edges with the given order in the mesh
3295 elementOrder: the order of elements
3296 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3302 return self.mesh.NbEdgesOfOrder(elementOrder)
3306 Return the number of faces in the mesh
3312 return self.mesh.NbFaces()
3314 def NbFacesOfOrder(self, elementOrder):
3316 Return the number of faces with the given order in the mesh
3319 elementOrder: the order of elements
3320 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3326 return self.mesh.NbFacesOfOrder(elementOrder)
3328 def NbTriangles(self):
3330 Return the number of triangles in the mesh
3336 return self.mesh.NbTriangles()
3338 def NbTrianglesOfOrder(self, elementOrder):
3340 Return the number of triangles with the given order in the mesh
3343 elementOrder: is the order of elements
3344 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3350 return self.mesh.NbTrianglesOfOrder(elementOrder)
3352 def NbBiQuadTriangles(self):
3354 Return the number of biquadratic triangles in the mesh
3360 return self.mesh.NbBiQuadTriangles()
3362 def NbQuadrangles(self):
3364 Return the number of quadrangles in the mesh
3370 return self.mesh.NbQuadrangles()
3372 def NbQuadranglesOfOrder(self, elementOrder):
3374 Return the number of quadrangles with the given order in the mesh
3377 elementOrder: the order of elements
3378 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3384 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3386 def NbBiQuadQuadrangles(self):
3388 Return the number of biquadratic quadrangles in the mesh
3394 return self.mesh.NbBiQuadQuadrangles()
3396 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3398 Return the number of polygons of given order in the mesh
3401 elementOrder: the order of elements
3402 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3408 return self.mesh.NbPolygonsOfOrder(elementOrder)
3410 def NbVolumes(self):
3412 Return the number of volumes in the mesh
3418 return self.mesh.NbVolumes()
3421 def NbVolumesOfOrder(self, elementOrder):
3423 Return the number of volumes with the given order in the mesh
3426 elementOrder: the order of elements
3427 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3433 return self.mesh.NbVolumesOfOrder(elementOrder)
3437 Return the number of tetrahedrons in the mesh
3443 return self.mesh.NbTetras()
3445 def NbTetrasOfOrder(self, elementOrder):
3447 Return the number of tetrahedrons with the given order in the mesh
3450 elementOrder: the order of elements
3451 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3457 return self.mesh.NbTetrasOfOrder(elementOrder)
3461 Return the number of hexahedrons in the mesh
3467 return self.mesh.NbHexas()
3469 def NbHexasOfOrder(self, elementOrder):
3471 Return the number of hexahedrons with the given order in the mesh
3474 elementOrder: the order of elements
3475 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3481 return self.mesh.NbHexasOfOrder(elementOrder)
3483 def NbTriQuadraticHexas(self):
3485 Return the number of triquadratic hexahedrons in the mesh
3491 return self.mesh.NbTriQuadraticHexas()
3493 def NbPyramids(self):
3495 Return the number of pyramids in the mesh
3501 return self.mesh.NbPyramids()
3503 def NbPyramidsOfOrder(self, elementOrder):
3505 Return the number of pyramids with the given order in the mesh
3508 elementOrder: the order of elements
3509 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3515 return self.mesh.NbPyramidsOfOrder(elementOrder)
3519 Return the number of prisms in the mesh
3525 return self.mesh.NbPrisms()
3527 def NbPrismsOfOrder(self, elementOrder):
3529 Return the number of prisms with the given order in the mesh
3532 elementOrder: the order of elements
3533 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3539 return self.mesh.NbPrismsOfOrder(elementOrder)
3541 def NbHexagonalPrisms(self):
3543 Return the number of hexagonal prisms in the mesh
3549 return self.mesh.NbHexagonalPrisms()
3551 def NbPolyhedrons(self):
3553 Return the number of polyhedrons in the mesh
3559 return self.mesh.NbPolyhedrons()
3561 def NbSubMesh(self):
3563 Return the number of submeshes in the mesh
3569 return self.mesh.NbSubMesh()
3571 def GetElementsId(self):
3573 Return the list of all mesh elements IDs
3576 the list of integer values
3579 :meth:`GetElementsByType`
3582 return self.mesh.GetElementsId()
3584 def GetElementsByType(self, elementType):
3586 Return the list of IDs of mesh elements with the given type
3589 elementType (SMESH.ElementType): the required type of elements
3592 list of integer values
3595 return self.mesh.GetElementsByType(elementType)
3597 def GetNodesId(self):
3599 Return the list of mesh nodes IDs
3602 the list of integer values
3605 return self.mesh.GetNodesId()
3607 # Get the information about mesh elements:
3608 # ------------------------------------
3610 def GetElementType(self, id, iselem=True):
3612 Return the type of mesh element or node
3615 the value from :class:`SMESH.ElementType` enumeration.
3616 Return SMESH.ALL if element or node with the given ID does not exist
3619 return self.mesh.GetElementType(id, iselem)
3621 def GetElementGeomType(self, id):
3623 Return the geometric type of mesh element
3626 the value from :class:`SMESH.EntityType` enumeration.
3629 return self.mesh.GetElementGeomType(id)
3631 def GetElementShape(self, id):
3633 Return the shape type of mesh element
3636 the value from :class:`SMESH.GeometryType` enumeration.
3639 return self.mesh.GetElementShape(id)
3641 def GetSubMeshElementsId(self, Shape):
3643 Return the list of sub-mesh elements IDs
3646 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3647 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3650 list of integer values
3653 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3654 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3657 return self.mesh.GetSubMeshElementsId(ShapeID)
3659 def GetSubMeshNodesId(self, Shape, all):
3661 Return the list of sub-mesh nodes IDs
3664 Shape: a geom object (sub-shape).
3665 *Shape* must be the sub-shape of a :meth:`GetShape`
3666 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3669 list of integer values
3672 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3673 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3676 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3678 def GetSubMeshElementType(self, Shape):
3680 Return type of elements on given shape
3683 Shape: a geom object (sub-shape).
3684 *Shape* must be a sub-shape of a ShapeToMesh()
3687 :class:`SMESH.ElementType`
3690 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3691 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3694 return self.mesh.GetSubMeshElementType(ShapeID)
3698 Get the mesh description
3704 return self.mesh.Dump()
3707 # Get the information about nodes and elements of a mesh by its IDs:
3708 # -----------------------------------------------------------
3710 def GetNodeXYZ(self, id):
3712 Get XYZ coordinates of a node.
3713 If there is no node for the given ID - return an empty list
3716 list of float values
3719 return self.mesh.GetNodeXYZ(id)
3721 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3723 Return list of IDs of inverse elements for the given node.
3724 If there is no node for the given ID - return an empty list
3728 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3731 list of integer values
3734 return self.mesh.GetNodeInverseElements(id,elemType)
3736 def GetNodePosition(self,NodeID):
3738 Return the position of a node on the shape
3741 :class:`SMESH.NodePosition`
3744 return self.mesh.GetNodePosition(NodeID)
3746 def GetElementPosition(self,ElemID):
3748 Return the position of an element on the shape
3751 :class:`SMESH.ElementPosition`
3754 return self.mesh.GetElementPosition(ElemID)
3756 def GetShapeID(self, id):
3758 Return the ID of the shape, on which the given node was generated.
3761 an integer value > 0 or -1 if there is no node for the given
3762 ID or the node is not assigned to any geometry
3765 return self.mesh.GetShapeID(id)
3767 def GetShapeIDForElem(self,id):
3769 Return the ID of the shape, on which the given element was generated.
3772 an integer value > 0 or -1 if there is no element for the given
3773 ID or the element is not assigned to any geometry
3776 return self.mesh.GetShapeIDForElem(id)
3778 def GetElemNbNodes(self, id):
3780 Return the number of nodes of the given element
3783 an integer value > 0 or -1 if there is no element for the given ID
3786 return self.mesh.GetElemNbNodes(id)
3788 def GetElemNode(self, id, index):
3790 Return the node ID the given (zero based) index for the given element.
3792 * If there is no element for the given ID - return -1.
3793 * If there is no node for the given index - return -2.
3796 id (int): element ID
3797 index (int): node index within the element
3800 an integer value (ID)
3803 :meth:`GetElemNodes`
3806 return self.mesh.GetElemNode(id, index)
3808 def GetElemNodes(self, id):
3810 Return the IDs of nodes of the given element
3813 a list of integer values
3816 return self.mesh.GetElemNodes(id)
3818 def IsMediumNode(self, elementID, nodeID):
3820 Return true if the given node is the medium node in the given quadratic element
3823 return self.mesh.IsMediumNode(elementID, nodeID)
3825 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3827 Return true if the given node is the medium node in one of quadratic elements
3830 nodeID: ID of the node
3831 elementType: the type of elements to check a state of the node, either of
3832 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3835 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3837 def ElemNbEdges(self, id):
3839 Return the number of edges for the given element
3842 return self.mesh.ElemNbEdges(id)
3844 def ElemNbFaces(self, id):
3846 Return the number of faces for the given element
3849 return self.mesh.ElemNbFaces(id)
3851 def GetElemFaceNodes(self,elemId, faceIndex):
3853 Return nodes of given face (counted from zero) for given volumic element.
3856 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3858 def GetFaceNormal(self, faceId, normalized=False):
3860 Return three components of normal of given mesh face
3861 (or an empty array in KO case)
3864 return self.mesh.GetFaceNormal(faceId,normalized)
3866 def FindElementByNodes(self, nodes):
3868 Return an element based on all given nodes.
3871 return self.mesh.FindElementByNodes(nodes)
3873 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3875 Return elements including all given nodes.
3878 return self.mesh.GetElementsByNodes( nodes, elemType )
3880 def IsPoly(self, id):
3882 Return true if the given element is a polygon
3885 return self.mesh.IsPoly(id)
3887 def IsQuadratic(self, id):
3889 Return true if the given element is quadratic
3892 return self.mesh.IsQuadratic(id)
3894 def GetBallDiameter(self, id):
3896 Return diameter of a ball discrete element or zero in case of an invalid *id*
3899 return self.mesh.GetBallDiameter(id)
3901 def BaryCenter(self, id):
3903 Return XYZ coordinates of the barycenter of the given element.
3904 If there is no element for the given ID - return an empty list
3907 a list of three double values
3910 :meth:`smeshBuilder.GetGravityCenter`
3913 return self.mesh.BaryCenter(id)
3915 def GetIdsFromFilter(self, filter, meshParts=[] ):
3917 Pass mesh elements through the given filter and return IDs of fitting elements
3920 filter: :class:`SMESH.Filter`
3921 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3927 :meth:`SMESH.Filter.GetIDs`
3928 :meth:`SMESH.Filter.GetElementsIdFromParts`
3931 filter.SetMesh( self.mesh )
3934 if isinstance( meshParts, Mesh ):
3935 filter.SetMesh( meshParts.GetMesh() )
3936 return theFilter.GetIDs()
3937 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3938 meshParts = [ meshParts ]
3939 return filter.GetElementsIdFromParts( meshParts )
3941 return filter.GetIDs()
3943 # Get mesh measurements information:
3944 # ------------------------------------
3946 def GetFreeBorders(self):
3948 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3949 Return a list of special structures (borders).
3952 a list of :class:`SMESH.FreeEdges.Border`
3955 aFilterMgr = self.smeshpyD.CreateFilterManager()
3956 aPredicate = aFilterMgr.CreateFreeEdges()
3957 aPredicate.SetMesh(self.mesh)
3958 aBorders = aPredicate.GetBorders()
3959 aFilterMgr.UnRegister()
3962 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3964 Get minimum distance between two nodes, elements or distance to the origin
3967 id1: first node/element id
3968 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3969 isElem1: *True* if *id1* is element id, *False* if it is node id
3970 isElem2: *True* if *id2* is element id, *False* if it is node id
3973 minimum distance value
3975 :meth:`GetMinDistance`
3978 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3979 return aMeasure.value
3981 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3983 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3986 id1: first node/element id
3987 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3988 isElem1: *True* if *id1* is element id, *False* if it is node id
3989 isElem2: *True* if *id2* is element id, *False* if it is node id
3992 :class:`SMESH.Measure` structure
3998 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
4000 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
4003 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
4005 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4010 aMeasurements = self.smeshpyD.CreateMeasurements()
4011 aMeasure = aMeasurements.MinDistance(id1, id2)
4012 genObjUnRegister([aMeasurements,id1, id2])
4015 def BoundingBox(self, objects=None, isElem=False):
4017 Get bounding box of the specified object(s)
4020 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4021 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4022 *False* specifies that *objects* are nodes
4025 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4028 :meth:`GetBoundingBox()`
4031 result = self.GetBoundingBox(objects, isElem)
4035 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4038 def GetBoundingBox(self, objects=None, isElem=False):
4040 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4043 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4044 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4045 False means that *objects* are nodes
4048 :class:`SMESH.Measure` structure
4051 :meth:`BoundingBox()`
4055 objects = [self.mesh]
4056 elif isinstance(objects, tuple):
4057 objects = list(objects)
4058 if not isinstance(objects, list):
4060 if len(objects) > 0 and isinstance(objects[0], int):
4063 unRegister = genObjUnRegister()
4065 if isinstance(o, Mesh):
4066 srclist.append(o.mesh)
4067 elif hasattr(o, "_narrow"):
4068 src = o._narrow(SMESH.SMESH_IDSource)
4069 if src: srclist.append(src)
4071 elif isinstance(o, list):
4073 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4075 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4076 unRegister.set( srclist[-1] )
4079 aMeasurements = self.smeshpyD.CreateMeasurements()
4080 unRegister.set( aMeasurements )
4081 aMeasure = aMeasurements.BoundingBox(srclist)
4084 # Mesh edition (SMESH_MeshEditor functionality):
4085 # ---------------------------------------------
4087 def RemoveElements(self, IDsOfElements):
4089 Remove the elements from the mesh by ids
4092 IDsOfElements: is a list of ids of elements to remove
4098 This operation can create gaps in numeration of elements.
4099 Call :meth:`RenumberElements` to remove the gaps.
4102 return self.editor.RemoveElements(IDsOfElements)
4104 def RemoveNodes(self, IDsOfNodes):
4106 Remove nodes from mesh by ids
4109 IDsOfNodes: is a list of ids of nodes to remove
4115 This operation can create gaps in numeration of nodes.
4116 Call :meth:`RenumberElements` to remove the gaps.
4119 return self.editor.RemoveNodes(IDsOfNodes)
4121 def RemoveNodeWithReconnection(self, nodeID ):
4123 Remove a node along with changing surrounding faces to cover a hole.
4126 nodeID: ID of node to remove
4129 return self.editor.RemoveNodeWithReconnection( nodeID )
4131 def RemoveOrphanNodes(self):
4133 Remove all orphan (free) nodes from mesh
4136 number of the removed nodes
4139 This operation can create gaps in numeration of nodes.
4140 Call :meth:`RenumberElements` to remove the gaps.
4143 return self.editor.RemoveOrphanNodes()
4145 def AddNode(self, x, y, z):
4147 Add a node to the mesh by coordinates
4153 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4154 if hasVars: self.mesh.SetParameters(Parameters)
4155 return self.editor.AddNode( x, y, z)
4157 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4159 Create a 0D element on a node with given number.
4162 IDOfNode: the ID of node for creation of the element.
4163 DuplicateElements: to add one more 0D element to a node or not
4166 ID of the new 0D element
4169 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4171 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4173 Create 0D elements on all nodes of the given elements except those
4174 nodes on which a 0D element already exists.
4177 theObject: an object on whose nodes 0D elements will be created.
4178 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4179 theGroupName: optional name of a group to add 0D elements created
4180 and/or found on nodes of *theObject*.
4181 DuplicateElements: to add one more 0D element to a node or not
4184 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4185 IDs of new and/or found 0D elements. IDs of 0D elements
4186 can be retrieved from the returned object by
4187 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4190 unRegister = genObjUnRegister()
4191 if isinstance( theObject, Mesh ):
4192 theObject = theObject.GetMesh()
4193 elif isinstance( theObject, list ):
4194 theObject = self.GetIDSource( theObject, SMESH.ALL )
4195 unRegister.set( theObject )
4196 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4198 def AddBall(self, IDOfNode, diameter):
4200 Create a ball element on a node with given ID.
4203 IDOfNode: the ID of node for creation of the element.
4204 diameter: the bal diameter.
4207 ID of the new ball element
4210 return self.editor.AddBall( IDOfNode, diameter )
4212 def AddEdge(self, IDsOfNodes):
4214 Create a linear or quadratic edge (this is determined
4215 by the number of given nodes).
4218 IDsOfNodes: list of node IDs for creation of the element.
4219 The order of nodes in this list should correspond to
4220 the :ref:`connectivity convention <connectivity_page>`.
4226 return self.editor.AddEdge(IDsOfNodes)
4228 def AddFace(self, IDsOfNodes):
4230 Create a linear or quadratic face (this is determined
4231 by the number of given nodes).
4234 IDsOfNodes: list of node IDs for creation of the element.
4235 The order of nodes in this list should correspond to
4236 the :ref:`connectivity convention <connectivity_page>`.
4242 return self.editor.AddFace(IDsOfNodes)
4244 def AddPolygonalFace(self, IdsOfNodes):
4246 Add a polygonal face defined by a list of node IDs
4249 IdsOfNodes: the list of node IDs for creation of the element.
4255 return self.editor.AddPolygonalFace(IdsOfNodes)
4257 def AddQuadPolygonalFace(self, IdsOfNodes):
4259 Add a quadratic polygonal face defined by a list of node IDs
4262 IdsOfNodes: the list of node IDs for creation of the element;
4263 corner nodes follow first.
4269 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4271 def AddVolume(self, IDsOfNodes):
4273 Create both simple and quadratic volume (this is determined
4274 by the number of given nodes).
4277 IDsOfNodes: list of node IDs for creation of the element.
4278 The order of nodes in this list should correspond to
4279 the :ref:`connectivity convention <connectivity_page>`.
4282 ID of the new volumic element
4285 return self.editor.AddVolume(IDsOfNodes)
4287 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4289 Create a volume of many faces, giving nodes for each face.
4292 IdsOfNodes: list of node IDs for volume creation, face by face.
4293 Quantities: list of integer values, Quantities[i]
4294 gives the quantity of nodes in face number i.
4297 ID of the new volumic element
4300 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4302 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4304 Create a volume of many faces, giving the IDs of the existing faces.
4307 The created volume will refer only to the nodes
4308 of the given faces, not to the faces themselves.
4311 IdsOfFaces: the list of face IDs for volume creation.
4314 ID of the new volumic element
4317 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4320 def SetNodeOnVertex(self, NodeID, Vertex):
4322 Bind a node to a vertex
4326 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4329 True if succeed else raises an exception
4332 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4333 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4337 self.editor.SetNodeOnVertex(NodeID, VertexID)
4338 except SALOME.SALOME_Exception as inst:
4339 raise ValueError(inst.details.text)
4343 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4345 Store the node position on an edge
4349 Edge: an edge (GEOM.GEOM_Object) or edge ID
4350 paramOnEdge: a parameter on the edge where the node is located
4353 True if succeed else raises an exception
4356 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4357 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4361 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4362 except SALOME.SALOME_Exception as inst:
4363 raise ValueError(inst.details.text)
4366 def SetNodeOnFace(self, NodeID, Face, u, v):
4368 Store node position on a face
4372 Face: a face (GEOM.GEOM_Object) or face ID
4373 u: U parameter on the face where the node is located
4374 v: V parameter on the face where the node is located
4377 True if succeed else raises an exception
4380 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4381 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4385 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4386 except SALOME.SALOME_Exception as inst:
4387 raise ValueError(inst.details.text)
4390 def SetNodeInVolume(self, NodeID, Solid):
4392 Bind a node to a solid
4396 Solid: a solid (GEOM.GEOM_Object) or solid ID
4399 True if succeed else raises an exception
4402 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4403 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4407 self.editor.SetNodeInVolume(NodeID, SolidID)
4408 except SALOME.SALOME_Exception as inst:
4409 raise ValueError(inst.details.text)
4412 def SetMeshElementOnShape(self, ElementID, Shape):
4414 Bind an element to a shape
4417 ElementID: an element ID
4418 Shape: a shape (GEOM.GEOM_Object) or shape ID
4421 True if succeed else raises an exception
4424 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4425 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4429 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4430 except SALOME.SALOME_Exception as inst:
4431 raise ValueError(inst.details.text)
4435 def MoveNode(self, NodeID, x, y, z):
4437 Move the node with the given id
4440 NodeID: the id of the node
4441 x: a new X coordinate
4442 y: a new Y coordinate
4443 z: a new Z coordinate
4446 True if succeed else False
4449 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4450 if hasVars: self.mesh.SetParameters(Parameters)
4451 return self.editor.MoveNode(NodeID, x, y, z)
4453 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4455 Find the node closest to a point and moves it to a point location
4458 x: the X coordinate of a point
4459 y: the Y coordinate of a point
4460 z: the Z coordinate of a point
4461 NodeID: if specified (>0), the node with this ID is moved,
4462 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4465 the ID of a moved node
4468 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4469 if hasVars: self.mesh.SetParameters(Parameters)
4470 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4472 def FindNodeClosestTo(self, x, y, z):
4474 Find the node closest to a point
4477 x: the X coordinate of a point
4478 y: the Y coordinate of a point
4479 z: the Z coordinate of a point
4485 return self.editor.FindNodeClosestTo(x, y, z)
4487 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4489 Find the elements where a point lays IN or ON
4492 x,y,z (float): coordinates of the point
4493 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4494 means elements of any type excluding nodes, discrete and 0D elements.
4495 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4498 list of IDs of found elements
4501 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4503 return self.editor.FindElementsByPoint(x, y, z, elementType)
4505 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4507 Project a point to a mesh object.
4508 Return ID of an element of given type where the given point is projected
4509 and coordinates of the projection point.
4510 In the case if nothing found, return -1 and []
4512 if isinstance( meshObject, Mesh ):
4513 meshObject = meshObject.GetMesh()
4515 meshObject = self.GetMesh()
4516 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4518 def GetPointState(self, x, y, z):
4520 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4521 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4522 UNKNOWN state means that either mesh is wrong or the analysis fails.
4525 return self.editor.GetPointState(x, y, z)
4527 def IsManifold(self):
4529 Check if a 2D mesh is manifold
4532 return self.editor.IsManifold()
4534 def IsCoherentOrientation2D(self):
4536 Check if orientation of 2D elements is coherent
4539 return self.editor.IsCoherentOrientation2D()
4541 def Get1DBranches( self, edges, startNode = 0 ):
4543 Partition given 1D elements into groups of contiguous edges.
4544 A node where number of meeting edges != 2 is a group end.
4545 An optional startNode is used to orient groups it belongs to.
4548 A list of edge groups and a list of corresponding node groups,
4549 where the group is a list of IDs of edges or nodes, like follows
4550 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4551 If a group is closed, the first and last nodes of the group are same.
4553 if isinstance( edges, Mesh ):
4554 edges = edges.GetMesh()
4555 unRegister = genObjUnRegister()
4556 if isinstance( edges, list ):
4557 edges = self.GetIDSource( edges, SMESH.EDGE )
4558 unRegister.set( edges )
4559 return self.editor.Get1DBranches( edges, startNode )
4561 def FindSharpEdges( self, angle, addExisting=False ):
4563 Return sharp edges of faces and non-manifold ones.
4564 Optionally add existing edges.
4567 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4568 addExisting: to return existing edges (1D elements) as well
4571 list of FaceEdge structures
4573 angle = ParseParameters( angle )[0]
4574 return self.editor.FindSharpEdges( angle, addExisting )
4576 def MeshToPassThroughAPoint(self, x, y, z):
4578 Find the node closest to a point and moves it to a point location
4581 x: the X coordinate of a point
4582 y: the Y coordinate of a point
4583 z: the Z coordinate of a point
4586 the ID of a moved node
4589 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4591 def InverseDiag(self, NodeID1, NodeID2):
4593 Replace two neighbour triangles sharing Node1-Node2 link
4594 with the triangles built on the same 4 nodes but having other common link.
4597 NodeID1: the ID of the first node
4598 NodeID2: the ID of the second node
4601 False if proper faces were not found
4603 return self.editor.InverseDiag(NodeID1, NodeID2)
4605 def DeleteDiag(self, NodeID1, NodeID2):
4607 Replace two neighbour triangles sharing *Node1-Node2* link
4608 with a quadrangle built on the same 4 nodes.
4611 NodeID1: ID of the first node
4612 NodeID2: ID of the second node
4615 False if proper faces were not found
4618 This operation can create gaps in numeration of elements.
4619 Call :meth:`RenumberElements` to remove the gaps.
4622 return self.editor.DeleteDiag(NodeID1, NodeID2)
4624 def AddNodeOnSegment(self, Node1, Node2, position = 0.5):
4626 Replace each triangle bound by Node1-Node2 segment with
4627 two triangles by connecting a node made on the link with a node
4628 opposite to the link.
4631 Node1: ID of the first node
4632 Node2: ID of the second node
4633 position: location [0,1] of the new node on the segment
4635 return self.editor.AddNodeOnSegment(Node1, Node2, position)
4637 def AddNodeOnFace(self, face, x, y, z):
4639 Split a face into triangles by adding a new node onto the face
4640 and connecting the new node with face nodes
4643 face: ID of the face
4644 x,y,z: coordinates of the new node
4646 return self.editor.AddNodeOnFace(face, x, y, z)
4648 def Reorient(self, IDsOfElements=None):
4650 Reorient elements by ids
4653 IDsOfElements: if undefined reorients all mesh elements
4656 True if succeed else False
4659 if IDsOfElements == None:
4660 IDsOfElements = self.GetElementsId()
4661 return self.editor.Reorient(IDsOfElements)
4663 def ReorientObject(self, theObject):
4665 Reorient all elements of the object
4668 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4671 True if succeed else False
4674 if ( isinstance( theObject, Mesh )):
4675 theObject = theObject.GetMesh()
4676 return self.editor.ReorientObject(theObject)
4678 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4680 Reorient faces contained in *the2DObject*.
4683 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4684 theDirection: a desired direction of normal of *theFace*.
4685 It can be either a GEOM vector or a list of coordinates [x,y,z].
4686 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4687 compared with theDirection. It can be either ID of face or a point
4688 by which the face will be found. The point can be given as either
4689 a GEOM vertex or a list of point coordinates.
4692 number of reoriented faces
4695 unRegister = genObjUnRegister()
4697 if isinstance( the2DObject, Mesh ):
4698 the2DObject = the2DObject.GetMesh()
4699 if isinstance( the2DObject, list ):
4700 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4701 unRegister.set( the2DObject )
4702 # check theDirection
4703 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4704 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4705 if isinstance( theDirection, list ):
4706 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4707 # prepare theFace and thePoint
4708 theFace = theFaceOrPoint
4709 thePoint = PointStruct(0,0,0)
4710 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4711 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4713 if isinstance( theFaceOrPoint, list ):
4714 thePoint = PointStruct( *theFaceOrPoint )
4716 if isinstance( theFaceOrPoint, PointStruct ):
4717 thePoint = theFaceOrPoint
4719 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4721 def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4723 Reorient faces contained in a list of *objectFaces*
4724 equally to faces contained in a list of *referenceFaces*.
4727 objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4728 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.
4731 number of reoriented faces.
4733 if not isinstance( objectFaces, list ):
4734 objectFaces = [ objectFaces ]
4735 for i,obj2D in enumerate( objectFaces ):
4736 if isinstance( obj2D, Mesh ):
4737 objectFaces[i] = obj2D.GetMesh()
4738 if not isinstance( referenceFaces, list ):
4739 referenceFaces = [ referenceFaces ]
4741 return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4744 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4746 Reorient faces according to adjacent volumes.
4749 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4750 either IDs of faces or face groups.
4751 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4752 theOutsideNormal: to orient faces to have their normals
4753 pointing either *outside* or *inside* the adjacent volumes.
4756 number of reoriented faces.
4759 unRegister = genObjUnRegister()
4761 if not isinstance( the2DObject, list ):
4762 the2DObject = [ the2DObject ]
4763 elif the2DObject and isinstance( the2DObject[0], int ):
4764 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4765 unRegister.set( the2DObject )
4766 the2DObject = [ the2DObject ]
4767 for i,obj2D in enumerate( the2DObject ):
4768 if isinstance( obj2D, Mesh ):
4769 the2DObject[i] = obj2D.GetMesh()
4770 if isinstance( obj2D, list ):
4771 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4772 unRegister.set( the2DObject[i] )
4774 if isinstance( the3DObject, Mesh ):
4775 the3DObject = the3DObject.GetMesh()
4776 if isinstance( the3DObject, list ):
4777 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4778 unRegister.set( the3DObject )
4779 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4781 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4783 Fuse the neighbouring triangles into quadrangles.
4786 IDsOfElements: The triangles to be fused.
4787 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4788 applied to possible quadrangles to choose a neighbour to fuse with.
4789 Note that not all items of :class:`SMESH.FunctorType` corresponds
4790 to numerical functors.
4791 MaxAngle: is the maximum angle between element normals at which the fusion
4792 is still performed; theMaxAngle is measured in radians.
4793 Also it could be a name of variable which defines angle in degrees.
4796 True in case of success, False otherwise.
4799 This operation can create gaps in numeration of elements.
4800 Call :meth:`RenumberElements` to remove the gaps.
4803 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4804 self.mesh.SetParameters(Parameters)
4805 if not IDsOfElements:
4806 IDsOfElements = self.GetElementsId()
4807 Functor = self.smeshpyD.GetFunctor(theCriterion)
4808 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4810 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4812 Fuse the neighbouring triangles of the object into quadrangles
4815 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4816 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4817 applied to possible quadrangles to choose a neighbour to fuse with.
4818 Note that not all items of :class:`SMESH.FunctorType` corresponds
4819 to numerical functors.
4820 MaxAngle: a max angle between element normals at which the fusion
4821 is still performed; theMaxAngle is measured in radians.
4824 True in case of success, False otherwise.
4827 This operation can create gaps in numeration of elements.
4828 Call :meth:`RenumberElements` to remove the gaps.
4831 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4832 self.mesh.SetParameters(Parameters)
4833 if isinstance( theObject, Mesh ):
4834 theObject = theObject.GetMesh()
4835 Functor = self.smeshpyD.GetFunctor(theCriterion)
4836 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4838 def QuadToTri (self, IDsOfElements, theCriterion = None):
4840 Split quadrangles into triangles.
4843 IDsOfElements: the faces to be splitted.
4844 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4845 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4846 value, then quadrangles will be split by the smallest diagonal.
4847 Note that not all items of :class:`SMESH.FunctorType` corresponds
4848 to numerical functors.
4851 True in case of success, False otherwise.
4854 This operation can create gaps in numeration of elements.
4855 Call :meth:`RenumberElements` to remove the gaps.
4857 if IDsOfElements == []:
4858 IDsOfElements = self.GetElementsId()
4859 if theCriterion is None:
4860 theCriterion = FT_MaxElementLength2D
4861 Functor = self.smeshpyD.GetFunctor(theCriterion)
4862 return self.editor.QuadToTri(IDsOfElements, Functor)
4864 def QuadToTriObject (self, theObject, theCriterion = None):
4866 Split quadrangles into triangles.
4869 theObject: the object from which the list of elements is taken,
4870 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4871 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4872 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4873 value, then quadrangles will be split by the smallest diagonal.
4874 Note that not all items of :class:`SMESH.FunctorType` corresponds
4875 to numerical functors.
4878 True in case of success, False otherwise.
4881 This operation can create gaps in numeration of elements.
4882 Call :meth:`RenumberElements` to remove the gaps.
4884 if ( isinstance( theObject, Mesh )):
4885 theObject = theObject.GetMesh()
4886 if theCriterion is None:
4887 theCriterion = FT_MaxElementLength2D
4888 Functor = self.smeshpyD.GetFunctor(theCriterion)
4889 return self.editor.QuadToTriObject(theObject, Functor)
4891 def QuadTo4Tri (self, theElements=[]):
4893 Split each of given quadrangles into 4 triangles. A node is added at the center of
4897 theElements: the faces to be splitted. This can be either
4898 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4899 or a list of face IDs. By default all quadrangles are split
4902 This operation can create gaps in numeration of elements.
4903 Call :meth:`RenumberElements` to remove the gaps.
4905 unRegister = genObjUnRegister()
4906 if isinstance( theElements, Mesh ):
4907 theElements = theElements.mesh
4908 elif not theElements:
4909 theElements = self.mesh
4910 elif isinstance( theElements, list ):
4911 theElements = self.GetIDSource( theElements, SMESH.FACE )
4912 unRegister.set( theElements )
4913 return self.editor.QuadTo4Tri( theElements )
4915 def SplitQuad (self, IDsOfElements, Diag13):
4917 Split quadrangles into triangles.
4920 IDsOfElements: the faces to be splitted
4921 Diag13 (boolean): is used to choose a diagonal for splitting.
4924 True in case of success, False otherwise.
4927 This operation can create gaps in numeration of elements.
4928 Call :meth:`RenumberElements` to remove the gaps.
4930 if IDsOfElements == []:
4931 IDsOfElements = self.GetElementsId()
4932 return self.editor.SplitQuad(IDsOfElements, Diag13)
4934 def SplitQuadObject (self, theObject, Diag13):
4936 Split quadrangles into triangles.
4939 theObject: the object from which the list of elements is taken,
4940 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4941 Diag13 (boolean): is used to choose a diagonal for splitting.
4944 True in case of success, False otherwise.
4947 This operation can create gaps in numeration of elements.
4948 Call :meth:`RenumberElements` to remove the gaps.
4950 if ( isinstance( theObject, Mesh )):
4951 theObject = theObject.GetMesh()
4952 return self.editor.SplitQuadObject(theObject, Diag13)
4954 def BestSplit (self, IDOfQuad, theCriterion):
4956 Find a better splitting of the given quadrangle.
4959 IDOfQuad: the ID of the quadrangle to be splitted.
4960 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4961 choose a diagonal for splitting.
4962 Note that not all items of :class:`SMESH.FunctorType` corresponds
4963 to numerical functors.
4966 * 1 if 1-3 diagonal is better,
4967 * 2 if 2-4 diagonal is better,
4968 * 0 if error occurs.
4971 This operation can create gaps in numeration of elements.
4972 Call :meth:`RenumberElements` to remove the gaps.
4974 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4976 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4978 Split volumic elements into tetrahedrons
4981 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4982 method: flags passing splitting method:
4983 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4984 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4987 This operation can create gaps in numeration of elements.
4988 Call :meth:`RenumberElements` to remove the gaps.
4990 unRegister = genObjUnRegister()
4991 if isinstance( elems, Mesh ):
4992 elems = elems.GetMesh()
4993 if ( isinstance( elems, list )):
4994 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4995 unRegister.set( elems )
4996 self.editor.SplitVolumesIntoTetra(elems, method)
4999 def SplitBiQuadraticIntoLinear(self, elems=None):
5001 Split bi-quadratic elements into linear ones without creation of additional nodes:
5003 - bi-quadratic triangle will be split into 3 linear quadrangles;
5004 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
5005 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
5007 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
5008 will be split in order to keep the mesh conformal.
5011 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
5012 if None (default), all bi-quadratic elements will be split
5015 This operation can create gaps in numeration of elements.
5016 Call :meth:`RenumberElements` to remove the gaps.
5018 unRegister = genObjUnRegister()
5019 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
5020 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
5021 unRegister.set( elems )
5023 elems = [ self.GetMesh() ]
5024 if isinstance( elems, Mesh ):
5025 elems = [ elems.GetMesh() ]
5026 if not isinstance( elems, list ):
5028 self.editor.SplitBiQuadraticIntoLinear( elems )
5030 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
5031 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
5033 Split hexahedra into prisms
5036 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5037 startHexPoint: a point used to find a hexahedron for which *facetNormal*
5038 gives a normal vector defining facets to split into triangles.
5039 *startHexPoint* can be either a triple of coordinates or a vertex.
5040 facetNormal: a normal to a facet to split into triangles of a
5041 hexahedron found by *startHexPoint*.
5042 *facetNormal* can be either a triple of coordinates or an edge.
5043 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
5044 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
5045 allDomains: if :code:`False`, only hexahedra adjacent to one closest
5046 to *startHexPoint* are split, else *startHexPoint*
5047 is used to find the facet to split in all domains present in *elems*.
5050 This operation can create gaps in numeration of elements.
5051 Call :meth:`RenumberElements` to remove the gaps.
5054 unRegister = genObjUnRegister()
5055 if isinstance( elems, Mesh ):
5056 elems = elems.GetMesh()
5057 if ( isinstance( elems, list )):
5058 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5059 unRegister.set( elems )
5062 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5063 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5064 elif isinstance( startHexPoint, list ):
5065 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5068 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5069 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5070 elif isinstance( facetNormal, list ):
5071 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5074 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5076 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5078 def SplitQuadsNearTriangularFacets(self):
5080 Split quadrangle faces near triangular facets of volumes
5083 This operation can create gaps in numeration of elements.
5084 Call :meth:`RenumberElements` to remove the gaps.
5086 faces_array = self.GetElementsByType(SMESH.FACE)
5087 for face_id in faces_array:
5088 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5089 quad_nodes = self.mesh.GetElemNodes(face_id)
5090 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5091 isVolumeFound = False
5092 for node1_elem in node1_elems:
5093 if not isVolumeFound:
5094 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5095 nb_nodes = self.GetElemNbNodes(node1_elem)
5096 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5097 volume_elem = node1_elem
5098 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5099 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5100 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5101 isVolumeFound = True
5102 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5103 self.SplitQuad([face_id], False) # diagonal 2-4
5104 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5105 isVolumeFound = True
5106 self.SplitQuad([face_id], True) # diagonal 1-3
5107 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5108 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5109 isVolumeFound = True
5110 self.SplitQuad([face_id], True) # diagonal 1-3
5112 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5114 Split hexahedrons into tetrahedrons.
5116 This operation uses :doc:`pattern_mapping` functionality for splitting.
5119 theObject: the object from which the list of hexahedrons is taken;
5120 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5121 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5122 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5123 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5124 key-point will be mapped into *theNode001*-th node of each volume.
5125 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5128 True in case of success, False otherwise.
5131 This operation can create gaps in numeration of elements.
5132 Call :meth:`RenumberElements` to remove the gaps.
5140 # (0,0,1) 4.---------.7 * |
5147 # (0,0,0) 0.---------.3
5148 pattern_tetra = "!!! Nb of points: \n 8 \n\
5158 !!! Indices of points of 6 tetras: \n\
5166 pattern = self.smeshpyD.GetPattern()
5167 isDone = pattern.LoadFromFile(pattern_tetra)
5169 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5172 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5173 isDone = pattern.MakeMesh(self.mesh, False, False)
5174 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5176 # split quafrangle faces near triangular facets of volumes
5177 self.SplitQuadsNearTriangularFacets()
5181 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5183 Split hexahedrons into prisms.
5185 Uses the :doc:`pattern_mapping` functionality for splitting.
5188 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5189 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5190 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5191 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5192 will be mapped into the *theNode001* -th node of each volume.
5193 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5196 True in case of success, False otherwise.
5199 This operation can create gaps in numeration of elements.
5200 Call :meth:`RenumberElements` to remove the gaps.
5202 # Pattern: 5.---------.6
5207 # (0,0,1) 4.---------.7 |
5214 # (0,0,0) 0.---------.3
5215 pattern_prism = "!!! Nb of points: \n 8 \n\
5225 !!! Indices of points of 2 prisms: \n\
5229 pattern = self.smeshpyD.GetPattern()
5230 isDone = pattern.LoadFromFile(pattern_prism)
5232 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5235 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5236 isDone = pattern.MakeMesh(self.mesh, False, False)
5237 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5239 # Split quafrangle faces near triangular facets of volumes
5240 self.SplitQuadsNearTriangularFacets()
5244 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5245 MaxNbOfIterations, MaxAspectRatio, Method):
5250 IDsOfElements: the list if ids of elements to smooth
5251 IDsOfFixedNodes: the list of ids of fixed nodes.
5252 Note that nodes built on edges and boundary nodes are always fixed.
5253 MaxNbOfIterations: the maximum number of iterations
5254 MaxAspectRatio: varies in range [1.0, inf]
5255 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5256 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5259 True in case of success, False otherwise.
5262 if IDsOfElements == []:
5263 IDsOfElements = self.GetElementsId()
5264 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5265 self.mesh.SetParameters(Parameters)
5266 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5267 MaxNbOfIterations, MaxAspectRatio, Method)
5269 def SmoothObject(self, theObject, IDsOfFixedNodes,
5270 MaxNbOfIterations, MaxAspectRatio, Method):
5272 Smooth elements which belong to the given object
5275 theObject: the object to smooth
5276 IDsOfFixedNodes: the list of ids of fixed nodes.
5277 Note that nodes built on edges and boundary nodes are always fixed.
5278 MaxNbOfIterations: the maximum number of iterations
5279 MaxAspectRatio: varies in range [1.0, inf]
5280 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5281 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5284 True in case of success, False otherwise.
5287 if ( isinstance( theObject, Mesh )):
5288 theObject = theObject.GetMesh()
5289 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5290 MaxNbOfIterations, MaxAspectRatio, Method)
5292 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5293 MaxNbOfIterations, MaxAspectRatio, Method):
5295 Parametrically smooth the given elements
5298 IDsOfElements: the list if ids of elements to smooth
5299 IDsOfFixedNodes: the list of ids of fixed nodes.
5300 Note that nodes built on edges and boundary nodes are always fixed.
5301 MaxNbOfIterations: the maximum number of iterations
5302 MaxAspectRatio: varies in range [1.0, inf]
5303 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5304 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5307 True in case of success, False otherwise.
5310 if IDsOfElements == []:
5311 IDsOfElements = self.GetElementsId()
5312 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5313 self.mesh.SetParameters(Parameters)
5314 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5315 MaxNbOfIterations, MaxAspectRatio, Method)
5317 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5318 MaxNbOfIterations, MaxAspectRatio, Method):
5320 Parametrically smooth the elements which belong to the given object
5323 theObject: the object to smooth
5324 IDsOfFixedNodes: the list of ids of fixed nodes.
5325 Note that nodes built on edges and boundary nodes are always fixed.
5326 MaxNbOfIterations: the maximum number of iterations
5327 MaxAspectRatio: varies in range [1.0, inf]
5328 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5329 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5332 True in case of success, False otherwise.
5335 if ( isinstance( theObject, Mesh )):
5336 theObject = theObject.GetMesh()
5337 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5338 MaxNbOfIterations, MaxAspectRatio, Method)
5340 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5342 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5343 them with quadratic with the same id.
5346 theForce3d: method of new node creation:
5348 * False - the medium node lies at the geometrical entity from which the mesh element is built
5349 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5350 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5351 theToBiQuad: If True, converts the mesh to bi-quadratic
5354 :class:`SMESH.ComputeError` which can hold a warning
5357 If *theSubMesh* is provided, the mesh can become non-conformal
5360 This operation can create gaps in numeration of nodes or elements.
5361 Call :meth:`RenumberElements` to remove the gaps.
5364 if isinstance( theSubMesh, Mesh ):
5365 theSubMesh = theSubMesh.mesh
5367 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5370 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5372 self.editor.ConvertToQuadratic(theForce3d)
5373 error = self.editor.GetLastError()
5374 if error and error.comment:
5375 print(error.comment)
5378 def ConvertFromQuadratic(self, theSubMesh=None):
5380 Convert the mesh from quadratic to ordinary,
5381 deletes old quadratic elements,
5382 replacing them with ordinary mesh elements with the same id.
5385 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5388 If *theSubMesh* is provided, the mesh can become non-conformal
5391 This operation can create gaps in numeration of nodes or elements.
5392 Call :meth:`RenumberElements` to remove the gaps.
5396 self.editor.ConvertFromQuadraticObject(theSubMesh)
5398 return self.editor.ConvertFromQuadratic()
5400 def Make2DMeshFrom3D(self):
5402 Create 2D mesh as skin on boundary faces of a 3D mesh
5405 True if operation has been completed successfully, False otherwise
5408 return self.editor.Make2DMeshFrom3D()
5410 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5411 toCopyElements=False, toCopyExistingBondary=False):
5413 Create missing boundary elements
5416 elements: elements whose boundary is to be checked:
5417 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5418 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5419 dimension: defines type of boundary elements to create, either of
5420 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5421 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5422 groupName: a name of group to store created boundary elements in,
5423 "" means not to create the group
5424 meshName: a name of new mesh to store created boundary elements in,
5425 "" means not to create the new mesh
5426 toCopyElements: if True, the checked elements will be copied into
5427 the new mesh else only boundary elements will be copied into the new mesh
5428 toCopyExistingBondary: if True, not only new but also pre-existing
5429 boundary elements will be copied into the new mesh
5432 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5435 unRegister = genObjUnRegister()
5436 if isinstance( elements, Mesh ):
5437 elements = elements.GetMesh()
5438 if ( isinstance( elements, list )):
5439 elemType = SMESH.ALL
5440 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5441 elements = self.editor.MakeIDSource(elements, elemType)
5442 unRegister.set( elements )
5443 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5444 toCopyElements,toCopyExistingBondary)
5445 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5448 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5449 toCopyAll=False, groups=[]):
5451 Create missing boundary elements around either the whole mesh or
5455 dimension: defines type of boundary elements to create, either of
5456 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5457 groupName: a name of group to store all boundary elements in,
5458 "" means not to create the group
5459 meshName: a name of a new mesh, which is a copy of the initial
5460 mesh + created boundary elements; "" means not to create the new mesh
5461 toCopyAll: if True, the whole initial mesh will be copied into
5462 the new mesh else only boundary elements will be copied into the new mesh
5463 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5466 tuple( long, mesh, group )
5467 - long - number of added boundary elements
5468 - mesh - the :class:`Mesh` where elements were added to
5469 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5472 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5474 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5475 return nb, mesh, group
5477 def RenumberNodes(self):
5479 Renumber mesh nodes to remove unused node IDs
5481 self.editor.RenumberNodes()
5483 def RenumberElements(self):
5485 Renumber mesh elements to remove unused element IDs
5487 self.editor.RenumberElements()
5489 def _getIdSourceList(self, arg, idType, unRegister):
5491 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5493 if arg and isinstance( arg, list ):
5494 if isinstance( arg[0], int ):
5495 arg = self.GetIDSource( arg, idType )
5496 unRegister.set( arg )
5497 elif isinstance( arg[0], Mesh ):
5498 arg[0] = arg[0].GetMesh()
5499 elif isinstance( arg, Mesh ):
5501 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5505 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5506 MakeGroups=False, TotalAngle=False):
5508 Generate new elements by rotation of the given elements and nodes around the axis
5511 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5512 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5513 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5514 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5515 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5516 which defines angle in degrees
5517 NbOfSteps: the number of steps
5518 Tolerance: tolerance
5519 MakeGroups: forces the generation of new groups from existing ones
5520 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5521 of all steps, else - size of each step
5524 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5527 unRegister = genObjUnRegister()
5528 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5529 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5530 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5532 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5533 Axis = self.smeshpyD.GetAxisStruct( Axis )
5534 if isinstance( Axis, list ):
5535 Axis = SMESH.AxisStruct( *Axis )
5537 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5538 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5539 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5540 self.mesh.SetParameters(Parameters)
5541 if TotalAngle and NbOfSteps:
5542 AngleInRadians /= NbOfSteps
5543 return self.editor.RotationSweepObjects( nodes, edges, faces,
5544 Axis, AngleInRadians,
5545 NbOfSteps, Tolerance, MakeGroups)
5547 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5548 MakeGroups=False, TotalAngle=False):
5550 Generate new elements by rotation of the elements around the axis
5553 IDsOfElements: the list of ids of elements to sweep
5554 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5555 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5556 NbOfSteps: the number of steps
5557 Tolerance: tolerance
5558 MakeGroups: forces the generation of new groups from existing ones
5559 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5560 of all steps, else - size of each step
5563 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5566 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5567 AngleInRadians, NbOfSteps, Tolerance,
5568 MakeGroups, TotalAngle)
5570 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5571 MakeGroups=False, TotalAngle=False):
5573 Generate new elements by rotation of the elements of object around the axis
5574 theObject object which elements should be sweeped.
5575 It can be a mesh, a sub mesh or a group.
5578 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5579 AngleInRadians: the angle of Rotation
5580 NbOfSteps: number of steps
5581 Tolerance: tolerance
5582 MakeGroups: forces the generation of new groups from existing ones
5583 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5584 of all steps, else - size of each step
5587 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5590 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5591 AngleInRadians, NbOfSteps, Tolerance,
5592 MakeGroups, TotalAngle )
5594 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5595 MakeGroups=False, TotalAngle=False):
5597 Generate new elements by rotation of the elements of object around the axis
5598 theObject object which elements should be sweeped.
5599 It can be a mesh, a sub mesh or a group.
5602 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5603 AngleInRadians: the angle of Rotation
5604 NbOfSteps: number of steps
5605 Tolerance: tolerance
5606 MakeGroups: forces the generation of new groups from existing ones
5607 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5608 of all steps, else - size of each step
5611 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5612 empty list otherwise
5615 return self.RotationSweepObjects([],theObject,[], Axis,
5616 AngleInRadians, NbOfSteps, Tolerance,
5617 MakeGroups, TotalAngle)
5619 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5620 MakeGroups=False, TotalAngle=False):
5622 Generate new elements by rotation of the elements of object around the axis
5623 theObject object which elements should be sweeped.
5624 It can be a mesh, a sub mesh or a group.
5627 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5628 AngleInRadians: the angle of Rotation
5629 NbOfSteps: number of steps
5630 Tolerance: tolerance
5631 MakeGroups: forces the generation of new groups from existing ones
5632 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5633 of all steps, else - size of each step
5636 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5639 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5640 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5642 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5643 scaleFactors=[], linearVariation=False, basePoint=[],
5644 angles=[], anglesVariation=False):
5646 Generate new elements by extrusion of the given elements and nodes
5649 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5650 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5651 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5652 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5653 the direction and value of extrusion for one step (the total extrusion
5654 length will be NbOfSteps * ||StepVector||)
5655 NbOfSteps: the number of steps
5656 MakeGroups: forces the generation of new groups from existing ones
5657 scaleFactors: optional scale factors to apply during extrusion
5658 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5659 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5660 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5661 nodes and elements being extruded is used as the scaling center.
5664 - a list of tree components of the point or
5667 angles: list of angles in radians. Nodes at each extrusion step are rotated
5668 around *basePoint*, additionally to previous steps.
5669 anglesVariation: forces the computation of rotation angles as linear
5670 variation of the given *angles* along path steps
5672 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5674 Example: :ref:`tui_extrusion`
5676 unRegister = genObjUnRegister()
5677 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5678 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5679 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5681 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5682 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5683 if isinstance( StepVector, list ):
5684 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5686 if isinstance( basePoint, int):
5687 xyz = self.GetNodeXYZ( basePoint )
5689 raise RuntimeError("Invalid node ID: %s" % basePoint)
5691 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5692 basePoint = self.geompyD.PointCoordinates( basePoint )
5694 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5695 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5696 angles,angleParameters,hasVars = ParseAngles(angles)
5697 Parameters = StepVector.PS.parameters + var_separator + \
5698 Parameters + var_separator + \
5699 scaleParameters + var_separator + angleParameters
5700 self.mesh.SetParameters(Parameters)
5702 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5703 StepVector, NbOfSteps, MakeGroups,
5704 scaleFactors, linearVariation, basePoint,
5705 angles, anglesVariation )
5708 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5710 Generate new elements by extrusion of the elements with given ids
5713 IDsOfElements: the list of ids of elements or nodes for extrusion
5714 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5715 the direction and value of extrusion for one step (the total extrusion
5716 length will be NbOfSteps * ||StepVector||)
5717 NbOfSteps: the number of steps
5718 MakeGroups: forces the generation of new groups from existing ones
5719 IsNodes: is True if elements with given ids are nodes
5722 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5724 Example: :ref:`tui_extrusion`
5727 if IsNodes: n = IDsOfElements
5728 else : e,f, = IDsOfElements,IDsOfElements
5729 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5731 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5732 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5734 Generate new elements by extrusion along the normal to a discretized surface or wire
5737 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5738 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5739 StepSize: length of one extrusion step (the total extrusion
5740 length will be *NbOfSteps* *StepSize*).
5741 NbOfSteps: number of extrusion steps.
5742 ByAverageNormal: if True each node is translated by *StepSize*
5743 along the average of the normal vectors to the faces sharing the node;
5744 else each node is translated along the same average normal till
5745 intersection with the plane got by translation of the face sharing
5746 the node along its own normal by *StepSize*.
5747 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5748 for every node of *Elements*.
5749 MakeGroups: forces generation of new groups from existing ones.
5750 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5751 is not yet implemented. This parameter is used if *Elements* contains
5752 both faces and edges, i.e. *Elements* is a Mesh.
5755 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5756 empty list otherwise.
5757 Example: :ref:`tui_extrusion`
5760 unRegister = genObjUnRegister()
5761 if isinstance( Elements, Mesh ):
5762 Elements = [ Elements.GetMesh() ]
5763 if isinstance( Elements, list ):
5765 raise RuntimeError("Elements empty!")
5766 if isinstance( Elements[0], Mesh ):
5767 Elements = [ Elements[0].GetMesh() ]
5768 if isinstance( Elements[0], int ):
5769 Elements = self.GetIDSource( Elements, SMESH.ALL )
5770 unRegister.set( Elements )
5771 if not isinstance( Elements, list ):
5772 Elements = [ Elements ]
5773 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5774 self.mesh.SetParameters(Parameters)
5775 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5776 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5778 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5780 Generate new elements by extrusion of the elements or nodes which belong to the object
5783 theObject: the object whose elements or nodes should be processed.
5784 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5785 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5786 the direction and value of extrusion for one step (the total extrusion
5787 length will be NbOfSteps * ||StepVector||)
5788 NbOfSteps: the number of steps
5789 MakeGroups: forces the generation of new groups from existing ones
5790 IsNodes: is True if elements to extrude are nodes
5793 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5794 Example: :ref:`tui_extrusion`
5798 if IsNodes: n = theObject
5799 else : e,f, = theObject,theObject
5800 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5802 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5804 Generate new elements by extrusion of edges which belong to the object
5807 theObject: object whose 1D elements should be processed.
5808 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5809 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5810 the direction and value of extrusion for one step (the total extrusion
5811 length will be NbOfSteps * ||StepVector||)
5812 NbOfSteps: the number of steps
5813 MakeGroups: to generate new groups from existing ones
5816 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5817 Example: :ref:`tui_extrusion`
5820 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5822 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5824 Generate new elements by extrusion of faces which belong to the object
5827 theObject: object whose 2D elements should be processed.
5828 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5829 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5830 the direction and value of extrusion for one step (the total extrusion
5831 length will be NbOfSteps * ||StepVector||)
5832 NbOfSteps: the number of steps
5833 MakeGroups: forces the generation of new groups from existing ones
5836 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5837 Example: :ref:`tui_extrusion`
5840 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5842 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5843 ExtrFlags, SewTolerance, MakeGroups=False):
5845 Generate new elements by extrusion of the elements with given ids
5848 IDsOfElements: is ids of elements
5849 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5850 the direction and value of extrusion for one step (the total extrusion
5851 length will be NbOfSteps * ||StepVector||)
5852 NbOfSteps: the number of steps
5853 ExtrFlags: sets flags for extrusion
5854 SewTolerance: uses for comparing locations of nodes if flag
5855 EXTRUSION_FLAG_SEW is set
5856 MakeGroups: forces the generation of new groups from existing ones
5859 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5862 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5863 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5864 if isinstance( StepVector, list ):
5865 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5866 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5867 ExtrFlags, SewTolerance, MakeGroups)
5869 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5870 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5871 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5872 ScaleFactors=[], ScalesVariation=False):
5874 Generate new elements by extrusion of the given elements and nodes along the path.
5875 The path of extrusion must be a meshed edge.
5878 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5879 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5880 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5881 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5882 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
5883 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5884 HasAngles: not used obsolete
5885 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5886 around *basePoint*, additionally to previous steps.
5887 LinearVariation: forces the computation of rotation angles as linear
5888 variation of the given Angles along path steps
5889 HasRefPoint: allows using the reference point
5890 RefPoint: optional scaling and rotation center (mass center of the extruded
5891 elements by default). The User can specify any point as the Reference Point.
5892 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5893 MakeGroups: forces the generation of new groups from existing ones
5894 ScaleFactors: optional scale factors to apply during extrusion
5895 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5896 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5899 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5900 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5901 Example: :ref:`tui_extrusion_along_path`
5904 unRegister = genObjUnRegister()
5905 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5906 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5907 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5909 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5910 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5911 if isinstance( RefPoint, list ):
5912 if not RefPoint: RefPoint = [0,0,0]
5913 RefPoint = SMESH.PointStruct( *RefPoint )
5914 if isinstance( PathObject, Mesh ):
5915 PathObject = PathObject.GetMesh()
5916 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5917 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5918 Parameters = AnglesParameters + var_separator + \
5919 RefPoint.parameters + var_separator + ScalesParameters
5920 self.mesh.SetParameters(Parameters)
5921 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5922 PathObject, PathShape, NodeStart,
5923 HasAngles, Angles, LinearVariation,
5924 HasRefPoint, RefPoint, MakeGroups,
5925 ScaleFactors, ScalesVariation)
5927 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5928 HasAngles=False, Angles=[], LinearVariation=False,
5929 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5930 ElemType=SMESH.FACE):
5932 Generate new elements by extrusion of the given elements.
5933 The path of extrusion must be a meshed edge.
5936 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5937 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5938 NodeStart: the start node from Path. Defines the direction of extrusion
5939 HasAngles: not used obsolete
5940 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5941 around *basePoint*, additionally to previous steps.
5942 LinearVariation: forces the computation of rotation angles as linear
5943 variation of the given Angles along path steps
5944 HasRefPoint: allows using the reference point
5945 RefPoint: the reference point around which the elements are rotated (the mass
5946 center of the elements by default).
5947 The User can specify any point as the Reference Point.
5948 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5949 MakeGroups: forces the generation of new groups from existing ones
5950 ElemType: type of elements for extrusion (if param Base is a mesh)
5953 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5954 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5955 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5957 Example: :ref:`tui_extrusion_along_path`
5961 if ElemType == SMESH.NODE: n = Base
5962 if ElemType == SMESH.EDGE: e = Base
5963 if ElemType == SMESH.FACE: f = Base
5964 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5965 HasAngles, Angles, LinearVariation,
5966 HasRefPoint, RefPoint, MakeGroups)
5967 if MakeGroups: return gr,er
5970 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5971 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5972 MakeGroups=False, LinearVariation=False):
5974 Generate new elements by extrusion of the given elements.
5975 The path of extrusion must be a meshed edge.
5978 IDsOfElements: ids of elements
5979 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5980 PathShape: shape (edge) defines the sub-mesh for the path
5981 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5982 HasAngles: not used obsolete
5983 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5984 around *basePoint*, additionally to previous steps.
5985 HasRefPoint: allows using the reference point
5986 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5987 The User can specify any point as the Reference Point.
5988 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5989 MakeGroups: forces the generation of new groups from existing ones
5990 LinearVariation: forces the computation of rotation angles as linear
5991 variation of the given Angles along path steps
5994 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5995 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5996 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5997 Example: :ref:`tui_extrusion_along_path`
6000 if not IDsOfElements:
6001 IDsOfElements = [ self.GetMesh() ]
6002 n,e,f = [],IDsOfElements,IDsOfElements
6003 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
6004 NodeStart, HasAngles, Angles,
6006 HasRefPoint, RefPoint, MakeGroups)
6007 if MakeGroups: return gr,er
6010 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
6011 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6012 MakeGroups=False, LinearVariation=False):
6014 Generate new elements by extrusion of the elements which belong to the object.
6015 The path of extrusion must be a meshed edge.
6018 theObject: the object whose elements should be processed.
6019 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6020 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6021 PathShape: shape (edge) defines the sub-mesh for the path
6022 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6023 HasAngles: not used obsolete
6024 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6025 around *basePoint*, additionally to previous steps.
6026 HasRefPoint: allows using the reference point
6027 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6028 The User can specify any point as the Reference Point.
6029 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6030 MakeGroups: forces the generation of new groups from existing ones
6031 LinearVariation: forces the computation of rotation angles as linear
6032 variation of the given Angles along path steps
6035 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6036 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6037 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6038 Example: :ref:`tui_extrusion_along_path`
6041 n,e,f = [],theObject,theObject
6042 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6043 HasAngles, Angles, LinearVariation,
6044 HasRefPoint, RefPoint, MakeGroups)
6045 if MakeGroups: return gr,er
6048 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
6049 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6050 MakeGroups=False, LinearVariation=False):
6052 Generate new elements by extrusion of mesh segments which belong to the object.
6053 The path of extrusion must be a meshed edge.
6056 theObject: the object whose 1D elements should be processed.
6057 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6058 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6059 PathShape: shape (edge) defines the sub-mesh for the path
6060 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6061 HasAngles: not used obsolete
6062 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6063 around *basePoint*, additionally to previous steps.
6064 HasRefPoint: allows using the reference point
6065 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6066 The User can specify any point as the Reference Point.
6067 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6068 MakeGroups: forces the generation of new groups from existing ones
6069 LinearVariation: forces the computation of rotation angles as linear
6070 variation of the given Angles along path steps
6073 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6074 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6075 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6076 Example: :ref:`tui_extrusion_along_path`
6079 n,e,f = [],theObject,[]
6080 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6081 HasAngles, Angles, LinearVariation,
6082 HasRefPoint, RefPoint, MakeGroups)
6083 if MakeGroups: return gr,er
6086 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6087 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6088 MakeGroups=False, LinearVariation=False):
6090 Generate new elements by extrusion of faces which belong to the object.
6091 The path of extrusion must be a meshed edge.
6094 theObject: the object whose 2D elements should be processed.
6095 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6096 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6097 PathShape: shape (edge) defines the sub-mesh for the path
6098 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6099 HasAngles: not used obsolete
6100 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6101 around *basePoint*, additionally to previous steps.
6102 HasRefPoint: allows using the reference point
6103 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6104 The User can specify any point as the Reference Point.
6105 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6106 MakeGroups: forces the generation of new groups from existing ones
6107 LinearVariation: forces the computation of rotation angles as linear
6108 variation of the given Angles along path steps
6111 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6112 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6113 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6114 Example: :ref:`tui_extrusion_along_path`
6117 n,e,f = [],[],theObject
6118 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6119 HasAngles, Angles, LinearVariation,
6120 HasRefPoint, RefPoint, MakeGroups)
6121 if MakeGroups: return gr,er
6124 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6126 Create a symmetrical copy of mesh elements
6129 IDsOfElements: list of elements ids
6130 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6131 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6132 If the *Mirror* is a geom object this parameter is unnecessary
6133 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6134 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6137 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6140 if IDsOfElements == []:
6141 IDsOfElements = self.GetElementsId()
6142 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6143 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6144 theMirrorType = Mirror._mirrorType
6146 self.mesh.SetParameters(Mirror.parameters)
6147 if Copy and MakeGroups:
6148 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6149 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6152 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6154 Create a new mesh by a symmetrical copy of mesh elements
6157 IDsOfElements: the list of elements ids
6158 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6159 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6160 If the *Mirror* is a geom object this parameter is unnecessary
6161 MakeGroups: to generate new groups from existing ones
6162 NewMeshName: a name of the new mesh to create
6165 instance of class :class:`Mesh`
6168 if IDsOfElements == []:
6169 IDsOfElements = self.GetElementsId()
6170 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6171 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6172 theMirrorType = Mirror._mirrorType
6174 self.mesh.SetParameters(Mirror.parameters)
6175 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6176 MakeGroups, NewMeshName)
6177 return Mesh(self.smeshpyD,self.geompyD,mesh)
6179 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6181 Create a symmetrical copy of the object
6184 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6185 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6186 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6187 If the *Mirror* is a geom object this parameter is unnecessary
6188 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6189 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6192 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6195 if ( isinstance( theObject, Mesh )):
6196 theObject = theObject.GetMesh()
6197 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6198 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6199 theMirrorType = Mirror._mirrorType
6201 self.mesh.SetParameters(Mirror.parameters)
6202 if Copy and MakeGroups:
6203 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6204 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6207 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6209 Create a new mesh by a symmetrical copy of the object
6212 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6213 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6214 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6215 If the *Mirror* is a geom object this parameter is unnecessary
6216 MakeGroups: forces the generation of new groups from existing ones
6217 NewMeshName: the name of the new mesh to create
6220 instance of class :class:`Mesh`
6223 if ( isinstance( theObject, Mesh )):
6224 theObject = theObject.GetMesh()
6225 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6226 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6227 theMirrorType = Mirror._mirrorType
6229 self.mesh.SetParameters(Mirror.parameters)
6230 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6231 MakeGroups, NewMeshName)
6232 return Mesh( self.smeshpyD,self.geompyD,mesh )
6234 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6236 Translate the elements
6239 IDsOfElements: list of elements ids
6240 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6241 Copy: allows copying the translated elements
6242 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6245 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6248 if IDsOfElements == []:
6249 IDsOfElements = self.GetElementsId()
6250 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6251 Vector = self.smeshpyD.GetDirStruct(Vector)
6252 if isinstance( Vector, list ):
6253 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6254 self.mesh.SetParameters(Vector.PS.parameters)
6255 if Copy and MakeGroups:
6256 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6257 self.editor.Translate(IDsOfElements, Vector, Copy)
6260 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6262 Create a new mesh of translated elements
6265 IDsOfElements: list of elements ids
6266 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6267 MakeGroups: forces the generation of new groups from existing ones
6268 NewMeshName: the name of the newly created mesh
6271 instance of class :class:`Mesh`
6274 if IDsOfElements == []:
6275 IDsOfElements = self.GetElementsId()
6276 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6277 Vector = self.smeshpyD.GetDirStruct(Vector)
6278 if isinstance( Vector, list ):
6279 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6280 self.mesh.SetParameters(Vector.PS.parameters)
6281 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6282 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6284 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6286 Translate the object
6289 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6290 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6291 Copy: allows copying the translated elements
6292 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6295 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6298 if ( isinstance( theObject, Mesh )):
6299 theObject = theObject.GetMesh()
6300 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6301 Vector = self.smeshpyD.GetDirStruct(Vector)
6302 if isinstance( Vector, list ):
6303 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6304 self.mesh.SetParameters(Vector.PS.parameters)
6305 if Copy and MakeGroups:
6306 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6307 self.editor.TranslateObject(theObject, Vector, Copy)
6310 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6312 Create a new mesh from the translated object
6315 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6316 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6317 MakeGroups: forces the generation of new groups from existing ones
6318 NewMeshName: the name of the newly created mesh
6321 instance of class :class:`Mesh`
6324 if isinstance( theObject, Mesh ):
6325 theObject = theObject.GetMesh()
6326 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6327 Vector = self.smeshpyD.GetDirStruct(Vector)
6328 if isinstance( Vector, list ):
6329 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6330 self.mesh.SetParameters(Vector.PS.parameters)
6331 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6332 return Mesh( self.smeshpyD, self.geompyD, mesh )
6336 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6341 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6342 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6343 theScaleFact: list of 1-3 scale factors for axises
6344 Copy: allows copying the translated elements
6345 MakeGroups: forces the generation of new groups from existing
6349 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6350 empty list otherwise
6352 unRegister = genObjUnRegister()
6353 if ( isinstance( theObject, Mesh )):
6354 theObject = theObject.GetMesh()
6355 if ( isinstance( theObject, list )):
6356 theObject = self.GetIDSource(theObject, SMESH.ALL)
6357 unRegister.set( theObject )
6358 if ( isinstance( thePoint, list )):
6359 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6360 if ( isinstance( theScaleFact, float )):
6361 theScaleFact = [theScaleFact]
6362 if ( isinstance( theScaleFact, int )):
6363 theScaleFact = [ float(theScaleFact)]
6365 self.mesh.SetParameters(thePoint.parameters)
6367 if Copy and MakeGroups:
6368 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6369 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6372 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6374 Create a new mesh from the translated object
6377 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6378 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6379 theScaleFact: list of 1-3 scale factors for axises
6380 MakeGroups: forces the generation of new groups from existing ones
6381 NewMeshName: the name of the newly created mesh
6384 instance of class :class:`Mesh`
6386 unRegister = genObjUnRegister()
6387 if (isinstance(theObject, Mesh)):
6388 theObject = theObject.GetMesh()
6389 if ( isinstance( theObject, list )):
6390 theObject = self.GetIDSource(theObject,SMESH.ALL)
6391 unRegister.set( theObject )
6392 if ( isinstance( thePoint, list )):
6393 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6394 if ( isinstance( theScaleFact, float )):
6395 theScaleFact = [theScaleFact]
6396 if ( isinstance( theScaleFact, int )):
6397 theScaleFact = [ float(theScaleFact)]
6399 self.mesh.SetParameters(thePoint.parameters)
6400 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6401 MakeGroups, NewMeshName)
6402 return Mesh( self.smeshpyD, self.geompyD, mesh )
6406 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6411 IDsOfElements: list of elements ids
6412 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6413 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6414 Copy: allows copying the rotated elements
6415 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6418 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6422 if IDsOfElements == []:
6423 IDsOfElements = self.GetElementsId()
6424 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6425 Axis = self.smeshpyD.GetAxisStruct(Axis)
6426 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6427 Parameters = Axis.parameters + var_separator + Parameters
6428 self.mesh.SetParameters(Parameters)
6429 if Copy and MakeGroups:
6430 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6431 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6434 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6436 Create a new mesh of rotated elements
6439 IDsOfElements: list of element ids
6440 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6441 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6442 MakeGroups: forces the generation of new groups from existing ones
6443 NewMeshName: the name of the newly created mesh
6446 instance of class :class:`Mesh`
6449 if IDsOfElements == []:
6450 IDsOfElements = self.GetElementsId()
6451 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6452 Axis = self.smeshpyD.GetAxisStruct(Axis)
6453 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6454 Parameters = Axis.parameters + var_separator + Parameters
6455 self.mesh.SetParameters(Parameters)
6456 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6457 MakeGroups, NewMeshName)
6458 return Mesh( self.smeshpyD, self.geompyD, mesh )
6460 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6465 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6466 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6467 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6468 Copy: allows copying the rotated elements
6469 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6472 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6475 if (isinstance(theObject, Mesh)):
6476 theObject = theObject.GetMesh()
6477 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6478 Axis = self.smeshpyD.GetAxisStruct(Axis)
6479 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6480 Parameters = Axis.parameters + ":" + Parameters
6481 self.mesh.SetParameters(Parameters)
6482 if Copy and MakeGroups:
6483 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6484 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6487 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6489 Create a new mesh from the rotated object
6492 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6493 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6494 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6495 MakeGroups: forces the generation of new groups from existing ones
6496 NewMeshName: the name of the newly created mesh
6499 instance of class :class:`Mesh`
6502 if (isinstance( theObject, Mesh )):
6503 theObject = theObject.GetMesh()
6504 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6505 Axis = self.smeshpyD.GetAxisStruct(Axis)
6506 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6507 Parameters = Axis.parameters + ":" + Parameters
6508 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6509 MakeGroups, NewMeshName)
6510 self.mesh.SetParameters(Parameters)
6511 return Mesh( self.smeshpyD, self.geompyD, mesh )
6513 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6515 Create an offset mesh from the given 2D object
6518 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6519 theValue (float): signed offset size
6520 MakeGroups (boolean): forces the generation of new groups from existing ones
6521 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6522 False means to remove original elements.
6523 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6526 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6529 if isinstance( theObject, Mesh ):
6530 theObject = theObject.GetMesh()
6531 theValue,Parameters,hasVars = ParseParameters(Value)
6532 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6533 self.mesh.SetParameters(Parameters)
6535 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6538 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6540 Find groups of adjacent nodes within Tolerance.
6543 Tolerance (float): the value of tolerance
6544 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6545 corner and medium nodes in separate groups thus preventing
6546 their further merge.
6549 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6552 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6554 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6555 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6557 Find groups of adjacent nodes within Tolerance.
6560 Tolerance: the value of tolerance
6561 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6562 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6563 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6564 corner and medium nodes in separate groups thus preventing
6565 their further merge.
6568 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6571 unRegister = genObjUnRegister()
6572 if not isinstance( SubMeshOrGroup, list ):
6573 SubMeshOrGroup = [ SubMeshOrGroup ]
6574 for i,obj in enumerate( SubMeshOrGroup ):
6575 if isinstance( obj, Mesh ):
6576 SubMeshOrGroup = [ obj.GetMesh() ]
6578 if isinstance( obj, int ):
6579 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6580 unRegister.set( SubMeshOrGroup )
6583 if not isinstance( exceptNodes, list ):
6584 exceptNodes = [ exceptNodes ]
6585 if exceptNodes and isinstance( exceptNodes[0], int ):
6586 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6587 unRegister.set( exceptNodes )
6589 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6590 exceptNodes, SeparateCornerAndMediumNodes)
6592 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6597 GroupsOfNodes: a list of groups of nodes IDs for merging.
6598 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6599 in all elements and mesh groups by nodes 1 and 25 correspondingly
6600 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6601 If *NodesToKeep* does not include a node to keep for some group to merge,
6602 then the first node in the group is kept.
6603 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6607 This operation can create gaps in numeration of nodes or elements.
6608 Call :meth:`RenumberElements` to remove the gaps.
6610 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6612 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6614 Find the elements built on the same nodes.
6617 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6618 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6622 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6625 unRegister = genObjUnRegister()
6626 if MeshOrSubMeshOrGroup is None:
6627 MeshOrSubMeshOrGroup = [ self.mesh ]
6628 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6629 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6630 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6631 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6632 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6633 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6634 unRegister.set( MeshOrSubMeshOrGroup )
6635 for item in MeshOrSubMeshOrGroup:
6636 if isinstance( item, Mesh ):
6637 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6639 if not isinstance( exceptElements, list ):
6640 exceptElements = [ exceptElements ]
6641 if exceptElements and isinstance( exceptElements[0], int ):
6642 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6643 unRegister.set( exceptElements )
6645 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6647 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6649 Merge elements in each given group.
6652 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6653 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6654 replaced in all mesh groups by elements 1 and 25)
6655 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6656 If *ElementsToKeep* does not include an element to keep for some group to merge,
6657 then the first element in the group is kept.
6660 This operation can create gaps in numeration of elements.
6661 Call :meth:`RenumberElements` to remove the gaps.
6664 unRegister = genObjUnRegister()
6666 if not isinstance( ElementsToKeep, list ):
6667 ElementsToKeep = [ ElementsToKeep ]
6668 if isinstance( ElementsToKeep[0], int ):
6669 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6670 unRegister.set( ElementsToKeep )
6672 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6674 def MergeEqualElements(self):
6676 Leave one element and remove all other elements built on the same nodes.
6679 This operation can create gaps in numeration of elements.
6680 Call :meth:`RenumberElements` to remove the gaps.
6683 self.editor.MergeEqualElements()
6685 def FindFreeBorders(self, ClosedOnly=True):
6687 Returns all or only closed free borders
6690 list of SMESH.FreeBorder's
6693 return self.editor.FindFreeBorders( ClosedOnly )
6695 def FillHole(self, holeNodes, groupName=""):
6697 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6700 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6701 must describe all sequential nodes of the hole border. The first and the last
6702 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6703 groupName (string): name of a group to add new faces
6705 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6709 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6710 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6711 if not isinstance( holeNodes, SMESH.FreeBorder ):
6712 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6713 return self.editor.FillHole( holeNodes, groupName )
6715 def FindCoincidentFreeBorders (self, tolerance=0.):
6717 Return groups of FreeBorder's coincident within the given tolerance.
6720 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6721 size of elements adjacent to free borders being compared is used.
6724 SMESH.CoincidentFreeBorders structure
6727 return self.editor.FindCoincidentFreeBorders( tolerance )
6729 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6731 Sew FreeBorder's of each group
6734 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6735 where each enclosed list contains node IDs of a group of coincident free
6736 borders such that each consequent triple of IDs within a group describes
6737 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6738 last node of a border.
6739 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6740 groups of coincident free borders, each group including two borders.
6741 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6742 polygons if a node of opposite border falls on a face edge, else such
6743 faces are split into several ones.
6744 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6745 polyhedra if a node of opposite border falls on a volume edge, else such
6746 volumes, if any, remain intact and the mesh becomes non-conformal.
6749 a number of successfully sewed groups
6752 This operation can create gaps in numeration of nodes or elements.
6753 Call :meth:`RenumberElements` to remove the gaps.
6756 if freeBorders and isinstance( freeBorders, list ):
6757 # construct SMESH.CoincidentFreeBorders
6758 if isinstance( freeBorders[0], int ):
6759 freeBorders = [freeBorders]
6761 coincidentGroups = []
6762 for nodeList in freeBorders:
6763 if not nodeList or len( nodeList ) % 3:
6764 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6767 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6768 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6769 nodeList = nodeList[3:]
6771 coincidentGroups.append( group )
6773 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6775 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6777 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6778 FirstNodeID2, SecondNodeID2, LastNodeID2,
6779 CreatePolygons, CreatePolyedrs):
6784 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6787 This operation can create gaps in numeration of nodes or elements.
6788 Call :meth:`RenumberElements` to remove the gaps.
6791 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6792 FirstNodeID2, SecondNodeID2, LastNodeID2,
6793 CreatePolygons, CreatePolyedrs)
6795 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6796 FirstNodeID2, SecondNodeID2):
6798 Sew conform free borders
6801 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6804 This operation can create gaps in numeration of elements.
6805 Call :meth:`RenumberElements` to remove the gaps.
6808 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6809 FirstNodeID2, SecondNodeID2)
6811 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6812 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6817 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6820 This operation can create gaps in numeration of elements.
6821 Call :meth:`RenumberElements` to remove the gaps.
6824 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6825 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6827 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6828 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6829 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6831 Sew two sides of a mesh. The nodes belonging to Side1 are
6832 merged with the nodes of elements of Side2.
6833 The number of elements in theSide1 and in theSide2 must be
6834 equal and they should have similar nodal connectivity.
6835 The nodes to merge should belong to side borders and
6836 the first node should be linked to the second.
6839 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6842 This operation can create gaps in numeration of nodes.
6843 Call :meth:`RenumberElements` to remove the gaps.
6846 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6847 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6848 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6850 def ChangeElemNodes(self, ide, newIDs):
6852 Set new nodes for the given element. Number of nodes should be kept.
6859 False if the number of nodes does not correspond to the type of element
6862 return self.editor.ChangeElemNodes(ide, newIDs)
6864 def GetLastCreatedNodes(self):
6866 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6867 created, this method return the list of their IDs.
6868 If new nodes were not created - return empty list
6871 the list of integer values (can be empty)
6874 return self.editor.GetLastCreatedNodes()
6876 def GetLastCreatedElems(self):
6878 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6879 created this method return the list of their IDs.
6880 If new elements were not created - return empty list
6883 the list of integer values (can be empty)
6886 return self.editor.GetLastCreatedElems()
6888 def ClearLastCreated(self):
6890 Forget what nodes and elements were created by the last mesh edition operation
6893 self.editor.ClearLastCreated()
6895 def DoubleElements(self, theElements, theGroupName=""):
6897 Create duplicates of given elements, i.e. create new elements based on the
6898 same nodes as the given ones.
6901 theElements: container of elements to duplicate. It can be a
6902 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6903 or a list of element IDs. If *theElements* is
6904 a :class:`Mesh`, elements of highest dimension are duplicated
6905 theGroupName: a name of group to contain the generated elements.
6906 If a group with such a name already exists, the new elements
6907 are added to the existing group, else a new group is created.
6908 If *theGroupName* is empty, new elements are not added
6912 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6913 None if *theGroupName* == "".
6916 unRegister = genObjUnRegister()
6917 if isinstance( theElements, Mesh ):
6918 theElements = theElements.mesh
6919 elif isinstance( theElements, list ):
6920 theElements = self.GetIDSource( theElements, SMESH.ALL )
6921 unRegister.set( theElements )
6922 return self.editor.DoubleElements(theElements, theGroupName)
6924 def DoubleNodes(self, theNodes, theModifiedElems):
6926 Create a hole in a mesh by doubling the nodes of some particular elements
6929 theNodes: IDs of nodes to be doubled
6930 theModifiedElems: IDs of elements to be updated by the new (doubled)
6931 nodes. If list of element identifiers is empty then nodes are doubled but
6932 they not assigned to elements
6935 True if operation has been completed successfully, False otherwise
6938 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6940 def DoubleNode(self, theNodeId, theModifiedElems):
6942 Create a hole in a mesh by doubling the nodes of some particular elements.
6943 This method provided for convenience works as :meth:`DoubleNodes`.
6946 theNodeId: IDs of node to double
6947 theModifiedElems: IDs of elements to update
6950 True if operation has been completed successfully, False otherwise
6953 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6955 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6957 Create a hole in a mesh by doubling the nodes of some particular elements.
6958 This method provided for convenience works as :meth:`DoubleNodes`.
6961 theNodes: group of nodes to double.
6962 theModifiedElems: group of elements to update.
6963 theMakeGroup: forces the generation of a group containing new nodes.
6966 True or a created group if operation has been completed successfully,
6967 False or None otherwise
6971 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6972 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6974 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6976 Create a hole in a mesh by doubling the nodes of some particular elements.
6977 This method provided for convenience works as :meth:`DoubleNodes`.
6980 theNodes: list of groups of nodes to double.
6981 theModifiedElems: list of groups of elements to update.
6982 theMakeGroup: forces the generation of a group containing new nodes.
6985 True if operation has been completed successfully, False otherwise
6989 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6990 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6992 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6994 Create a hole in a mesh by doubling the nodes of some particular elements
6997 theElems: the list of elements (edges or faces) to replicate.
6998 The nodes for duplication could be found from these elements
6999 theNodesNot: list of nodes NOT to replicate
7000 theAffectedElems: the list of elements (cells and edges) to which the
7001 replicated nodes should be associated to
7004 True if operation has been completed successfully, False otherwise
7007 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
7009 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
7011 Create a hole in a mesh by doubling the nodes of some particular elements
7014 theElems: the list of elements (edges or faces) to replicate.
7015 The nodes for duplication could be found from these elements
7016 theNodesNot: list of nodes NOT to replicate
7017 theShape: shape to detect affected elements (element which geometric center
7018 located on or inside shape).
7019 The replicated nodes should be associated to affected elements.
7022 True if operation has been completed successfully, False otherwise
7025 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
7027 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
7028 theMakeGroup=False, theMakeNodeGroup=False):
7030 Create a hole in a mesh by doubling the nodes of some particular elements.
7031 This method provided for convenience works as :meth:`DoubleNodes`.
7034 theElems: group of of elements (edges or faces) to replicate.
7035 theNodesNot: group of nodes NOT to replicate.
7036 theAffectedElems: group of elements to which the replicated nodes
7037 should be associated to.
7038 theMakeGroup: forces the generation of a group containing new elements.
7039 theMakeNodeGroup: forces the generation of a group containing new nodes.
7042 True or created groups (one or two) if operation has been completed successfully,
7043 False or None otherwise
7046 if theMakeGroup or theMakeNodeGroup:
7047 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
7049 theMakeGroup, theMakeNodeGroup)
7050 if theMakeGroup and theMakeNodeGroup:
7053 return twoGroups[ int(theMakeNodeGroup) ]
7054 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7056 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7058 Create a hole in a mesh by doubling the nodes of some particular elements.
7059 This method provided for convenience works as :meth:`DoubleNodes`.
7062 theElems: group of of elements (edges or faces) to replicate
7063 theNodesNot: group of nodes not to replicate
7064 theShape: shape to detect affected elements (element which geometric center
7065 located on or inside shape).
7066 The replicated nodes should be associated to affected elements
7069 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7071 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7072 theMakeGroup=False, theMakeNodeGroup=False):
7074 Create a hole in a mesh by doubling the nodes of some particular elements.
7075 This method provided for convenience works as :meth:`DoubleNodes`.
7078 theElems: list of groups of elements (edges or faces) to replicate
7079 theNodesNot: list of groups of nodes NOT to replicate
7080 theAffectedElems: group of elements to which the replicated nodes
7081 should be associated to
7082 theMakeGroup: forces generation of a group containing new elements.
7083 theMakeNodeGroup: forces generation of a group containing new nodes
7086 True or created groups (one or two) if operation has been completed successfully,
7087 False or None otherwise
7090 if theMakeGroup or theMakeNodeGroup:
7091 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7093 theMakeGroup, theMakeNodeGroup)
7094 if theMakeGroup and theMakeNodeGroup:
7097 return twoGroups[ int(theMakeNodeGroup) ]
7098 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7100 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7102 Create a hole in a mesh by doubling the nodes of some particular elements.
7103 This method provided for convenience works as :meth:`DoubleNodes`.
7106 theElems: list of groups of elements (edges or faces) to replicate
7107 theNodesNot: list of groups of nodes NOT to replicate
7108 theShape: shape to detect affected elements (element which geometric center
7109 located on or inside shape).
7110 The replicated nodes should be associated to affected elements
7113 True if operation has been completed successfully, False otherwise
7116 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7118 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7120 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7121 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7124 theElems: list of groups of nodes or elements (edges or faces) to replicate
7125 theNodesNot: list of groups of nodes NOT to replicate
7126 theShape: shape to detect affected elements (element which geometric center
7127 located on or inside shape).
7128 The replicated nodes should be associated to affected elements
7131 groups of affected elements in order: volumes, faces, edges
7134 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7136 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7139 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7140 The list of groups must describe a partition of the mesh volumes.
7141 The nodes of the internal faces at the boundaries of the groups are doubled.
7142 In option, the internal faces are replaced by flat elements.
7143 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7146 theDomains: list of groups of volumes
7147 createJointElems: if True, create the elements
7148 onAllBoundaries: if True, the nodes and elements are also created on
7149 the boundary between *theDomains* and the rest mesh
7152 True if operation has been completed successfully, False otherwise
7155 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7157 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7159 Double nodes on some external faces and create flat elements.
7160 Flat elements are mainly used by some types of mechanic calculations.
7162 Each group of the list must be constituted of faces.
7163 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7166 theGroupsOfFaces: list of groups of faces
7169 True if operation has been completed successfully, False otherwise
7172 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7174 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7176 Identify all the elements around a geom shape, get the faces delimiting the hole
7178 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7180 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7182 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7183 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7184 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7185 If there are several paths connecting a pair of points, the shortest path is
7186 selected by the module. Position of the cutting plane is defined by the two
7187 points and an optional vector lying on the plane specified by a PolySegment.
7188 By default the vector is defined by Mesh module as following. A middle point
7189 of the two given points is computed. The middle point is projected to the mesh.
7190 The vector goes from the middle point to the projection point. In case of planar
7191 mesh, the vector is normal to the mesh.
7193 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7196 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7197 groupName: optional name of a group where created mesh segments will be added.
7200 editor = self.editor
7202 editor = self.mesh.GetMeshEditPreviewer()
7203 segmentsRes = editor.MakePolyLine( segments, groupName )
7204 for i, seg in enumerate( segmentsRes ):
7205 segments[i].vector = seg.vector
7207 return editor.GetPreviewData()
7210 def MakeSlot(self, segmentGroup, width ):
7212 Create a slot of given width around given 1D elements lying on a triangle mesh.
7213 The slot is constructed by cutting faces by cylindrical surfaces made
7214 around each segment. Segments are expected to be created by MakePolyLine().
7217 FaceEdge's located at the slot boundary
7219 return self.editor.MakeSlot( segmentGroup, width )
7221 def GetFunctor(self, funcType ):
7223 Return a cached numerical functor by its type.
7226 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7227 Note that not all items correspond to numerical functors.
7230 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7233 fn = self.functors[ funcType._v ]
7235 fn = self.smeshpyD.GetFunctor(funcType)
7236 fn.SetMesh(self.mesh)
7237 self.functors[ funcType._v ] = fn
7240 def FunctorValue(self, funcType, elemId, isElem=True):
7242 Return value of a functor for a given element
7245 funcType: an item of :class:`SMESH.FunctorType` enum.
7246 elemId: element or node ID
7247 isElem: *elemId* is ID of element or node
7250 the functor value or zero in case of invalid arguments
7253 fn = self.GetFunctor( funcType )
7254 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7255 val = fn.GetValue(elemId)
7260 def GetLength(self, elemId=None):
7262 Get length of given 1D elements or of all 1D mesh elements
7265 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.
7268 Sum of lengths of given elements
7273 length = self.smeshpyD.GetLength(self)
7274 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7275 length = self.smeshpyD.GetLength(elemId)
7278 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7280 length += self.smeshpyD.GetLength(obj)
7281 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7282 unRegister = genObjUnRegister()
7283 obj = self.GetIDSource( elemId )
7284 unRegister.set( obj )
7285 length = self.smeshpyD.GetLength( obj )
7287 length = self.FunctorValue(SMESH.FT_Length, elemId)
7290 def GetArea(self, elemId=None):
7292 Get area of given 2D elements or of all 2D mesh elements
7295 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.
7298 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7303 area = self.smeshpyD.GetArea(self)
7304 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7305 area = self.smeshpyD.GetArea(elemId)
7308 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7310 area += self.smeshpyD.GetArea(obj)
7311 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7312 unRegister = genObjUnRegister()
7313 obj = self.GetIDSource( elemId )
7314 unRegister.set( obj )
7315 area = self.smeshpyD.GetArea( obj )
7317 area = self.FunctorValue(SMESH.FT_Area, elemId)
7320 def GetVolume(self, elemId=None):
7322 Get volume of given 3D elements or of all 3D mesh elements
7325 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.
7328 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7333 volume= self.smeshpyD.GetVolume(self)
7334 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7335 volume= self.smeshpyD.GetVolume(elemId)
7338 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7340 volume+= self.smeshpyD.GetVolume(obj)
7341 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7342 unRegister = genObjUnRegister()
7343 obj = self.GetIDSource( elemId )
7344 unRegister.set( obj )
7345 volume= self.smeshpyD.GetVolume( obj )
7347 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7350 def GetAngle(self, node1, node2, node3 ):
7352 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7355 node1,node2,node3: IDs of the three nodes
7358 Angle in radians [0,PI]. -1 if failure case.
7360 p1 = self.GetNodeXYZ( node1 )
7361 p2 = self.GetNodeXYZ( node2 )
7362 p3 = self.GetNodeXYZ( node3 )
7363 if p1 and p2 and p3:
7364 return self.smeshpyD.GetAngle( p1,p2,p3 )
7368 def GetMaxElementLength(self, elemId):
7370 Get maximum element length.
7373 elemId: mesh element ID
7376 element's maximum length value
7379 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7380 ftype = SMESH.FT_MaxElementLength3D
7382 ftype = SMESH.FT_MaxElementLength2D
7383 return self.FunctorValue(ftype, elemId)
7385 def GetAspectRatio(self, elemId):
7387 Get aspect ratio of 2D or 3D element.
7390 elemId: mesh element ID
7393 element's aspect ratio value
7396 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7397 ftype = SMESH.FT_AspectRatio3D
7399 ftype = SMESH.FT_AspectRatio
7400 return self.FunctorValue(ftype, elemId)
7402 def GetWarping(self, elemId):
7404 Get warping angle of 2D element.
7407 elemId: mesh element ID
7410 element's warping angle value
7413 return self.FunctorValue(SMESH.FT_Warping, elemId)
7415 def GetMinimumAngle(self, elemId):
7417 Get minimum angle of 2D element.
7420 elemId: mesh element ID
7423 element's minimum angle value
7426 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7428 def GetTaper(self, elemId):
7430 Get taper of 2D element.
7433 elemId: mesh element ID
7436 element's taper value
7439 return self.FunctorValue(SMESH.FT_Taper, elemId)
7441 def GetSkew(self, elemId):
7443 Get skew of 2D element.
7446 elemId: mesh element ID
7449 element's skew value
7452 return self.FunctorValue(SMESH.FT_Skew, elemId)
7454 def GetMinMax(self, funType, meshPart=None):
7456 Return minimal and maximal value of a given functor.
7459 funType (SMESH.FunctorType): a functor type.
7460 Note that not all items of :class:`SMESH.FunctorType` corresponds
7461 to numerical functors.
7462 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7468 unRegister = genObjUnRegister()
7469 if isinstance( meshPart, list ):
7470 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7471 unRegister.set( meshPart )
7472 if isinstance( meshPart, Mesh ):
7473 meshPart = meshPart.mesh
7474 fun = self.GetFunctor( funType )
7477 if hasattr( meshPart, "SetMesh" ):
7478 meshPart.SetMesh( self.mesh ) # set mesh to filter
7479 hist = fun.GetLocalHistogram( 1, False, meshPart )
7481 hist = fun.GetHistogram( 1, False )
7483 return hist[0].min, hist[0].max
7486 pass # end of Mesh class
7489 class meshProxy(SMESH._objref_SMESH_Mesh):
7491 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7492 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7494 def __init__(self,*args):
7495 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7496 def __deepcopy__(self, memo=None):
7497 new = self.__class__(self)
7499 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7500 if len( args ) == 3:
7501 args += SMESH.ALL_NODES, True
7502 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7503 def ExportToMEDX(self, *args): # function removed
7504 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7505 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7506 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7507 def ExportToMED(self, *args): # function removed
7508 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7509 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7511 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7513 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7514 def ExportPartToMED(self, *args): # 'version' parameter removed
7515 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7516 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7517 def ExportMED(self, *args): # signature of method changed
7518 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7520 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7522 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7523 def ExportUNV(self, *args): # renumber arg added
7524 if len( args ) == 1:
7526 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
7527 def ExportDAT(self, *args): # renumber arg added
7528 if len( args ) == 1:
7530 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
7532 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7535 class submeshProxy(SMESH._objref_SMESH_subMesh):
7538 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7540 def __init__(self,*args):
7541 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7543 def __deepcopy__(self, memo=None):
7544 new = self.__class__(self)
7547 def Compute(self,refresh=False):
7549 Compute the sub-mesh and return the status of the computation
7552 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7557 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7558 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7562 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7564 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7566 if salome.sg.hasDesktop():
7567 if refresh: salome.sg.updateObjBrowser()
7572 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7575 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7577 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7578 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7581 def __init__(self,*args):
7582 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7584 def __getattr__(self, name ): # method called if an attribute not found
7585 if not self.mesh: # look for name() method in Mesh class
7586 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7587 if hasattr( self.mesh, name ):
7588 return getattr( self.mesh, name )
7589 if name == "ExtrusionAlongPathObjX":
7590 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7591 print("meshEditor: attribute '%s' NOT FOUND" % name)
7593 def __deepcopy__(self, memo=None):
7594 new = self.__class__(self)
7596 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7597 if len( args ) == 1: args += False,
7598 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7599 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7600 if len( args ) == 2: args += False,
7601 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7602 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7603 if len( args ) == 1:
7604 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7605 NodesToKeep = args[1]
7606 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7607 unRegister = genObjUnRegister()
7609 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7610 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7611 if not isinstance( NodesToKeep, list ):
7612 NodesToKeep = [ NodesToKeep ]
7613 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7615 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7617 class Pattern(SMESH._objref_SMESH_Pattern):
7619 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7620 variables in some methods
7623 def LoadFromFile(self, patternTextOrFile ):
7624 text = patternTextOrFile
7625 if os.path.exists( text ):
7626 text = open( patternTextOrFile ).read()
7628 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7630 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7631 decrFun = lambda i: i-1
7632 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7633 theMesh.SetParameters(Parameters)
7634 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7636 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7637 decrFun = lambda i: i-1
7638 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7639 theMesh.SetParameters(Parameters)
7640 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7642 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7643 if isinstance( mesh, Mesh ):
7644 mesh = mesh.GetMesh()
7645 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7647 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7649 Registering the new proxy for Pattern
7654 Private class used to bind methods creating algorithms to the class Mesh
7657 def __init__(self, method):
7659 self.defaultAlgoType = ""
7660 self.algoTypeToClass = {}
7661 self.method = method
7663 def add(self, algoClass):
7665 Store a python class of algorithm
7667 if inspect.isclass(algoClass) and \
7668 hasattr( algoClass, "algoType"):
7669 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7670 if not self.defaultAlgoType and \
7671 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7672 self.defaultAlgoType = algoClass.algoType
7673 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7675 def copy(self, mesh):
7677 Create a copy of self and assign mesh to the copy
7680 other = algoCreator( self.method )
7681 other.defaultAlgoType = self.defaultAlgoType
7682 other.algoTypeToClass = self.algoTypeToClass
7686 def __call__(self,algo="",geom=0,*args):
7688 Create an instance of algorithm
7692 if isinstance( algo, str ):
7694 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7695 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7700 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7702 elif not algoType and isinstance( geom, str ):
7707 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7709 elif isinstance( arg, str ) and not algoType:
7712 import traceback, sys
7713 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7714 sys.stderr.write( msg + '\n' )
7715 tb = traceback.extract_stack(None,2)
7716 traceback.print_list( [tb[0]] )
7718 algoType = self.defaultAlgoType
7719 if not algoType and self.algoTypeToClass:
7720 algoType = sorted( self.algoTypeToClass.keys() )[0]
7721 if algoType in self.algoTypeToClass:
7722 #print("Create algo",algoType)
7723 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7724 raise RuntimeError( "No class found for algo type %s" % algoType)
7727 class hypMethodWrapper:
7729 Private class used to substitute and store variable parameters of hypotheses.
7732 def __init__(self, hyp, method):
7734 self.method = method
7735 #print("REBIND:", method.__name__)
7738 def __call__(self,*args):
7740 call a method of hypothesis with calling SetVarParameter() before
7744 return self.method( self.hyp, *args ) # hypothesis method with no args
7746 #print("MethWrapper.__call__", self.method.__name__, args)
7748 parsed = ParseParameters(*args) # replace variables with their values
7749 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7750 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7751 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7752 # maybe there is a replaced string arg which is not variable
7753 result = self.method( self.hyp, *args )
7754 except ValueError as detail: # raised by ParseParameters()
7756 result = self.method( self.hyp, *args )
7757 except omniORB.CORBA.BAD_PARAM:
7758 raise ValueError(detail) # wrong variable name
7763 class genObjUnRegister:
7765 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7768 def __init__(self, genObj=None):
7769 self.genObjList = []
7773 def set(self, genObj):
7774 "Store one or a list of of SALOME.GenericObj'es"
7775 if isinstance( genObj, list ):
7776 self.genObjList.extend( genObj )
7778 self.genObjList.append( genObj )
7782 for genObj in self.genObjList:
7783 if genObj and hasattr( genObj, "UnRegister" ):
7786 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7788 Bind methods creating mesher plug-ins to the Mesh class
7791 # print("pluginName: ", pluginName)
7792 pluginBuilderName = pluginName + "Builder"
7794 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7795 except Exception as e:
7796 from salome_utils import verbose
7797 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7799 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7800 plugin = eval( pluginBuilderName )
7801 # print(" plugin:" , str(plugin))
7803 # add methods creating algorithms to Mesh
7804 for k in dir( plugin ):
7805 if k[0] == '_': continue
7806 algo = getattr( plugin, k )
7807 #print(" algo:", str(algo))
7808 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7809 #print(" meshMethod:" , str(algo.meshMethod))
7810 if not hasattr( Mesh, algo.meshMethod ):
7811 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7813 _mmethod = getattr( Mesh, algo.meshMethod )
7814 if hasattr( _mmethod, "add" ):