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, adaptToShape):
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
785 adpatToShape: if true project boundary points on shape
788 an instance of class :class:`Mesh`
790 if isinstance( mesh, Mesh ):
791 mesh = mesh.GetMesh()
792 print("calling createdualmesh from Python")
793 dualMesh = SMESH._objref_SMESH_Gen.CreateDualMesh(self, mesh, meshName, adaptToShape)
794 return Mesh(self, self.geompyD, dualMesh)
797 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
799 Create a mesh by copying a part of another mesh.
802 meshPart: a part of mesh to copy, either
803 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
804 To copy nodes or elements not forming any mesh object,
805 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
806 meshName: a name of the new mesh
807 toCopyGroups: to create in the new mesh groups the copied elements belongs to
808 toKeepIDs: to preserve order of the copied elements or not
811 an instance of class :class:`Mesh`
814 if isinstance( meshPart, Mesh ):
815 meshPart = meshPart.GetMesh()
816 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
817 return Mesh(self, self.geompyD, mesh)
819 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
820 toReuseHypotheses=True, toCopyElements=True):
822 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
823 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
824 To facilitate and speed up the operation, consider using
825 "Set presentation parameters and sub-shapes from arguments" option in
826 a dialog of geometrical operation used to create the new geometry.
829 sourceMesh: the mesh to copy definition of.
830 newGeom: the new geometry.
831 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
832 toCopyGroups: to create groups in the new mesh.
833 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
834 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
837 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
838 *invalidEntries* are study entries of objects whose
839 counterparts are not found in the *newGeom*, followed by entries
840 of mesh sub-objects that are invalid because they depend on a not found
843 if isinstance( sourceMesh, Mesh ):
844 sourceMesh = sourceMesh.GetMesh()
846 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
847 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
851 return ( ok, Mesh(self, self.geompyD, newMesh),
852 newGroups, newSubMeshes, newHypotheses, invalidEntries )
854 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
856 Return IDs of sub-shapes
859 theMainObject (GEOM.GEOM_Object): a shape
860 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
862 the list of integer values
865 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
867 def GetPattern(self):
869 Create a pattern mapper.
872 an instance of :class:`SMESH.SMESH_Pattern`
874 :ref:`Example of Patterns usage <tui_pattern_mapping>`
877 return SMESH._objref_SMESH_Gen.GetPattern(self)
879 def SetBoundaryBoxSegmentation(self, nbSegments):
881 Set number of segments per diagonal of boundary box of geometry, by which
882 default segment length of appropriate 1D hypotheses is defined in GUI.
886 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
888 # Filtering. Auxiliary functions:
889 # ------------------------------
891 def GetEmptyCriterion(self):
893 Create an empty criterion
896 :class:`SMESH.Filter.Criterion`
899 Type = self.EnumToLong(FT_Undefined)
900 Compare = self.EnumToLong(FT_Undefined)
904 UnaryOp = self.EnumToLong(FT_Undefined)
905 BinaryOp = self.EnumToLong(FT_Undefined)
908 Precision = -1 ##@1e-07
909 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
910 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
912 def GetCriterion(self,elementType,
914 Compare = FT_EqualTo,
916 UnaryOp=FT_Undefined,
917 BinaryOp=FT_Undefined,
920 Create a criterion by the given parameters
921 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
924 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
925 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
926 Note that the items starting from FT_LessThan are not suitable for *CritType*.
927 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
928 Threshold: the threshold value (range of ids as string, shape, numeric)
929 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
930 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
932 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
933 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
936 :class:`SMESH.Filter.Criterion`
938 Example: :ref:`combining_filters`
941 if not CritType in SMESH.FunctorType._items:
942 raise TypeError("CritType should be of SMESH.FunctorType")
943 aCriterion = self.GetEmptyCriterion()
944 aCriterion.TypeOfElement = elementType
945 aCriterion.Type = self.EnumToLong(CritType)
946 aCriterion.Tolerance = Tolerance
948 aThreshold = Threshold
950 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
951 aCriterion.Compare = self.EnumToLong(Compare)
952 elif Compare == "=" or Compare == "==":
953 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
955 aCriterion.Compare = self.EnumToLong(FT_LessThan)
957 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
958 elif Compare != FT_Undefined:
959 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
962 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
963 FT_BelongToCylinder, FT_LyingOnGeom]:
964 # Check that Threshold is GEOM object
965 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
966 aCriterion.ThresholdStr = GetName(aThreshold)
967 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
968 if not aCriterion.ThresholdID:
969 name = aCriterion.ThresholdStr
971 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
972 geompyD = aThreshold.GetGen()
973 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
974 # or a name of GEOM object
975 elif isinstance( aThreshold, str ):
976 aCriterion.ThresholdStr = aThreshold
978 raise TypeError("The Threshold should be a shape.")
979 if isinstance(UnaryOp,float):
980 aCriterion.Tolerance = UnaryOp
981 UnaryOp = FT_Undefined
983 elif CritType == FT_BelongToMeshGroup:
984 # Check that Threshold is a group
985 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
986 if aThreshold.GetType() != elementType:
987 raise ValueError("Group type mismatches Element type")
988 aCriterion.ThresholdStr = aThreshold.GetName()
989 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
990 study = salome.myStudy
992 so = study.FindObjectIOR( aCriterion.ThresholdID )
996 aCriterion.ThresholdID = entry
998 raise TypeError("The Threshold should be a Mesh Group")
999 elif CritType == FT_RangeOfIds:
1000 # Check that Threshold is string
1001 if isinstance(aThreshold, str):
1002 aCriterion.ThresholdStr = aThreshold
1004 raise TypeError("The Threshold should be a string.")
1005 elif CritType == FT_CoplanarFaces:
1006 # Check the Threshold
1007 if isinstance(aThreshold, int):
1008 aCriterion.ThresholdID = str(aThreshold)
1009 elif isinstance(aThreshold, str):
1010 ID = int(aThreshold)
1012 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
1013 aCriterion.ThresholdID = aThreshold
1015 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1016 elif CritType == FT_ConnectedElements:
1017 # Check the Threshold
1018 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1019 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1020 if not aCriterion.ThresholdID:
1021 name = aThreshold.GetName()
1023 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1024 geompyD = aThreshold.GetGen()
1025 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
1026 elif isinstance(aThreshold, int): # node id
1027 aCriterion.Threshold = aThreshold
1028 elif isinstance(aThreshold, list): # 3 point coordinates
1029 if len( aThreshold ) < 3:
1030 raise ValueError("too few point coordinates, must be 3")
1031 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1032 elif isinstance(aThreshold, str):
1033 if aThreshold.isdigit():
1034 aCriterion.Threshold = aThreshold # node id
1036 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1038 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1039 "or a list of point coordinates and not '%s'"%aThreshold)
1040 elif CritType == FT_ElemGeomType:
1041 # Check the Threshold
1043 aCriterion.Threshold = self.EnumToLong(aThreshold)
1044 assert( aThreshold in SMESH.GeometryType._items )
1046 if isinstance(aThreshold, int):
1047 aCriterion.Threshold = aThreshold
1049 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1052 elif CritType == FT_EntityType:
1053 # Check the Threshold
1055 aCriterion.Threshold = self.EnumToLong(aThreshold)
1056 assert( aThreshold in SMESH.EntityType._items )
1058 if isinstance(aThreshold, int):
1059 aCriterion.Threshold = aThreshold
1061 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1065 elif CritType == FT_GroupColor:
1066 # Check the Threshold
1068 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1070 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1072 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1073 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1074 FT_BareBorderFace, FT_BareBorderVolume,
1075 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1076 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1077 # At this point the Threshold is unnecessary
1078 if aThreshold == FT_LogicalNOT:
1079 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1080 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1081 aCriterion.BinaryOp = aThreshold
1085 aThreshold = float(aThreshold)
1086 aCriterion.Threshold = aThreshold
1088 raise TypeError("The Threshold should be a number.")
1091 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1092 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1094 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1095 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1097 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1098 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1100 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1101 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1105 def GetFilter(self,elementType,
1106 CritType=FT_Undefined,
1109 UnaryOp=FT_Undefined,
1113 Create a filter with the given parameters
1116 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1117 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1118 Note that the items starting from FT_LessThan are not suitable for CritType.
1119 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1120 Threshold: the threshold value (range of ids as string, shape, numeric)
1121 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1122 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1123 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1124 mesh: the mesh to initialize the filter with
1127 :class:`SMESH.Filter`
1130 See :doc:`Filters usage examples <tui_filters>`
1133 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1134 aFilterMgr = self.CreateFilterManager()
1135 aFilter = aFilterMgr.CreateFilter()
1137 aCriteria.append(aCriterion)
1138 aFilter.SetCriteria(aCriteria)
1140 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1141 else : aFilter.SetMesh( mesh )
1142 aFilterMgr.UnRegister()
1145 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1147 Create a filter from criteria
1150 criteria: a list of :class:`SMESH.Filter.Criterion`
1151 binOp: binary operator used when binary operator of criteria is undefined
1154 :class:`SMESH.Filter`
1157 See :doc:`Filters usage examples <tui_filters>`
1160 for i in range( len( criteria ) - 1 ):
1161 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1162 criteria[i].BinaryOp = self.EnumToLong( binOp )
1163 aFilterMgr = self.CreateFilterManager()
1164 aFilter = aFilterMgr.CreateFilter()
1165 aFilter.SetCriteria(criteria)
1166 aFilterMgr.UnRegister()
1169 def GetFunctor(self,theCriterion):
1171 Create a numerical functor by its type
1174 theCriterion (SMESH.FunctorType): functor type.
1175 Note that not all items correspond to numerical functors.
1178 :class:`SMESH.NumericalFunctor`
1181 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1183 aFilterMgr = self.CreateFilterManager()
1185 if theCriterion == FT_AspectRatio:
1186 functor = aFilterMgr.CreateAspectRatio()
1187 elif theCriterion == FT_AspectRatio3D:
1188 functor = aFilterMgr.CreateAspectRatio3D()
1189 elif theCriterion == FT_Warping:
1190 functor = aFilterMgr.CreateWarping()
1191 elif theCriterion == FT_MinimumAngle:
1192 functor = aFilterMgr.CreateMinimumAngle()
1193 elif theCriterion == FT_Taper:
1194 functor = aFilterMgr.CreateTaper()
1195 elif theCriterion == FT_Skew:
1196 functor = aFilterMgr.CreateSkew()
1197 elif theCriterion == FT_Area:
1198 functor = aFilterMgr.CreateArea()
1199 elif theCriterion == FT_Volume3D:
1200 functor = aFilterMgr.CreateVolume3D()
1201 elif theCriterion == FT_MaxElementLength2D:
1202 functor = aFilterMgr.CreateMaxElementLength2D()
1203 elif theCriterion == FT_MaxElementLength3D:
1204 functor = aFilterMgr.CreateMaxElementLength3D()
1205 elif theCriterion == FT_MultiConnection:
1206 functor = aFilterMgr.CreateMultiConnection()
1207 elif theCriterion == FT_MultiConnection2D:
1208 functor = aFilterMgr.CreateMultiConnection2D()
1209 elif theCriterion == FT_Length:
1210 functor = aFilterMgr.CreateLength()
1211 elif theCriterion == FT_Length2D:
1212 functor = aFilterMgr.CreateLength2D()
1213 elif theCriterion == FT_Length3D:
1214 functor = aFilterMgr.CreateLength3D()
1215 elif theCriterion == FT_Deflection2D:
1216 functor = aFilterMgr.CreateDeflection2D()
1217 elif theCriterion == FT_NodeConnectivityNumber:
1218 functor = aFilterMgr.CreateNodeConnectivityNumber()
1219 elif theCriterion == FT_BallDiameter:
1220 functor = aFilterMgr.CreateBallDiameter()
1222 print("Error: given parameter is not numerical functor type.")
1223 aFilterMgr.UnRegister()
1226 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1231 theHType (string): mesh hypothesis type
1232 theLibName (string): mesh plug-in library name
1235 created hypothesis instance
1237 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1239 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1242 # wrap hypothesis methods
1243 for meth_name in dir( hyp.__class__ ):
1244 if not meth_name.startswith("Get") and \
1245 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1246 method = getattr ( hyp.__class__, meth_name )
1247 if callable(method):
1248 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1252 def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1254 Create hypothesis initialized according to parameters
1257 hypType (string): hypothesis type
1258 libName (string): plug-in library name
1259 mesh: optional mesh by which a hypotheses can initialize self
1260 shape: optional geometry by size of which a hypotheses can initialize self
1261 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1264 created hypothesis instance
1266 if isinstance( mesh, Mesh ):
1267 mesh = mesh.GetMesh()
1268 if isinstance( initParams, (bool,int)):
1269 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1270 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1271 mesh, shape, initParams )
1273 def GetMeshInfo(self, obj):
1275 Get the mesh statistic.
1278 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1281 if isinstance( obj, Mesh ):
1284 if hasattr(obj, "GetMeshInfo"):
1285 values = obj.GetMeshInfo()
1286 for i in range(SMESH.Entity_Last._v):
1287 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1291 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1293 Get minimum distance between two objects
1295 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1296 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1299 src1 (SMESH.SMESH_IDSource): first source object
1300 src2 (SMESH.SMESH_IDSource): second source object
1301 id1 (int): node/element id from the first source
1302 id2 (int): node/element id from the second (or first) source
1303 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1304 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1307 minimum distance value
1310 :meth:`GetMinDistance`
1313 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1317 result = result.value
1320 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1322 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1324 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1325 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1328 src1 (SMESH.SMESH_IDSource): first source object
1329 src2 (SMESH.SMESH_IDSource): second source object
1330 id1 (int): node/element id from the first source
1331 id2 (int): node/element id from the second (or first) source
1332 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1333 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1336 :class:`SMESH.Measure` structure or None if input data is invalid
1341 if isinstance(src1, Mesh): src1 = src1.mesh
1342 if isinstance(src2, Mesh): src2 = src2.mesh
1343 if src2 is None and id2 != 0: src2 = src1
1344 if not hasattr(src1, "_narrow"): return None
1345 src1 = src1._narrow(SMESH.SMESH_IDSource)
1346 if not src1: return None
1347 unRegister = genObjUnRegister()
1350 e = m.GetMeshEditor()
1352 src1 = e.MakeIDSource([id1], SMESH.FACE)
1354 src1 = e.MakeIDSource([id1], SMESH.NODE)
1355 unRegister.set( src1 )
1357 if hasattr(src2, "_narrow"):
1358 src2 = src2._narrow(SMESH.SMESH_IDSource)
1359 if src2 and id2 != 0:
1361 e = m.GetMeshEditor()
1363 src2 = e.MakeIDSource([id2], SMESH.FACE)
1365 src2 = e.MakeIDSource([id2], SMESH.NODE)
1366 unRegister.set( src2 )
1369 aMeasurements = self.CreateMeasurements()
1370 unRegister.set( aMeasurements )
1371 result = aMeasurements.MinDistance(src1, src2)
1374 def BoundingBox(self, objects):
1376 Get bounding box of the specified object(s)
1379 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1382 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1385 :meth:`GetBoundingBox`
1388 result = self.GetBoundingBox(objects)
1392 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1395 def GetBoundingBox(self, objects):
1397 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1400 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1403 :class:`SMESH.Measure` structure
1409 if isinstance(objects, tuple):
1410 objects = list(objects)
1411 if not isinstance(objects, list):
1415 if isinstance(o, Mesh):
1416 srclist.append(o.mesh)
1417 elif hasattr(o, "_narrow"):
1418 src = o._narrow(SMESH.SMESH_IDSource)
1419 if src: srclist.append(src)
1422 aMeasurements = self.CreateMeasurements()
1423 result = aMeasurements.BoundingBox(srclist)
1424 aMeasurements.UnRegister()
1427 def GetLength(self, obj):
1429 Get sum of lengths of all 1D elements in the mesh object.
1432 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1435 sum of lengths of all 1D elements
1438 if isinstance(obj, Mesh): obj = obj.mesh
1439 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1440 aMeasurements = self.CreateMeasurements()
1441 value = aMeasurements.Length(obj)
1442 aMeasurements.UnRegister()
1445 def GetArea(self, obj):
1447 Get sum of areas of all 2D elements in the mesh object.
1450 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1453 sum of areas of all 2D elements
1456 if isinstance(obj, Mesh): obj = obj.mesh
1457 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1458 aMeasurements = self.CreateMeasurements()
1459 value = aMeasurements.Area(obj)
1460 aMeasurements.UnRegister()
1463 def GetVolume(self, obj):
1465 Get sum of volumes of all 3D elements in the mesh object.
1468 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1471 sum of volumes of all 3D elements
1474 if isinstance(obj, Mesh): obj = obj.mesh
1475 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1476 aMeasurements = self.CreateMeasurements()
1477 value = aMeasurements.Volume(obj)
1478 aMeasurements.UnRegister()
1481 def GetGravityCenter(self, obj):
1483 Get gravity center of all nodes of a mesh object.
1486 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1489 Three components of the gravity center (x,y,z)
1492 :meth:`Mesh.BaryCenter`
1494 if isinstance(obj, Mesh): obj = obj.mesh
1495 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1496 aMeasurements = self.CreateMeasurements()
1497 pointStruct = aMeasurements.GravityCenter(obj)
1498 aMeasurements.UnRegister()
1499 return pointStruct.x, pointStruct.y, pointStruct.z
1501 def GetAngle(self, p1, p2, p3 ):
1503 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1506 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1512 if isinstance( p1, list ): p1 = PointStruct(*p1)
1513 if isinstance( p2, list ): p2 = PointStruct(*p2)
1514 if isinstance( p3, list ): p3 = PointStruct(*p3)
1516 aMeasurements = self.CreateMeasurements()
1517 angle = aMeasurements.Angle(p1,p2,p3)
1518 aMeasurements.UnRegister()
1523 pass # end of class smeshBuilder
1526 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1527 """Registering the new proxy for SMESH.SMESH_Gen"""
1530 def New( instance=None, instanceGeom=None):
1532 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1533 interface to create or load meshes.
1538 salome.salome_init()
1539 from salome.smesh import smeshBuilder
1540 smesh = smeshBuilder.New()
1543 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1544 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1546 :class:`smeshBuilder` instance
1551 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1553 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1558 smeshInst = smeshBuilder()
1559 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1560 smeshInst.init_smesh(instanceGeom)
1564 # Public class: Mesh
1565 # ==================
1568 class Mesh(metaclass = MeshMeta):
1570 This class allows defining and managing a mesh.
1571 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1572 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1573 new nodes and elements and by changing the existing entities), to get information
1574 about a mesh and to export a mesh in different formats.
1581 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1586 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1587 sets the GUI name of this mesh to *name*.
1590 smeshpyD: an instance of smeshBuilder class
1591 geompyD: an instance of geomBuilder class
1592 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1593 name: Study name of the mesh
1596 self.smeshpyD = smeshpyD
1597 self.geompyD = geompyD
1602 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1605 # publish geom of mesh (issue 0021122)
1606 if not self.geom.GetStudyEntry():
1610 geo_name = name + " shape"
1612 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1613 geompyD.addToStudy( self.geom, geo_name )
1614 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1616 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1619 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1621 self.smeshpyD.SetName(self.mesh, name)
1623 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1626 self.geom = self.mesh.GetShapeToMesh()
1628 self.editor = self.mesh.GetMeshEditor()
1629 self.functors = [None] * SMESH.FT_Undefined._v
1631 # set self to algoCreator's
1632 for attrName in dir(self):
1633 attr = getattr( self, attrName )
1634 if isinstance( attr, algoCreator ):
1635 setattr( self, attrName, attr.copy( self ))
1642 Destructor. Clean-up resources
1645 #self.mesh.UnRegister()
1649 def SetMesh(self, theMesh):
1651 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1654 theMesh: a :class:`SMESH.SMESH_Mesh` object
1656 # do not call Register() as this prevents mesh servant deletion at closing study
1657 #if self.mesh: self.mesh.UnRegister()
1660 #self.mesh.Register()
1661 self.geom = self.mesh.GetShapeToMesh()
1665 if salome.sg.hasDesktop():
1666 so = salome.ObjectToSObject( self.geom )
1667 comp = so.GetFatherComponent()
1668 if comp.ComponentDataType() == "SHAPERSTUDY":
1669 import shaperBuilder
1670 self.geompyD = shaperBuilder.New()
1673 if not self.geompyD:
1674 self.geompyD = self.geom.GetGen()
1679 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1682 a :class:`SMESH.SMESH_Mesh` object
1687 def GetEngine(self):
1689 Return a smeshBuilder instance created this mesh
1691 return self.smeshpyD
1693 def GetGeomEngine(self):
1695 Return a geomBuilder instance
1701 Get the name of the mesh
1704 the name of the mesh as a string
1707 name = GetName(self.GetMesh())
1710 def SetName(self, name):
1712 Set a name to the mesh
1715 name: a new name of the mesh
1718 self.smeshpyD.SetName(self.GetMesh(), name)
1720 def GetSubMesh(self, geom, name):
1722 Get a sub-mesh object associated to a *geom* geometrical object.
1725 geom: a geometrical object (shape)
1726 name: a name for the sub-mesh in the Object Browser
1729 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1730 which lies on the given shape
1733 A sub-mesh is implicitly created when a sub-shape is specified at
1734 creating an algorithm, for example::
1736 algo1D = mesh.Segment(geom=Edge_1)
1738 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1739 The created sub-mesh can be retrieved from the algorithm::
1741 submesh = algo1D.GetSubMesh()
1744 AssureGeomPublished( self, geom, name )
1745 submesh = self.mesh.GetSubMesh( geom, name )
1750 Return the shape associated to the mesh
1758 def SetShape(self, geom):
1760 Associate the given shape to the mesh (entails the recreation of the mesh)
1763 geom: the shape to be meshed (GEOM_Object)
1766 self.mesh = self.smeshpyD.CreateMesh(geom)
1768 def HasShapeToMesh(self):
1770 Return ``True`` if this mesh is based on geometry
1772 return self.mesh.HasShapeToMesh()
1776 Load mesh from the study after opening the study
1780 def IsReadyToCompute(self, theSubObject):
1782 Return true if the hypotheses are defined well
1785 theSubObject: a sub-shape of a mesh shape
1791 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1793 def GetAlgoState(self, theSubObject):
1795 Return errors of hypotheses definition.
1796 The list of errors is empty if everything is OK.
1799 theSubObject: a sub-shape of a mesh shape
1805 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1807 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1809 Return a geometrical object on which the given element was built.
1810 The returned geometrical object, if not nil, is either found in the
1811 study or published by this method with the given name
1814 theElementID: the id of the mesh element
1815 theGeomName: the user-defined name of the geometrical object
1818 GEOM.GEOM_Object instance
1821 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1823 def MeshDimension(self):
1825 Return the mesh dimension depending on the dimension of the underlying shape
1826 or, if the mesh is not based on any shape, basing on deimension of elements
1829 mesh dimension as an integer value [0,3]
1832 if self.mesh.HasShapeToMesh():
1833 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1834 if len( shells ) > 0 :
1836 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1838 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1843 if self.NbVolumes() > 0: return 3
1844 if self.NbFaces() > 0: return 2
1845 if self.NbEdges() > 0: return 1
1848 def Evaluate(self, geom=0):
1850 Evaluate size of prospective mesh on a shape
1853 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1854 To know predicted number of e.g. edges, inquire it this way::
1856 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1859 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1861 geom = self.mesh.GetShapeToMesh()
1864 return self.smeshpyD.Evaluate(self.mesh, geom)
1867 def Compute(self, geom=0, discardModifs=False, refresh=False, nbThreads=0):
1869 Compute the mesh and return the status of the computation
1872 geom: geomtrical shape on which mesh data should be computed
1873 discardModifs: if True and the mesh has been edited since
1874 a last total re-compute and that may prevent successful partial re-compute,
1875 then the mesh is cleaned before Compute()
1876 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1877 nbThreads: Number of threads to use for a parallel computation
1883 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1884 geom = self.mesh.GetShapeToMesh()
1887 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1889 # Setting parallel parameters
1890 self.mesh.SetNbThreads(nbThreads)
1891 ok = self.smeshpyD.Compute(self.mesh, geom)
1892 except SALOME.SALOME_Exception as ex:
1893 print("Mesh computation failed, exception caught:")
1894 print(" ", ex.details.text)
1897 print("Mesh computation failed, exception caught:")
1898 traceback.print_exc()
1902 # Treat compute errors
1903 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1905 for err in computeErrors:
1906 if self.mesh.HasShapeToMesh():
1907 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1909 stdErrors = ["OK", #COMPERR_OK
1910 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1911 "std::exception", #COMPERR_STD_EXCEPTION
1912 "OCC exception", #COMPERR_OCC_EXCEPTION
1913 "..", #COMPERR_SLM_EXCEPTION
1914 "Unknown exception", #COMPERR_EXCEPTION
1915 "Memory allocation problem", #COMPERR_MEMORY_PB
1916 "Algorithm failed", #COMPERR_ALGO_FAILED
1917 "Unexpected geometry", #COMPERR_BAD_SHAPE
1918 "Warning", #COMPERR_WARNING
1919 "Computation cancelled",#COMPERR_CANCELED
1920 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1922 if err.code < len(stdErrors): errText = stdErrors[err.code]
1924 errText = "code %s" % -err.code
1925 if errText: errText += ". "
1926 errText += err.comment
1927 if allReasons: allReasons += "\n"
1929 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1931 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1935 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1937 if err.isGlobalAlgo:
1945 reason = '%s %sD algorithm is missing' % (glob, dim)
1946 elif err.state == HYP_MISSING:
1947 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1948 % (glob, dim, name, dim))
1949 elif err.state == HYP_NOTCONFORM:
1950 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1951 elif err.state == HYP_BAD_PARAMETER:
1952 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1953 % ( glob, dim, name ))
1954 elif err.state == HYP_BAD_GEOMETRY:
1955 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1956 'geometry' % ( glob, dim, name ))
1957 elif err.state == HYP_HIDDEN_ALGO:
1958 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1959 'algorithm of upper dimension generating %sD mesh'
1960 % ( glob, dim, name, glob, dim ))
1962 reason = ("For unknown reason. "
1963 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1965 if allReasons: allReasons += "\n"
1966 allReasons += "- " + reason
1968 if not ok or allReasons != "":
1969 msg = '"' + GetName(self.mesh) + '"'
1970 if ok: msg += " has been computed with warnings"
1971 else: msg += " has not been computed"
1972 if allReasons != "": msg += ":"
1978 if salome.sg.hasDesktop():
1979 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1980 if refresh: salome.sg.updateObjBrowser()
1984 def GetComputeErrors(self, shape=0 ):
1986 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1990 shape = self.mesh.GetShapeToMesh()
1991 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1993 def GetSubShapeName(self, subShapeID ):
1995 Return a name of a sub-shape by its ID.
1996 Possible variants (for *subShapeID* == 3):
1998 - **"Face_12"** - published sub-shape
1999 - **FACE #3** - not published sub-shape
2000 - **sub-shape #3** - invalid sub-shape ID
2001 - **#3** - error in this function
2004 subShapeID: a unique ID of a sub-shape
2007 a string describing the sub-shape
2011 if not self.mesh.HasShapeToMesh():
2015 mainIOR = salome.orb.object_to_string( self.GetShape() )
2017 mainSO = s.FindObjectIOR(mainIOR)
2020 shapeText = '"%s"' % mainSO.GetName()
2021 subIt = s.NewChildIterator(mainSO)
2023 subSO = subIt.Value()
2025 obj = subSO.GetObject()
2026 if not obj: continue
2027 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2030 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2033 if ids == subShapeID:
2034 shapeText = '"%s"' % subSO.GetName()
2037 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2039 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2041 shapeText = 'sub-shape #%s' % (subShapeID)
2043 shapeText = "#%s" % (subShapeID)
2046 def GetFailedShapes(self, publish=False):
2048 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2049 error of an algorithm
2052 publish: if *True*, the returned groups will be published in the study
2055 a list of GEOM groups each named after a failed algorithm
2060 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2061 for err in computeErrors:
2062 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2063 if not shape: continue
2064 if err.algoName in algo2shapes:
2065 algo2shapes[ err.algoName ].append( shape )
2067 algo2shapes[ err.algoName ] = [ shape ]
2071 for algoName, shapes in list(algo2shapes.items()):
2073 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2074 otherTypeShapes = []
2076 group = self.geompyD.CreateGroup( self.geom, groupType )
2077 for shape in shapes:
2078 if shape.GetShapeType() == shapes[0].GetShapeType():
2079 sameTypeShapes.append( shape )
2081 otherTypeShapes.append( shape )
2082 self.geompyD.UnionList( group, sameTypeShapes )
2084 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2086 group.SetName( algoName )
2087 groups.append( group )
2088 shapes = otherTypeShapes
2091 for group in groups:
2092 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2095 def GetMeshOrder(self):
2097 Return sub-mesh objects list in meshing order
2100 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2103 return self.mesh.GetMeshOrder()
2105 def SetMeshOrder(self, submeshes):
2107 Set priority of sub-meshes. It works in two ways:
2109 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2110 *several dimensions*, it sets the order in which the sub-meshes are computed.
2111 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2112 when looking for meshing parameters to apply to a sub-shape. To impose the
2113 order in which sub-meshes with uni-dimensional algorithms are computed,
2114 call **submesh.Compute()** in a desired order.
2117 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2119 Warning: the method is for setting the order for all sub-meshes at once:
2120 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2123 return self.mesh.SetMeshOrder(submeshes)
2125 def Clear(self, refresh=False):
2127 Remove all nodes and elements generated on geometry. Imported elements remain.
2130 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2134 if ( salome.sg.hasDesktop() ):
2135 if refresh: salome.sg.updateObjBrowser()
2137 def ClearSubMesh(self, geomId, refresh=False):
2139 Remove all nodes and elements of indicated shape
2142 geomId: the ID of a sub-shape to remove elements on
2143 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2146 self.mesh.ClearSubMesh(geomId)
2147 if salome.sg.hasDesktop():
2148 if refresh: salome.sg.updateObjBrowser()
2150 def AutomaticTetrahedralization(self, fineness=0):
2152 Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron
2155 fineness: [0.0,1.0] defines mesh fineness
2161 dim = self.MeshDimension()
2163 self.RemoveGlobalHypotheses()
2164 self.Segment().AutomaticLength(fineness)
2166 self.Triangle().LengthFromEdges()
2171 return self.Compute()
2173 def AutomaticHexahedralization(self, fineness=0):
2175 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2178 fineness: [0.0, 1.0] defines mesh fineness
2184 dim = self.MeshDimension()
2185 # assign the hypotheses
2186 self.RemoveGlobalHypotheses()
2187 self.Segment().AutomaticLength(fineness)
2194 return self.Compute()
2196 def AddHypothesis(self, hyp, geom=0):
2201 hyp: a hypothesis to assign
2202 geom: a subhape of mesh geometry
2205 :class:`SMESH.Hypothesis_Status`
2208 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2209 hyp, geom = geom, hyp
2210 if isinstance( hyp, Mesh_Algorithm ):
2211 hyp = hyp.GetAlgorithm()
2216 geom = self.mesh.GetShapeToMesh()
2219 if self.mesh.HasShapeToMesh():
2220 hyp_type = hyp.GetName()
2221 lib_name = hyp.GetLibName()
2222 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2223 # if checkAll and geom:
2224 # checkAll = geom.GetType() == 37
2226 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2228 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2229 status = self.mesh.AddHypothesis(geom, hyp)
2231 status = HYP_BAD_GEOMETRY, ""
2232 hyp_name = GetName( hyp )
2235 geom_name = geom.GetName()
2236 isAlgo = hyp._narrow( SMESH_Algo )
2237 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2240 def IsUsedHypothesis(self, hyp, geom):
2242 Return True if an algorithm or hypothesis is assigned to a given shape
2245 hyp: an algorithm or hypothesis to check
2246 geom: a subhape of mesh geometry
2252 if not hyp: # or not geom
2254 if isinstance( hyp, Mesh_Algorithm ):
2255 hyp = hyp.GetAlgorithm()
2257 hyps = self.GetHypothesisList(geom)
2259 if h.GetId() == hyp.GetId():
2263 def RemoveHypothesis(self, hyp, geom=0):
2265 Unassign a hypothesis
2268 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2269 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2272 :class:`SMESH.Hypothesis_Status`
2277 if isinstance( hyp, Mesh_Algorithm ):
2278 hyp = hyp.GetAlgorithm()
2284 if self.IsUsedHypothesis( hyp, shape ):
2285 return self.mesh.RemoveHypothesis( shape, hyp )
2286 hypName = GetName( hyp )
2287 geoName = GetName( shape )
2288 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2291 def GetHypothesisList(self, geom):
2293 Get the list of hypotheses added on a geometry
2296 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2299 the sequence of :class:`SMESH.SMESH_Hypothesis`
2302 return self.mesh.GetHypothesisList( geom )
2304 def RemoveGlobalHypotheses(self):
2306 Remove all global hypotheses
2309 current_hyps = self.mesh.GetHypothesisList( self.geom )
2310 for hyp in current_hyps:
2311 self.mesh.RemoveHypothesis( self.geom, hyp )
2315 def ExportMEDCoupling(self, *args, **kwargs):
2317 Export the mesh in a memory representation.
2320 auto_groups (boolean): parameter for creating/not creating
2321 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2322 the typical use is auto_groups=False.
2323 overwrite (boolean): parameter for overwriting/not overwriting the file
2324 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2325 to export instead of the mesh
2326 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2328 - 1D if all mesh nodes lie on OX coordinate axis, or
2329 - 2D if all mesh nodes lie on XOY coordinate plane, or
2330 - 3D in the rest cases.
2332 If *autoDimension* is *False*, the space dimension is always 3.
2333 fields: list of GEOM fields defined on the shape to mesh.
2334 geomAssocFields: each character of this string means a need to export a
2335 corresponding field; correspondence between fields and characters
2338 - 'v' stands for "_vertices_" field;
2339 - 'e' stands for "_edges_" field;
2340 - 'f' stands for "_faces_" field;
2341 - 's' stands for "_solids_" field.
2343 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2344 close to zero within a given tolerance, the coordinate is set to zero.
2345 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2346 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2348 auto_groups = args[0] if len(args) > 0 else False
2349 meshPart = args[1] if len(args) > 1 else None
2350 autoDimension = args[2] if len(args) > 2 else True
2351 fields = args[3] if len(args) > 3 else []
2352 geomAssocFields = args[4] if len(args) > 4 else ''
2353 z_tolerance = args[5] if len(args) > 5 else -1.
2354 saveNumbers = args[6] if len(args) > 6 else True
2355 # process keywords arguments
2356 auto_groups = kwargs.get("auto_groups", auto_groups)
2357 meshPart = kwargs.get("meshPart", meshPart)
2358 autoDimension = kwargs.get("autoDimension", autoDimension)
2359 fields = kwargs.get("fields", fields)
2360 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2361 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2362 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2364 # invoke engine's function
2365 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2366 unRegister = genObjUnRegister()
2367 if isinstance( meshPart, list ):
2368 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2369 unRegister.set( meshPart )
2371 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2372 self.mesh.SetParameters(Parameters)
2374 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2375 fields, geomAssocFields, z_tolerance,
2378 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2379 return medcoupling.MEDFileData.New(dab)
2381 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2383 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2384 return medcoupling.MEDFileMesh.New(dab)
2386 def ExportMED(self, *args, **kwargs):
2388 Export the mesh in a file in MED format
2389 allowing to overwrite the file if it exists or add the exported data to its contents
2392 fileName: is the file name
2393 auto_groups (boolean): parameter for creating/not creating
2394 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2395 the typical use is auto_groups=False.
2396 version (int): define the version (xy, where version is x.y.z) of MED file format.
2397 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2398 The rules of compatibility to write a mesh in an older version than
2399 the current version depend on the current version. For instance,
2400 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2401 or 3.2.1 or 3.3.1 formats.
2402 If the version is equal to -1, the version is not changed (default).
2403 overwrite (boolean): parameter for overwriting/not overwriting the file
2404 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2405 to export instead of the mesh
2406 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2408 - 1D if all mesh nodes lie on OX coordinate axis, or
2409 - 2D if all mesh nodes lie on XOY coordinate plane, or
2410 - 3D in the rest cases.
2412 If *autoDimension* is *False*, the space dimension is always 3.
2413 fields: list of GEOM fields defined on the shape to mesh.
2414 geomAssocFields: each character of this string means a need to export a
2415 corresponding field; correspondence between fields and characters
2418 - 'v' stands for "_vertices_" field;
2419 - 'e' stands for "_edges_" field;
2420 - 'f' stands for "_faces_" field;
2421 - 's' stands for "_solids_" field.
2423 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2424 close to zero within a given tolerance, the coordinate is set to zero.
2425 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2426 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2428 # process positional arguments
2429 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2431 auto_groups = args[1] if len(args) > 1 else False
2432 version = args[2] if len(args) > 2 else -1
2433 overwrite = args[3] if len(args) > 3 else True
2434 meshPart = args[4] if len(args) > 4 else None
2435 autoDimension = args[5] if len(args) > 5 else True
2436 fields = args[6] if len(args) > 6 else []
2437 geomAssocFields = args[7] if len(args) > 7 else ''
2438 z_tolerance = args[8] if len(args) > 8 else -1.
2439 saveNumbers = args[9] if len(args) > 9 else True
2440 # process keywords arguments
2441 auto_groups = kwargs.get("auto_groups", auto_groups)
2442 version = kwargs.get("version", version)
2443 version = kwargs.get("minor", version)
2444 overwrite = kwargs.get("overwrite", overwrite)
2445 meshPart = kwargs.get("meshPart", meshPart)
2446 autoDimension = kwargs.get("autoDimension", autoDimension)
2447 fields = kwargs.get("fields", fields)
2448 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2449 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2450 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2452 if isinstance( meshPart, Mesh):
2453 meshPart = meshPart.GetMesh()
2455 # invoke engine's function
2456 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2457 unRegister = genObjUnRegister()
2458 if isinstance( meshPart, list ):
2459 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2460 unRegister.set( meshPart )
2462 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2463 self.mesh.SetParameters(Parameters)
2465 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2466 version, overwrite, autoDimension,
2467 fields, geomAssocFields, z_tolerance, saveNumbers )
2469 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2471 def ExportDAT(self, f, meshPart=None, renumber=True):
2473 Export the mesh in a file in DAT format
2477 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2478 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2481 if meshPart or not renumber:
2482 unRegister = genObjUnRegister()
2483 if isinstance( meshPart, list ):
2484 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2485 unRegister.set( meshPart )
2486 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2488 self.mesh.ExportDAT( f, renumber )
2490 def ExportUNV(self, f, meshPart=None, renumber=True):
2492 Export the mesh in a file in UNV format
2496 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2497 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2500 if meshPart or not renumber:
2501 unRegister = genObjUnRegister()
2502 if isinstance( meshPart, list ):
2503 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2504 unRegister.set( meshPart )
2505 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2507 self.mesh.ExportUNV( f, renumber )
2509 def ExportSTL(self, f, ascii=1, meshPart=None):
2511 Export the mesh in a file in STL format
2515 ascii: defines the file encoding
2516 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2520 unRegister = genObjUnRegister()
2521 if isinstance( meshPart, list ):
2522 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2523 unRegister.set( meshPart )
2524 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2526 self.mesh.ExportSTL(f, ascii)
2528 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2530 Export the mesh in a file in CGNS format
2534 overwrite: boolean parameter for overwriting/not overwriting the file
2535 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2536 groupElemsByType: if True all elements of same entity type are exported at ones,
2537 else elements are exported in order of their IDs which can cause creation
2538 of multiple cgns sections
2541 unRegister = genObjUnRegister()
2542 if isinstance( meshPart, list ):
2543 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2544 unRegister.set( meshPart )
2545 if isinstance( meshPart, Mesh ):
2546 meshPart = meshPart.mesh
2548 meshPart = self.mesh
2549 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2551 def ExportGMF(self, f, meshPart=None):
2553 Export the mesh in a file in GMF format.
2554 GMF files must have .mesh extension for the ASCII format and .meshb for
2555 the bynary format. Other extensions are not allowed.
2559 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2562 unRegister = genObjUnRegister()
2563 if isinstance( meshPart, list ):
2564 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2565 unRegister.set( meshPart )
2566 if isinstance( meshPart, Mesh ):
2567 meshPart = meshPart.mesh
2569 meshPart = self.mesh
2570 self.mesh.ExportGMF(meshPart, f, True)
2572 def ExportToMED(self, *args, **kwargs):
2574 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2575 Export the mesh in a file in MED format
2576 allowing to overwrite the file if it exists or add the exported data to its contents
2579 fileName: the file name
2580 opt (boolean): parameter for creating/not creating
2581 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2582 overwrite: boolean parameter for overwriting/not overwriting the file
2583 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2585 - 1D if all mesh nodes lie on OX coordinate axis, or
2586 - 2D if all mesh nodes lie on XOY coordinate plane, or
2587 - 3D in the rest cases.
2589 If **autoDimension** is *False*, the space dimension is always 3.
2592 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2593 # process positional arguments
2594 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2596 auto_groups = args[1] if len(args) > 1 else False
2597 overwrite = args[2] if len(args) > 2 else True
2598 autoDimension = args[3] if len(args) > 3 else True
2599 # process keywords arguments
2600 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2601 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2602 overwrite = kwargs.get("overwrite", overwrite)
2603 autoDimension = kwargs.get("autoDimension", autoDimension)
2605 # invoke engine's function
2606 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2608 def ExportToMEDX(self, *args, **kwargs):
2610 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2611 Export the mesh in a file in MED format
2614 fileName: the file name
2615 opt (boolean): parameter for creating/not creating
2616 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2617 overwrite: boolean parameter for overwriting/not overwriting the file
2618 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2620 - 1D if all mesh nodes lie on OX coordinate axis, or
2621 - 2D if all mesh nodes lie on XOY coordinate plane, or
2622 - 3D in the rest cases.
2624 If **autoDimension** is *False*, the space dimension is always 3.
2627 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2628 # process positional arguments
2629 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2631 auto_groups = args[1] if len(args) > 1 else False
2632 overwrite = args[2] if len(args) > 2 else True
2633 autoDimension = args[3] if len(args) > 3 else True
2634 # process keywords arguments
2635 auto_groups = kwargs.get("auto_groups", auto_groups)
2636 overwrite = kwargs.get("overwrite", overwrite)
2637 autoDimension = kwargs.get("autoDimension", autoDimension)
2639 # invoke engine's function
2640 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2644 def Append(self, meshes, uniteIdenticalGroups = True,
2645 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2647 Append given meshes into this mesh.
2648 All groups of input meshes will be created in this mesh.
2651 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2652 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2653 mergeNodesAndElements: if True, equal nodes and elements are merged
2654 mergeTolerance: tolerance for merging nodes
2655 allGroups: forces creation of groups corresponding to every input mesh
2657 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2658 mergeNodesAndElements, mergeTolerance, allGroups,
2659 meshToAppendTo = self.GetMesh() )
2661 # Operations with groups:
2662 # ----------------------
2663 def CreateEmptyGroup(self, elementType, name):
2665 Create an empty standalone mesh group
2668 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2669 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2670 name: the name of the mesh group
2673 :class:`SMESH.SMESH_Group`
2676 return self.mesh.CreateGroup(elementType, name)
2678 def Group(self, grp, name=""):
2680 Create a mesh group based on the geometric object *grp*
2681 and give it a *name*.
2682 If *name* is not defined the name of the geometric group is used
2685 Works like :meth:`GroupOnGeom`.
2688 grp: a geometric group, a vertex, an edge, a face or a solid
2689 name: the name of the mesh group
2692 :class:`SMESH.SMESH_GroupOnGeom`
2695 return self.GroupOnGeom(grp, name)
2697 def GroupOnGeom(self, grp, name="", typ=None):
2699 Create a mesh group based on the geometrical object *grp*
2700 and give it a *name*.
2701 if *name* is not defined the name of the geometric group is used
2704 grp: a geometrical group, a vertex, an edge, a face or a solid
2705 name: the name of the mesh group
2706 typ: the type of elements in the group; either of
2707 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2708 automatically detected by the type of the geometry
2711 :class:`SMESH.SMESH_GroupOnGeom`
2714 AssureGeomPublished( self, grp, name )
2716 name = grp.GetName()
2718 typ = self._groupTypeFromShape( grp )
2719 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2721 def _groupTypeFromShape( self, shape ):
2723 Pivate method to get a type of group on geometry
2725 tgeo = str(shape.GetShapeType())
2726 if tgeo == "VERTEX":
2728 elif tgeo == "EDGE" or tgeo == "WIRE":
2730 elif tgeo == "FACE" or tgeo == "SHELL":
2732 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2734 elif tgeo == "COMPOUND":
2736 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2738 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2739 # simplification of access in geomBuilder: omniORB.registerObjref
2740 from SHAPERSTUDY_utils import getEngine
2743 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2745 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2746 return self._groupTypeFromShape( sub[0] )
2748 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2751 def GroupOnFilter(self, typ, name, filter):
2753 Create a mesh group with given *name* based on the *filter*.
2754 It is a special type of group dynamically updating it's contents during
2758 typ: the type of elements in the group; either of
2759 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2760 name: the name of the mesh group
2761 filter (SMESH.Filter): the filter defining group contents
2764 :class:`SMESH.SMESH_GroupOnFilter`
2767 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2769 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2771 Create a mesh group by the given ids of elements
2774 groupName: the name of the mesh group
2775 elementType: the type of elements in the group; either of
2776 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2777 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2780 :class:`SMESH.SMESH_Group`
2783 group = self.mesh.CreateGroup(elementType, groupName)
2784 if isinstance( elemIDs, Mesh ):
2785 elemIDs = elemIDs.GetMesh()
2786 if hasattr( elemIDs, "GetIDs" ):
2787 if hasattr( elemIDs, "SetMesh" ):
2788 elemIDs.SetMesh( self.GetMesh() )
2789 group.AddFrom( elemIDs )
2797 CritType=FT_Undefined,
2800 UnaryOp=FT_Undefined,
2803 Create a mesh group by the given conditions
2806 groupName: the name of the mesh group
2807 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2808 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2809 Note that the items starting from FT_LessThan are not suitable for CritType.
2810 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2811 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2812 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2813 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2814 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2817 :class:`SMESH.SMESH_GroupOnFilter`
2820 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2821 group = self.MakeGroupByCriterion(groupName, aCriterion)
2824 def MakeGroupByCriterion(self, groupName, Criterion):
2826 Create a mesh group by the given criterion
2829 groupName: the name of the mesh group
2830 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2833 :class:`SMESH.SMESH_GroupOnFilter`
2836 :meth:`smeshBuilder.GetCriterion`
2839 return self.MakeGroupByCriteria( groupName, [Criterion] )
2841 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2843 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2846 groupName: the name of the mesh group
2847 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2848 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2851 :class:`SMESH.SMESH_GroupOnFilter`
2854 :meth:`smeshBuilder.GetCriterion`
2857 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2858 group = self.MakeGroupByFilter(groupName, aFilter)
2861 def MakeGroupByFilter(self, groupName, theFilter):
2863 Create a mesh group by the given filter
2866 groupName (string): the name of the mesh group
2867 theFilter (SMESH.Filter): the filter
2870 :class:`SMESH.SMESH_GroupOnFilter`
2873 :meth:`smeshBuilder.GetFilter`
2876 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2877 #theFilter.SetMesh( self.mesh )
2878 #group.AddFrom( theFilter )
2879 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2882 def RemoveGroup(self, group):
2887 group (SMESH.SMESH_GroupBase): group to remove
2890 self.mesh.RemoveGroup(group)
2892 def RemoveGroupWithContents(self, group):
2894 Remove a group with its contents
2897 group (SMESH.SMESH_GroupBase): group to remove
2900 This operation can create gaps in numeration of nodes or elements.
2901 Call :meth:`RenumberElements` to remove the gaps.
2904 self.mesh.RemoveGroupWithContents(group)
2906 def GetGroups(self, elemType = SMESH.ALL):
2908 Get the list of groups existing in the mesh in the order of creation
2909 (starting from the oldest one)
2912 elemType (SMESH.ElementType): type of elements the groups contain;
2913 by default groups of elements of all types are returned
2916 a list of :class:`SMESH.SMESH_GroupBase`
2919 groups = self.mesh.GetGroups()
2920 if elemType == SMESH.ALL:
2924 if g.GetType() == elemType:
2925 typedGroups.append( g )
2932 Get the number of groups existing in the mesh
2935 the quantity of groups as an integer value
2938 return self.mesh.NbGroups()
2940 def GetGroupNames(self):
2942 Get the list of names of groups existing in the mesh
2948 groups = self.GetGroups()
2950 for group in groups:
2951 names.append(group.GetName())
2954 def GetGroupByName(self, name, elemType = None):
2956 Find groups by name and type
2959 name (string): name of the group of interest
2960 elemType (SMESH.ElementType): type of elements the groups contain;
2961 by default one group of any type is returned;
2962 if elemType == SMESH.ALL then all groups of any type are returned
2965 a list of :class:`SMESH.SMESH_GroupBase`
2969 for group in self.GetGroups():
2970 if group.GetName() == name:
2971 if elemType is None:
2973 if ( elemType == SMESH.ALL or
2974 group.GetType() == elemType ):
2975 groups.append( group )
2978 def UnionGroups(self, group1, group2, name):
2980 Produce a union of two groups.
2981 A new group is created. All mesh elements that are
2982 present in the initial groups are added to the new one
2985 group1 (SMESH.SMESH_GroupBase): a group
2986 group2 (SMESH.SMESH_GroupBase): another group
2989 instance of :class:`SMESH.SMESH_Group`
2992 return self.mesh.UnionGroups(group1, group2, name)
2994 def UnionListOfGroups(self, groups, name):
2996 Produce a union list of groups.
2997 New group is created. All mesh elements that are present in
2998 initial groups are added to the new one
3001 groups: list of :class:`SMESH.SMESH_GroupBase`
3004 instance of :class:`SMESH.SMESH_Group`
3006 return self.mesh.UnionListOfGroups(groups, name)
3008 def IntersectGroups(self, group1, group2, name):
3010 Prodice an intersection of two groups.
3011 A new group is created. All mesh elements that are common
3012 for the two initial groups are added to the new one.
3015 group1 (SMESH.SMESH_GroupBase): a group
3016 group2 (SMESH.SMESH_GroupBase): another group
3019 instance of :class:`SMESH.SMESH_Group`
3022 return self.mesh.IntersectGroups(group1, group2, name)
3024 def IntersectListOfGroups(self, groups, name):
3026 Produce an intersection of groups.
3027 New group is created. All mesh elements that are present in all
3028 initial groups simultaneously are added to the new one
3031 groups: a list of :class:`SMESH.SMESH_GroupBase`
3034 instance of :class:`SMESH.SMESH_Group`
3036 return self.mesh.IntersectListOfGroups(groups, name)
3038 def CutGroups(self, main_group, tool_group, name):
3040 Produce a cut of two groups.
3041 A new group is created. All mesh elements that are present in
3042 the main group but are not present in the tool group are added to the new one
3045 main_group (SMESH.SMESH_GroupBase): a group to cut from
3046 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3049 an instance of :class:`SMESH.SMESH_Group`
3052 return self.mesh.CutGroups(main_group, tool_group, name)
3054 def CutListOfGroups(self, main_groups, tool_groups, name):
3056 Produce a cut of groups.
3057 A new group is created. All mesh elements that are present in main groups
3058 but do not present in tool groups are added to the new one
3061 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3062 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3065 an instance of :class:`SMESH.SMESH_Group`
3068 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3070 def CreateDimGroup(self, groups, elemType, name,
3071 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3073 Create a standalone group of entities basing on nodes of other groups.
3076 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3077 elemType: a type of elements to include to the new group; either of
3078 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3079 name: a name of the new group.
3080 nbCommonNodes: a criterion of inclusion of an element to the new group
3081 basing on number of element nodes common with reference *groups*.
3082 Meaning of possible values are:
3084 - SMESH.ALL_NODES - include if all nodes are common,
3085 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3086 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3087 - SMEHS.MAJORITY - include if half of nodes or more are common.
3088 underlyingOnly: if *True* (default), an element is included to the
3089 new group provided that it is based on nodes of an element of *groups*;
3090 in this case the reference *groups* are supposed to be of higher dimension
3091 than *elemType*, which can be useful for example to get all faces lying on
3092 volumes of the reference *groups*.
3095 an instance of :class:`SMESH.SMESH_Group`
3098 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3100 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3102 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3104 Distribute all faces of the mesh among groups using sharp edges and optionally
3105 existing 1D elements as group boundaries.
3108 sharpAngle: edge is considered sharp if an angle between normals of
3109 adjacent faces is more than \a sharpAngle in degrees.
3110 createEdges (boolean): to create 1D elements for detected sharp edges.
3111 useExistingEdges (boolean): to use existing edges as group boundaries
3113 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3115 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3116 self.mesh.SetParameters(Parameters)
3117 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3119 def ConvertToStandalone(self, group):
3121 Convert group on geom into standalone group
3124 return self.mesh.ConvertToStandalone(group)
3126 # Get some info about mesh:
3127 # ------------------------
3129 def GetLog(self, clearAfterGet):
3131 Return the log of nodes and elements added or removed
3132 since the previous clear of the log.
3135 clearAfterGet: log is emptied after Get (safe if concurrents access)
3138 list of SMESH.log_block structures { commandType, number, coords, indexes }
3141 return self.mesh.GetLog(clearAfterGet)
3145 Clear the log of nodes and elements added or removed since the previous
3146 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3149 self.mesh.ClearLog()
3151 def SetAutoColor(self, theAutoColor):
3153 Toggle auto color mode on the object.
3154 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3157 theAutoColor (boolean): the flag which toggles auto color mode.
3160 self.mesh.SetAutoColor(theAutoColor)
3162 def GetAutoColor(self):
3164 Get flag of object auto color mode.
3170 return self.mesh.GetAutoColor()
3177 integer value, which is the internal Id of the mesh
3180 return self.mesh.GetId()
3182 def HasDuplicatedGroupNamesMED(self):
3184 Check the group names for duplications.
3185 Consider the maximum group name length stored in MED file.
3191 return self.mesh.HasDuplicatedGroupNamesMED()
3193 def GetMeshEditor(self):
3195 Obtain the mesh editor tool
3198 an instance of :class:`SMESH.SMESH_MeshEditor`
3203 def GetIDSource(self, ids, elemType = SMESH.ALL):
3205 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3206 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3210 elemType: type of elements; this parameter is used to distinguish
3211 IDs of nodes from IDs of elements; by default ids are treated as
3212 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3215 an instance of :class:`SMESH.SMESH_IDSource`
3218 call UnRegister() for the returned object as soon as it is no more useful::
3220 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3221 mesh.DoSomething( idSrc )
3225 if isinstance( ids, int ):
3227 return self.editor.MakeIDSource(ids, elemType)
3230 # Get information about mesh contents:
3231 # ------------------------------------
3233 def GetMeshInfo(self, obj = None):
3235 Get the mesh statistic.
3238 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3241 if not obj: obj = self.mesh
3242 return self.smeshpyD.GetMeshInfo(obj)
3246 Return the number of nodes in the mesh
3252 return self.mesh.NbNodes()
3254 def NbElements(self):
3256 Return the number of elements in the mesh
3262 return self.mesh.NbElements()
3264 def Nb0DElements(self):
3266 Return the number of 0d elements in the mesh
3272 return self.mesh.Nb0DElements()
3276 Return the number of ball discrete elements in the mesh
3282 return self.mesh.NbBalls()
3286 Return the number of edges in the mesh
3292 return self.mesh.NbEdges()
3294 def NbEdgesOfOrder(self, elementOrder):
3296 Return the number of edges with the given order in the mesh
3299 elementOrder: the order of elements
3300 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3306 return self.mesh.NbEdgesOfOrder(elementOrder)
3310 Return the number of faces in the mesh
3316 return self.mesh.NbFaces()
3318 def NbFacesOfOrder(self, elementOrder):
3320 Return the number of faces with the given order in the mesh
3323 elementOrder: the order of elements
3324 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3330 return self.mesh.NbFacesOfOrder(elementOrder)
3332 def NbTriangles(self):
3334 Return the number of triangles in the mesh
3340 return self.mesh.NbTriangles()
3342 def NbTrianglesOfOrder(self, elementOrder):
3344 Return the number of triangles with the given order in the mesh
3347 elementOrder: is the order of elements
3348 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3354 return self.mesh.NbTrianglesOfOrder(elementOrder)
3356 def NbBiQuadTriangles(self):
3358 Return the number of biquadratic triangles in the mesh
3364 return self.mesh.NbBiQuadTriangles()
3366 def NbQuadrangles(self):
3368 Return the number of quadrangles in the mesh
3374 return self.mesh.NbQuadrangles()
3376 def NbQuadranglesOfOrder(self, elementOrder):
3378 Return the number of quadrangles with the given order in the mesh
3381 elementOrder: the order of elements
3382 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3388 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3390 def NbBiQuadQuadrangles(self):
3392 Return the number of biquadratic quadrangles in the mesh
3398 return self.mesh.NbBiQuadQuadrangles()
3400 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3402 Return the number of polygons of given order in the mesh
3405 elementOrder: the order of elements
3406 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3412 return self.mesh.NbPolygonsOfOrder(elementOrder)
3414 def NbVolumes(self):
3416 Return the number of volumes in the mesh
3422 return self.mesh.NbVolumes()
3425 def NbVolumesOfOrder(self, elementOrder):
3427 Return the number of volumes with the given order in the mesh
3430 elementOrder: the order of elements
3431 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3437 return self.mesh.NbVolumesOfOrder(elementOrder)
3441 Return the number of tetrahedrons in the mesh
3447 return self.mesh.NbTetras()
3449 def NbTetrasOfOrder(self, elementOrder):
3451 Return the number of tetrahedrons with the given order in the mesh
3454 elementOrder: the order of elements
3455 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3461 return self.mesh.NbTetrasOfOrder(elementOrder)
3465 Return the number of hexahedrons in the mesh
3471 return self.mesh.NbHexas()
3473 def NbHexasOfOrder(self, elementOrder):
3475 Return the number of hexahedrons with the given order in the mesh
3478 elementOrder: the order of elements
3479 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3485 return self.mesh.NbHexasOfOrder(elementOrder)
3487 def NbTriQuadraticHexas(self):
3489 Return the number of triquadratic hexahedrons in the mesh
3495 return self.mesh.NbTriQuadraticHexas()
3497 def NbPyramids(self):
3499 Return the number of pyramids in the mesh
3505 return self.mesh.NbPyramids()
3507 def NbPyramidsOfOrder(self, elementOrder):
3509 Return the number of pyramids with the given order in the mesh
3512 elementOrder: the order of elements
3513 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3519 return self.mesh.NbPyramidsOfOrder(elementOrder)
3523 Return the number of prisms in the mesh
3529 return self.mesh.NbPrisms()
3531 def NbPrismsOfOrder(self, elementOrder):
3533 Return the number of prisms with the given order in the mesh
3536 elementOrder: the order of elements
3537 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3543 return self.mesh.NbPrismsOfOrder(elementOrder)
3545 def NbHexagonalPrisms(self):
3547 Return the number of hexagonal prisms in the mesh
3553 return self.mesh.NbHexagonalPrisms()
3555 def NbPolyhedrons(self):
3557 Return the number of polyhedrons in the mesh
3563 return self.mesh.NbPolyhedrons()
3565 def NbSubMesh(self):
3567 Return the number of submeshes in the mesh
3573 return self.mesh.NbSubMesh()
3575 def GetElementsId(self):
3577 Return the list of all mesh elements IDs
3580 the list of integer values
3583 :meth:`GetElementsByType`
3586 return self.mesh.GetElementsId()
3588 def GetElementsByType(self, elementType):
3590 Return the list of IDs of mesh elements with the given type
3593 elementType (SMESH.ElementType): the required type of elements
3596 list of integer values
3599 return self.mesh.GetElementsByType(elementType)
3601 def GetNodesId(self):
3603 Return the list of mesh nodes IDs
3606 the list of integer values
3609 return self.mesh.GetNodesId()
3611 # Get the information about mesh elements:
3612 # ------------------------------------
3614 def GetElementType(self, id, iselem=True):
3616 Return the type of mesh element or node
3619 the value from :class:`SMESH.ElementType` enumeration.
3620 Return SMESH.ALL if element or node with the given ID does not exist
3623 return self.mesh.GetElementType(id, iselem)
3625 def GetElementGeomType(self, id):
3627 Return the geometric type of mesh element
3630 the value from :class:`SMESH.EntityType` enumeration.
3633 return self.mesh.GetElementGeomType(id)
3635 def GetElementShape(self, id):
3637 Return the shape type of mesh element
3640 the value from :class:`SMESH.GeometryType` enumeration.
3643 return self.mesh.GetElementShape(id)
3645 def GetSubMeshElementsId(self, Shape):
3647 Return the list of sub-mesh elements IDs
3650 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3651 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3654 list of integer values
3657 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3658 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3661 return self.mesh.GetSubMeshElementsId(ShapeID)
3663 def GetSubMeshNodesId(self, Shape, all):
3665 Return the list of sub-mesh nodes IDs
3668 Shape: a geom object (sub-shape).
3669 *Shape* must be the sub-shape of a :meth:`GetShape`
3670 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3673 list of integer values
3676 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3677 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3680 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3682 def GetSubMeshElementType(self, Shape):
3684 Return type of elements on given shape
3687 Shape: a geom object (sub-shape).
3688 *Shape* must be a sub-shape of a ShapeToMesh()
3691 :class:`SMESH.ElementType`
3694 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3695 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3698 return self.mesh.GetSubMeshElementType(ShapeID)
3702 Get the mesh description
3708 return self.mesh.Dump()
3711 # Get the information about nodes and elements of a mesh by its IDs:
3712 # -----------------------------------------------------------
3714 def GetNodeXYZ(self, id):
3716 Get XYZ coordinates of a node.
3717 If there is no node for the given ID - return an empty list
3720 list of float values
3723 return self.mesh.GetNodeXYZ(id)
3725 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3727 Return list of IDs of inverse elements for the given node.
3728 If there is no node for the given ID - return an empty list
3732 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3735 list of integer values
3738 return self.mesh.GetNodeInverseElements(id,elemType)
3740 def GetNodePosition(self,NodeID):
3742 Return the position of a node on the shape
3745 :class:`SMESH.NodePosition`
3748 return self.mesh.GetNodePosition(NodeID)
3750 def GetElementPosition(self,ElemID):
3752 Return the position of an element on the shape
3755 :class:`SMESH.ElementPosition`
3758 return self.mesh.GetElementPosition(ElemID)
3760 def GetShapeID(self, id):
3762 Return the ID of the shape, on which the given node was generated.
3765 an integer value > 0 or -1 if there is no node for the given
3766 ID or the node is not assigned to any geometry
3769 return self.mesh.GetShapeID(id)
3771 def GetShapeIDForElem(self,id):
3773 Return the ID of the shape, on which the given element was generated.
3776 an integer value > 0 or -1 if there is no element for the given
3777 ID or the element is not assigned to any geometry
3780 return self.mesh.GetShapeIDForElem(id)
3782 def GetElemNbNodes(self, id):
3784 Return the number of nodes of the given element
3787 an integer value > 0 or -1 if there is no element for the given ID
3790 return self.mesh.GetElemNbNodes(id)
3792 def GetElemNode(self, id, index):
3794 Return the node ID the given (zero based) index for the given element.
3796 * If there is no element for the given ID - return -1.
3797 * If there is no node for the given index - return -2.
3800 id (int): element ID
3801 index (int): node index within the element
3804 an integer value (ID)
3807 :meth:`GetElemNodes`
3810 return self.mesh.GetElemNode(id, index)
3812 def GetElemNodes(self, id):
3814 Return the IDs of nodes of the given element
3817 a list of integer values
3820 return self.mesh.GetElemNodes(id)
3822 def IsMediumNode(self, elementID, nodeID):
3824 Return true if the given node is the medium node in the given quadratic element
3827 return self.mesh.IsMediumNode(elementID, nodeID)
3829 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3831 Return true if the given node is the medium node in one of quadratic elements
3834 nodeID: ID of the node
3835 elementType: the type of elements to check a state of the node, either of
3836 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3839 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3841 def ElemNbEdges(self, id):
3843 Return the number of edges for the given element
3846 return self.mesh.ElemNbEdges(id)
3848 def ElemNbFaces(self, id):
3850 Return the number of faces for the given element
3853 return self.mesh.ElemNbFaces(id)
3855 def GetElemFaceNodes(self,elemId, faceIndex):
3857 Return nodes of given face (counted from zero) for given volumic element.
3860 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3862 def GetFaceNormal(self, faceId, normalized=False):
3864 Return three components of normal of given mesh face
3865 (or an empty array in KO case)
3868 return self.mesh.GetFaceNormal(faceId,normalized)
3870 def FindElementByNodes(self, nodes):
3872 Return an element based on all given nodes.
3875 return self.mesh.FindElementByNodes(nodes)
3877 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3879 Return elements including all given nodes.
3882 return self.mesh.GetElementsByNodes( nodes, elemType )
3884 def IsPoly(self, id):
3886 Return true if the given element is a polygon
3889 return self.mesh.IsPoly(id)
3891 def IsQuadratic(self, id):
3893 Return true if the given element is quadratic
3896 return self.mesh.IsQuadratic(id)
3898 def GetBallDiameter(self, id):
3900 Return diameter of a ball discrete element or zero in case of an invalid *id*
3903 return self.mesh.GetBallDiameter(id)
3905 def BaryCenter(self, id):
3907 Return XYZ coordinates of the barycenter of the given element.
3908 If there is no element for the given ID - return an empty list
3911 a list of three double values
3914 :meth:`smeshBuilder.GetGravityCenter`
3917 return self.mesh.BaryCenter(id)
3919 def GetIdsFromFilter(self, filter, meshParts=[] ):
3921 Pass mesh elements through the given filter and return IDs of fitting elements
3924 filter: :class:`SMESH.Filter`
3925 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3931 :meth:`SMESH.Filter.GetIDs`
3932 :meth:`SMESH.Filter.GetElementsIdFromParts`
3935 filter.SetMesh( self.mesh )
3938 if isinstance( meshParts, Mesh ):
3939 filter.SetMesh( meshParts.GetMesh() )
3940 return theFilter.GetIDs()
3941 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3942 meshParts = [ meshParts ]
3943 return filter.GetElementsIdFromParts( meshParts )
3945 return filter.GetIDs()
3947 # Get mesh measurements information:
3948 # ------------------------------------
3950 def GetFreeBorders(self):
3952 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3953 Return a list of special structures (borders).
3956 a list of :class:`SMESH.FreeEdges.Border`
3959 aFilterMgr = self.smeshpyD.CreateFilterManager()
3960 aPredicate = aFilterMgr.CreateFreeEdges()
3961 aPredicate.SetMesh(self.mesh)
3962 aBorders = aPredicate.GetBorders()
3963 aFilterMgr.UnRegister()
3966 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3968 Get minimum distance between two nodes, elements or distance to the origin
3971 id1: first node/element id
3972 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3973 isElem1: *True* if *id1* is element id, *False* if it is node id
3974 isElem2: *True* if *id2* is element id, *False* if it is node id
3977 minimum distance value
3979 :meth:`GetMinDistance`
3982 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3983 return aMeasure.value
3985 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3987 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3990 id1: first node/element id
3991 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3992 isElem1: *True* if *id1* is element id, *False* if it is node id
3993 isElem2: *True* if *id2* is element id, *False* if it is node id
3996 :class:`SMESH.Measure` structure
4002 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
4004 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
4007 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
4009 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4014 aMeasurements = self.smeshpyD.CreateMeasurements()
4015 aMeasure = aMeasurements.MinDistance(id1, id2)
4016 genObjUnRegister([aMeasurements,id1, id2])
4019 def BoundingBox(self, objects=None, isElem=False):
4021 Get bounding box of the specified object(s)
4024 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4025 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4026 *False* specifies that *objects* are nodes
4029 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4032 :meth:`GetBoundingBox()`
4035 result = self.GetBoundingBox(objects, isElem)
4039 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4042 def GetBoundingBox(self, objects=None, isElem=False):
4044 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4047 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4048 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4049 False means that *objects* are nodes
4052 :class:`SMESH.Measure` structure
4055 :meth:`BoundingBox()`
4059 objects = [self.mesh]
4060 elif isinstance(objects, tuple):
4061 objects = list(objects)
4062 if not isinstance(objects, list):
4064 if len(objects) > 0 and isinstance(objects[0], int):
4067 unRegister = genObjUnRegister()
4069 if isinstance(o, Mesh):
4070 srclist.append(o.mesh)
4071 elif hasattr(o, "_narrow"):
4072 src = o._narrow(SMESH.SMESH_IDSource)
4073 if src: srclist.append(src)
4075 elif isinstance(o, list):
4077 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4079 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4080 unRegister.set( srclist[-1] )
4083 aMeasurements = self.smeshpyD.CreateMeasurements()
4084 unRegister.set( aMeasurements )
4085 aMeasure = aMeasurements.BoundingBox(srclist)
4088 # Mesh edition (SMESH_MeshEditor functionality):
4089 # ---------------------------------------------
4091 def RemoveElements(self, IDsOfElements):
4093 Remove the elements from the mesh by ids
4096 IDsOfElements: is a list of ids of elements to remove
4102 This operation can create gaps in numeration of elements.
4103 Call :meth:`RenumberElements` to remove the gaps.
4106 return self.editor.RemoveElements(IDsOfElements)
4108 def RemoveNodes(self, IDsOfNodes):
4110 Remove nodes from mesh by ids
4113 IDsOfNodes: is a list of ids of nodes to remove
4119 This operation can create gaps in numeration of nodes.
4120 Call :meth:`RenumberElements` to remove the gaps.
4123 return self.editor.RemoveNodes(IDsOfNodes)
4125 def RemoveNodeWithReconnection(self, nodeID ):
4127 Remove a node along with changing surrounding faces to cover a hole.
4130 nodeID: ID of node to remove
4133 return self.editor.RemoveNodeWithReconnection( nodeID )
4135 def RemoveOrphanNodes(self):
4137 Remove all orphan (free) nodes from mesh
4140 number of the removed nodes
4143 This operation can create gaps in numeration of nodes.
4144 Call :meth:`RenumberElements` to remove the gaps.
4147 return self.editor.RemoveOrphanNodes()
4149 def AddNode(self, x, y, z):
4151 Add a node to the mesh by coordinates
4157 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4158 if hasVars: self.mesh.SetParameters(Parameters)
4159 return self.editor.AddNode( x, y, z)
4161 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4163 Create a 0D element on a node with given number.
4166 IDOfNode: the ID of node for creation of the element.
4167 DuplicateElements: to add one more 0D element to a node or not
4170 ID of the new 0D element
4173 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4175 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4177 Create 0D elements on all nodes of the given elements except those
4178 nodes on which a 0D element already exists.
4181 theObject: an object on whose nodes 0D elements will be created.
4182 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4183 theGroupName: optional name of a group to add 0D elements created
4184 and/or found on nodes of *theObject*.
4185 DuplicateElements: to add one more 0D element to a node or not
4188 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4189 IDs of new and/or found 0D elements. IDs of 0D elements
4190 can be retrieved from the returned object by
4191 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4194 unRegister = genObjUnRegister()
4195 if isinstance( theObject, Mesh ):
4196 theObject = theObject.GetMesh()
4197 elif isinstance( theObject, list ):
4198 theObject = self.GetIDSource( theObject, SMESH.ALL )
4199 unRegister.set( theObject )
4200 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4202 def AddBall(self, IDOfNode, diameter):
4204 Create a ball element on a node with given ID.
4207 IDOfNode: the ID of node for creation of the element.
4208 diameter: the bal diameter.
4211 ID of the new ball element
4214 return self.editor.AddBall( IDOfNode, diameter )
4216 def AddEdge(self, IDsOfNodes):
4218 Create a linear or quadratic edge (this is determined
4219 by the number of given nodes).
4222 IDsOfNodes: list of node IDs for creation of the element.
4223 The order of nodes in this list should correspond to
4224 the :ref:`connectivity convention <connectivity_page>`.
4230 return self.editor.AddEdge(IDsOfNodes)
4232 def AddFace(self, IDsOfNodes):
4234 Create a linear or quadratic face (this is determined
4235 by the number of given nodes).
4238 IDsOfNodes: list of node IDs for creation of the element.
4239 The order of nodes in this list should correspond to
4240 the :ref:`connectivity convention <connectivity_page>`.
4246 return self.editor.AddFace(IDsOfNodes)
4248 def AddPolygonalFace(self, IdsOfNodes):
4250 Add a polygonal face defined by a list of node IDs
4253 IdsOfNodes: the list of node IDs for creation of the element.
4259 return self.editor.AddPolygonalFace(IdsOfNodes)
4261 def AddQuadPolygonalFace(self, IdsOfNodes):
4263 Add a quadratic polygonal face defined by a list of node IDs
4266 IdsOfNodes: the list of node IDs for creation of the element;
4267 corner nodes follow first.
4273 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4275 def AddVolume(self, IDsOfNodes):
4277 Create both simple and quadratic volume (this is determined
4278 by the number of given nodes).
4281 IDsOfNodes: list of node IDs for creation of the element.
4282 The order of nodes in this list should correspond to
4283 the :ref:`connectivity convention <connectivity_page>`.
4286 ID of the new volumic element
4289 return self.editor.AddVolume(IDsOfNodes)
4291 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4293 Create a volume of many faces, giving nodes for each face.
4296 IdsOfNodes: list of node IDs for volume creation, face by face.
4297 Quantities: list of integer values, Quantities[i]
4298 gives the quantity of nodes in face number i.
4301 ID of the new volumic element
4304 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4306 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4308 Create a volume of many faces, giving the IDs of the existing faces.
4311 The created volume will refer only to the nodes
4312 of the given faces, not to the faces themselves.
4315 IdsOfFaces: the list of face IDs for volume creation.
4318 ID of the new volumic element
4321 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4324 def SetNodeOnVertex(self, NodeID, Vertex):
4326 Bind a node to a vertex
4330 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4333 True if succeed else raises an exception
4336 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4337 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4341 self.editor.SetNodeOnVertex(NodeID, VertexID)
4342 except SALOME.SALOME_Exception as inst:
4343 raise ValueError(inst.details.text)
4347 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4349 Store the node position on an edge
4353 Edge: an edge (GEOM.GEOM_Object) or edge ID
4354 paramOnEdge: a parameter on the edge where the node is located
4357 True if succeed else raises an exception
4360 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4361 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4365 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4366 except SALOME.SALOME_Exception as inst:
4367 raise ValueError(inst.details.text)
4370 def SetNodeOnFace(self, NodeID, Face, u, v):
4372 Store node position on a face
4376 Face: a face (GEOM.GEOM_Object) or face ID
4377 u: U parameter on the face where the node is located
4378 v: V parameter on the face where the node is located
4381 True if succeed else raises an exception
4384 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4385 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4389 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4390 except SALOME.SALOME_Exception as inst:
4391 raise ValueError(inst.details.text)
4394 def SetNodeInVolume(self, NodeID, Solid):
4396 Bind a node to a solid
4400 Solid: a solid (GEOM.GEOM_Object) or solid ID
4403 True if succeed else raises an exception
4406 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4407 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4411 self.editor.SetNodeInVolume(NodeID, SolidID)
4412 except SALOME.SALOME_Exception as inst:
4413 raise ValueError(inst.details.text)
4416 def SetMeshElementOnShape(self, ElementID, Shape):
4418 Bind an element to a shape
4421 ElementID: an element ID
4422 Shape: a shape (GEOM.GEOM_Object) or shape ID
4425 True if succeed else raises an exception
4428 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4429 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4433 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4434 except SALOME.SALOME_Exception as inst:
4435 raise ValueError(inst.details.text)
4439 def MoveNode(self, NodeID, x, y, z):
4441 Move the node with the given id
4444 NodeID: the id of the node
4445 x: a new X coordinate
4446 y: a new Y coordinate
4447 z: a new Z coordinate
4450 True if succeed else False
4453 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4454 if hasVars: self.mesh.SetParameters(Parameters)
4455 return self.editor.MoveNode(NodeID, x, y, z)
4457 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4459 Find the node closest to a point and moves it to a point location
4462 x: the X coordinate of a point
4463 y: the Y coordinate of a point
4464 z: the Z coordinate of a point
4465 NodeID: if specified (>0), the node with this ID is moved,
4466 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4469 the ID of a moved node
4472 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4473 if hasVars: self.mesh.SetParameters(Parameters)
4474 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4476 def FindNodeClosestTo(self, x, y, z):
4478 Find the node closest to a point
4481 x: the X coordinate of a point
4482 y: the Y coordinate of a point
4483 z: the Z coordinate of a point
4489 return self.editor.FindNodeClosestTo(x, y, z)
4491 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4493 Find the elements where a point lays IN or ON
4496 x,y,z (float): coordinates of the point
4497 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4498 means elements of any type excluding nodes, discrete and 0D elements.
4499 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4502 list of IDs of found elements
4505 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4507 return self.editor.FindElementsByPoint(x, y, z, elementType)
4509 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4511 Project a point to a mesh object.
4512 Return ID of an element of given type where the given point is projected
4513 and coordinates of the projection point.
4514 In the case if nothing found, return -1 and []
4516 if isinstance( meshObject, Mesh ):
4517 meshObject = meshObject.GetMesh()
4519 meshObject = self.GetMesh()
4520 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4522 def GetPointState(self, x, y, z):
4524 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4525 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4526 UNKNOWN state means that either mesh is wrong or the analysis fails.
4529 return self.editor.GetPointState(x, y, z)
4531 def IsManifold(self):
4533 Check if a 2D mesh is manifold
4536 return self.editor.IsManifold()
4538 def IsCoherentOrientation2D(self):
4540 Check if orientation of 2D elements is coherent
4543 return self.editor.IsCoherentOrientation2D()
4545 def Get1DBranches( self, edges, startNode = 0 ):
4547 Partition given 1D elements into groups of contiguous edges.
4548 A node where number of meeting edges != 2 is a group end.
4549 An optional startNode is used to orient groups it belongs to.
4552 A list of edge groups and a list of corresponding node groups,
4553 where the group is a list of IDs of edges or nodes, like follows
4554 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4555 If a group is closed, the first and last nodes of the group are same.
4557 if isinstance( edges, Mesh ):
4558 edges = edges.GetMesh()
4559 unRegister = genObjUnRegister()
4560 if isinstance( edges, list ):
4561 edges = self.GetIDSource( edges, SMESH.EDGE )
4562 unRegister.set( edges )
4563 return self.editor.Get1DBranches( edges, startNode )
4565 def FindSharpEdges( self, angle, addExisting=False ):
4567 Return sharp edges of faces and non-manifold ones.
4568 Optionally add existing edges.
4571 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4572 addExisting: to return existing edges (1D elements) as well
4575 list of FaceEdge structures
4577 angle = ParseParameters( angle )[0]
4578 return self.editor.FindSharpEdges( angle, addExisting )
4580 def MeshToPassThroughAPoint(self, x, y, z):
4582 Find the node closest to a point and moves it to a point location
4585 x: the X coordinate of a point
4586 y: the Y coordinate of a point
4587 z: the Z coordinate of a point
4590 the ID of a moved node
4593 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4595 def InverseDiag(self, NodeID1, NodeID2):
4597 Replace two neighbour triangles sharing Node1-Node2 link
4598 with the triangles built on the same 4 nodes but having other common link.
4601 NodeID1: the ID of the first node
4602 NodeID2: the ID of the second node
4605 False if proper faces were not found
4607 return self.editor.InverseDiag(NodeID1, NodeID2)
4609 def DeleteDiag(self, NodeID1, NodeID2):
4611 Replace two neighbour triangles sharing *Node1-Node2* link
4612 with a quadrangle built on the same 4 nodes.
4615 NodeID1: ID of the first node
4616 NodeID2: ID of the second node
4619 False if proper faces were not found
4622 This operation can create gaps in numeration of elements.
4623 Call :meth:`RenumberElements` to remove the gaps.
4626 return self.editor.DeleteDiag(NodeID1, NodeID2)
4628 def AddNodeOnSegment(self, Node1, Node2, position = 0.5):
4630 Replace each triangle bound by Node1-Node2 segment with
4631 two triangles by connecting a node made on the link with a node
4632 opposite to the link.
4635 Node1: ID of the first node
4636 Node2: ID of the second node
4637 position: location [0,1] of the new node on the segment
4639 return self.editor.AddNodeOnSegment(Node1, Node2, position)
4641 def AddNodeOnFace(self, face, x, y, z):
4643 Split a face into triangles by adding a new node onto the face
4644 and connecting the new node with face nodes
4647 face: ID of the face
4648 x,y,z: coordinates of the new node
4650 return self.editor.AddNodeOnFace(face, x, y, z)
4652 def Reorient(self, IDsOfElements=None):
4654 Reorient elements by ids
4657 IDsOfElements: if undefined reorients all mesh elements
4660 True if succeed else False
4663 if IDsOfElements == None:
4664 IDsOfElements = self.GetElementsId()
4665 return self.editor.Reorient(IDsOfElements)
4667 def ReorientObject(self, theObject):
4669 Reorient all elements of the object
4672 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4675 True if succeed else False
4678 if ( isinstance( theObject, Mesh )):
4679 theObject = theObject.GetMesh()
4680 return self.editor.ReorientObject(theObject)
4682 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4684 Reorient faces contained in *the2DObject*.
4687 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4688 theDirection: a desired direction of normal of *theFace*.
4689 It can be either a GEOM vector or a list of coordinates [x,y,z].
4690 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4691 compared with theDirection. It can be either ID of face or a point
4692 by which the face will be found. The point can be given as either
4693 a GEOM vertex or a list of point coordinates.
4696 number of reoriented faces
4699 unRegister = genObjUnRegister()
4701 if isinstance( the2DObject, Mesh ):
4702 the2DObject = the2DObject.GetMesh()
4703 if isinstance( the2DObject, list ):
4704 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4705 unRegister.set( the2DObject )
4706 # check theDirection
4707 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4708 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4709 if isinstance( theDirection, list ):
4710 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4711 # prepare theFace and thePoint
4712 theFace = theFaceOrPoint
4713 thePoint = PointStruct(0,0,0)
4714 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4715 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4717 if isinstance( theFaceOrPoint, list ):
4718 thePoint = PointStruct( *theFaceOrPoint )
4720 if isinstance( theFaceOrPoint, PointStruct ):
4721 thePoint = theFaceOrPoint
4723 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4725 def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4727 Reorient faces contained in a list of *objectFaces*
4728 equally to faces contained in a list of *referenceFaces*.
4731 objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4732 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.
4735 number of reoriented faces.
4737 if not isinstance( objectFaces, list ):
4738 objectFaces = [ objectFaces ]
4739 for i,obj2D in enumerate( objectFaces ):
4740 if isinstance( obj2D, Mesh ):
4741 objectFaces[i] = obj2D.GetMesh()
4742 if not isinstance( referenceFaces, list ):
4743 referenceFaces = [ referenceFaces ]
4745 return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4748 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4750 Reorient faces according to adjacent volumes.
4753 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4754 either IDs of faces or face groups.
4755 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4756 theOutsideNormal: to orient faces to have their normals
4757 pointing either *outside* or *inside* the adjacent volumes.
4760 number of reoriented faces.
4763 unRegister = genObjUnRegister()
4765 if not isinstance( the2DObject, list ):
4766 the2DObject = [ the2DObject ]
4767 elif the2DObject and isinstance( the2DObject[0], int ):
4768 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4769 unRegister.set( the2DObject )
4770 the2DObject = [ the2DObject ]
4771 for i,obj2D in enumerate( the2DObject ):
4772 if isinstance( obj2D, Mesh ):
4773 the2DObject[i] = obj2D.GetMesh()
4774 if isinstance( obj2D, list ):
4775 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4776 unRegister.set( the2DObject[i] )
4778 if isinstance( the3DObject, Mesh ):
4779 the3DObject = the3DObject.GetMesh()
4780 if isinstance( the3DObject, list ):
4781 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4782 unRegister.set( the3DObject )
4783 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4785 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4787 Fuse the neighbouring triangles into quadrangles.
4790 IDsOfElements: The triangles to be fused.
4791 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4792 applied to possible quadrangles to choose a neighbour to fuse with.
4793 Note that not all items of :class:`SMESH.FunctorType` corresponds
4794 to numerical functors.
4795 MaxAngle: is the maximum angle between element normals at which the fusion
4796 is still performed; theMaxAngle is measured in radians.
4797 Also it could be a name of variable which defines angle in degrees.
4800 True in case of success, False otherwise.
4803 This operation can create gaps in numeration of elements.
4804 Call :meth:`RenumberElements` to remove the gaps.
4807 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4808 self.mesh.SetParameters(Parameters)
4809 if not IDsOfElements:
4810 IDsOfElements = self.GetElementsId()
4811 Functor = self.smeshpyD.GetFunctor(theCriterion)
4812 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4814 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4816 Fuse the neighbouring triangles of the object into quadrangles
4819 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4820 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4821 applied to possible quadrangles to choose a neighbour to fuse with.
4822 Note that not all items of :class:`SMESH.FunctorType` corresponds
4823 to numerical functors.
4824 MaxAngle: a max angle between element normals at which the fusion
4825 is still performed; theMaxAngle is measured in radians.
4828 True in case of success, False otherwise.
4831 This operation can create gaps in numeration of elements.
4832 Call :meth:`RenumberElements` to remove the gaps.
4835 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4836 self.mesh.SetParameters(Parameters)
4837 if isinstance( theObject, Mesh ):
4838 theObject = theObject.GetMesh()
4839 Functor = self.smeshpyD.GetFunctor(theCriterion)
4840 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4842 def QuadToTri (self, IDsOfElements, theCriterion = None):
4844 Split quadrangles into triangles.
4847 IDsOfElements: the faces to be splitted.
4848 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4849 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4850 value, then quadrangles will be split by the smallest diagonal.
4851 Note that not all items of :class:`SMESH.FunctorType` corresponds
4852 to numerical functors.
4855 True in case of success, False otherwise.
4858 This operation can create gaps in numeration of elements.
4859 Call :meth:`RenumberElements` to remove the gaps.
4861 if IDsOfElements == []:
4862 IDsOfElements = self.GetElementsId()
4863 if theCriterion is None:
4864 theCriterion = FT_MaxElementLength2D
4865 Functor = self.smeshpyD.GetFunctor(theCriterion)
4866 return self.editor.QuadToTri(IDsOfElements, Functor)
4868 def QuadToTriObject (self, theObject, theCriterion = None):
4870 Split quadrangles into triangles.
4873 theObject: the object from which the list of elements is taken,
4874 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4875 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4876 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4877 value, then quadrangles will be split by the smallest diagonal.
4878 Note that not all items of :class:`SMESH.FunctorType` corresponds
4879 to numerical functors.
4882 True in case of success, False otherwise.
4885 This operation can create gaps in numeration of elements.
4886 Call :meth:`RenumberElements` to remove the gaps.
4888 if ( isinstance( theObject, Mesh )):
4889 theObject = theObject.GetMesh()
4890 if theCriterion is None:
4891 theCriterion = FT_MaxElementLength2D
4892 Functor = self.smeshpyD.GetFunctor(theCriterion)
4893 return self.editor.QuadToTriObject(theObject, Functor)
4895 def QuadTo4Tri (self, theElements=[]):
4897 Split each of given quadrangles into 4 triangles. A node is added at the center of
4901 theElements: the faces to be splitted. This can be either
4902 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4903 or a list of face IDs. By default all quadrangles are split
4906 This operation can create gaps in numeration of elements.
4907 Call :meth:`RenumberElements` to remove the gaps.
4909 unRegister = genObjUnRegister()
4910 if isinstance( theElements, Mesh ):
4911 theElements = theElements.mesh
4912 elif not theElements:
4913 theElements = self.mesh
4914 elif isinstance( theElements, list ):
4915 theElements = self.GetIDSource( theElements, SMESH.FACE )
4916 unRegister.set( theElements )
4917 return self.editor.QuadTo4Tri( theElements )
4919 def SplitQuad (self, IDsOfElements, Diag13):
4921 Split quadrangles into triangles.
4924 IDsOfElements: the faces to be splitted
4925 Diag13 (boolean): is used to choose a diagonal for splitting.
4928 True in case of success, False otherwise.
4931 This operation can create gaps in numeration of elements.
4932 Call :meth:`RenumberElements` to remove the gaps.
4934 if IDsOfElements == []:
4935 IDsOfElements = self.GetElementsId()
4936 return self.editor.SplitQuad(IDsOfElements, Diag13)
4938 def SplitQuadObject (self, theObject, Diag13):
4940 Split quadrangles into triangles.
4943 theObject: the object from which the list of elements is taken,
4944 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4945 Diag13 (boolean): is used to choose a diagonal for splitting.
4948 True in case of success, False otherwise.
4951 This operation can create gaps in numeration of elements.
4952 Call :meth:`RenumberElements` to remove the gaps.
4954 if ( isinstance( theObject, Mesh )):
4955 theObject = theObject.GetMesh()
4956 return self.editor.SplitQuadObject(theObject, Diag13)
4958 def BestSplit (self, IDOfQuad, theCriterion):
4960 Find a better splitting of the given quadrangle.
4963 IDOfQuad: the ID of the quadrangle to be splitted.
4964 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4965 choose a diagonal for splitting.
4966 Note that not all items of :class:`SMESH.FunctorType` corresponds
4967 to numerical functors.
4970 * 1 if 1-3 diagonal is better,
4971 * 2 if 2-4 diagonal is better,
4972 * 0 if error occurs.
4975 This operation can create gaps in numeration of elements.
4976 Call :meth:`RenumberElements` to remove the gaps.
4978 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4980 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4982 Split volumic elements into tetrahedrons
4985 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4986 method: flags passing splitting method:
4987 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4988 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4991 This operation can create gaps in numeration of elements.
4992 Call :meth:`RenumberElements` to remove the gaps.
4994 unRegister = genObjUnRegister()
4995 if isinstance( elems, Mesh ):
4996 elems = elems.GetMesh()
4997 if ( isinstance( elems, list )):
4998 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4999 unRegister.set( elems )
5000 self.editor.SplitVolumesIntoTetra(elems, method)
5003 def SplitBiQuadraticIntoLinear(self, elems=None):
5005 Split bi-quadratic elements into linear ones without creation of additional nodes:
5007 - bi-quadratic triangle will be split into 3 linear quadrangles;
5008 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
5009 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
5011 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
5012 will be split in order to keep the mesh conformal.
5015 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
5016 if None (default), all bi-quadratic elements will be split
5019 This operation can create gaps in numeration of elements.
5020 Call :meth:`RenumberElements` to remove the gaps.
5022 unRegister = genObjUnRegister()
5023 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
5024 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
5025 unRegister.set( elems )
5027 elems = [ self.GetMesh() ]
5028 if isinstance( elems, Mesh ):
5029 elems = [ elems.GetMesh() ]
5030 if not isinstance( elems, list ):
5032 self.editor.SplitBiQuadraticIntoLinear( elems )
5034 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
5035 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
5037 Split hexahedra into prisms
5040 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5041 startHexPoint: a point used to find a hexahedron for which *facetNormal*
5042 gives a normal vector defining facets to split into triangles.
5043 *startHexPoint* can be either a triple of coordinates or a vertex.
5044 facetNormal: a normal to a facet to split into triangles of a
5045 hexahedron found by *startHexPoint*.
5046 *facetNormal* can be either a triple of coordinates or an edge.
5047 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
5048 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
5049 allDomains: if :code:`False`, only hexahedra adjacent to one closest
5050 to *startHexPoint* are split, else *startHexPoint*
5051 is used to find the facet to split in all domains present in *elems*.
5054 This operation can create gaps in numeration of elements.
5055 Call :meth:`RenumberElements` to remove the gaps.
5058 unRegister = genObjUnRegister()
5059 if isinstance( elems, Mesh ):
5060 elems = elems.GetMesh()
5061 if ( isinstance( elems, list )):
5062 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5063 unRegister.set( elems )
5066 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5067 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5068 elif isinstance( startHexPoint, list ):
5069 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5072 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5073 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5074 elif isinstance( facetNormal, list ):
5075 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5078 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5080 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5082 def SplitQuadsNearTriangularFacets(self):
5084 Split quadrangle faces near triangular facets of volumes
5087 This operation can create gaps in numeration of elements.
5088 Call :meth:`RenumberElements` to remove the gaps.
5090 faces_array = self.GetElementsByType(SMESH.FACE)
5091 for face_id in faces_array:
5092 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5093 quad_nodes = self.mesh.GetElemNodes(face_id)
5094 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5095 isVolumeFound = False
5096 for node1_elem in node1_elems:
5097 if not isVolumeFound:
5098 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5099 nb_nodes = self.GetElemNbNodes(node1_elem)
5100 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5101 volume_elem = node1_elem
5102 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5103 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5104 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5105 isVolumeFound = True
5106 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5107 self.SplitQuad([face_id], False) # diagonal 2-4
5108 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5109 isVolumeFound = True
5110 self.SplitQuad([face_id], True) # diagonal 1-3
5111 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5112 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5113 isVolumeFound = True
5114 self.SplitQuad([face_id], True) # diagonal 1-3
5116 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5118 Split hexahedrons into tetrahedrons.
5120 This operation uses :doc:`pattern_mapping` functionality for splitting.
5123 theObject: the object from which the list of hexahedrons is taken;
5124 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5125 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5126 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5127 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5128 key-point will be mapped into *theNode001*-th node of each volume.
5129 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5132 True in case of success, False otherwise.
5135 This operation can create gaps in numeration of elements.
5136 Call :meth:`RenumberElements` to remove the gaps.
5144 # (0,0,1) 4.---------.7 * |
5151 # (0,0,0) 0.---------.3
5152 pattern_tetra = "!!! Nb of points: \n 8 \n\
5162 !!! Indices of points of 6 tetras: \n\
5170 pattern = self.smeshpyD.GetPattern()
5171 isDone = pattern.LoadFromFile(pattern_tetra)
5173 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5176 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5177 isDone = pattern.MakeMesh(self.mesh, False, False)
5178 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5180 # split quafrangle faces near triangular facets of volumes
5181 self.SplitQuadsNearTriangularFacets()
5185 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5187 Split hexahedrons into prisms.
5189 Uses the :doc:`pattern_mapping` functionality for splitting.
5192 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5193 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5194 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5195 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5196 will be mapped into the *theNode001* -th node of each volume.
5197 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5200 True in case of success, False otherwise.
5203 This operation can create gaps in numeration of elements.
5204 Call :meth:`RenumberElements` to remove the gaps.
5206 # Pattern: 5.---------.6
5211 # (0,0,1) 4.---------.7 |
5218 # (0,0,0) 0.---------.3
5219 pattern_prism = "!!! Nb of points: \n 8 \n\
5229 !!! Indices of points of 2 prisms: \n\
5233 pattern = self.smeshpyD.GetPattern()
5234 isDone = pattern.LoadFromFile(pattern_prism)
5236 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5239 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5240 isDone = pattern.MakeMesh(self.mesh, False, False)
5241 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5243 # Split quafrangle faces near triangular facets of volumes
5244 self.SplitQuadsNearTriangularFacets()
5248 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5249 MaxNbOfIterations, MaxAspectRatio, Method):
5254 IDsOfElements: the list if ids of elements to smooth
5255 IDsOfFixedNodes: the list of ids of fixed nodes.
5256 Note that nodes built on edges and boundary nodes are always fixed.
5257 MaxNbOfIterations: the maximum number of iterations
5258 MaxAspectRatio: varies in range [1.0, inf]
5259 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5260 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5263 True in case of success, False otherwise.
5266 if IDsOfElements == []:
5267 IDsOfElements = self.GetElementsId()
5268 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5269 self.mesh.SetParameters(Parameters)
5270 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5271 MaxNbOfIterations, MaxAspectRatio, Method)
5273 def SmoothObject(self, theObject, IDsOfFixedNodes,
5274 MaxNbOfIterations, MaxAspectRatio, Method):
5276 Smooth elements which belong to the given object
5279 theObject: the object to smooth
5280 IDsOfFixedNodes: the list of ids of fixed nodes.
5281 Note that nodes built on edges and boundary nodes are always fixed.
5282 MaxNbOfIterations: the maximum number of iterations
5283 MaxAspectRatio: varies in range [1.0, inf]
5284 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5285 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5288 True in case of success, False otherwise.
5291 if ( isinstance( theObject, Mesh )):
5292 theObject = theObject.GetMesh()
5293 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5294 MaxNbOfIterations, MaxAspectRatio, Method)
5296 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5297 MaxNbOfIterations, MaxAspectRatio, Method):
5299 Parametrically smooth the given elements
5302 IDsOfElements: the list if ids of elements to smooth
5303 IDsOfFixedNodes: the list of ids of fixed nodes.
5304 Note that nodes built on edges and boundary nodes are always fixed.
5305 MaxNbOfIterations: the maximum number of iterations
5306 MaxAspectRatio: varies in range [1.0, inf]
5307 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5308 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5311 True in case of success, False otherwise.
5314 if IDsOfElements == []:
5315 IDsOfElements = self.GetElementsId()
5316 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5317 self.mesh.SetParameters(Parameters)
5318 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5319 MaxNbOfIterations, MaxAspectRatio, Method)
5321 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5322 MaxNbOfIterations, MaxAspectRatio, Method):
5324 Parametrically smooth the elements which belong to the given object
5327 theObject: the object to smooth
5328 IDsOfFixedNodes: the list of ids of fixed nodes.
5329 Note that nodes built on edges and boundary nodes are always fixed.
5330 MaxNbOfIterations: the maximum number of iterations
5331 MaxAspectRatio: varies in range [1.0, inf]
5332 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5333 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5336 True in case of success, False otherwise.
5339 if ( isinstance( theObject, Mesh )):
5340 theObject = theObject.GetMesh()
5341 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5342 MaxNbOfIterations, MaxAspectRatio, Method)
5344 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5346 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5347 them with quadratic with the same id.
5350 theForce3d: method of new node creation:
5352 * False - the medium node lies at the geometrical entity from which the mesh element is built
5353 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5354 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5355 theToBiQuad: If True, converts the mesh to bi-quadratic
5358 :class:`SMESH.ComputeError` which can hold a warning
5361 If *theSubMesh* is provided, the mesh can become non-conformal
5364 This operation can create gaps in numeration of nodes or elements.
5365 Call :meth:`RenumberElements` to remove the gaps.
5368 if isinstance( theSubMesh, Mesh ):
5369 theSubMesh = theSubMesh.mesh
5371 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5374 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5376 self.editor.ConvertToQuadratic(theForce3d)
5377 error = self.editor.GetLastError()
5378 if error and error.comment:
5379 print(error.comment)
5382 def ConvertFromQuadratic(self, theSubMesh=None):
5384 Convert the mesh from quadratic to ordinary,
5385 deletes old quadratic elements,
5386 replacing them with ordinary mesh elements with the same id.
5389 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5392 If *theSubMesh* is provided, the mesh can become non-conformal
5395 This operation can create gaps in numeration of nodes or elements.
5396 Call :meth:`RenumberElements` to remove the gaps.
5400 self.editor.ConvertFromQuadraticObject(theSubMesh)
5402 return self.editor.ConvertFromQuadratic()
5404 def Make2DMeshFrom3D(self):
5406 Create 2D mesh as skin on boundary faces of a 3D mesh
5409 True if operation has been completed successfully, False otherwise
5412 return self.editor.Make2DMeshFrom3D()
5414 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5415 toCopyElements=False, toCopyExistingBondary=False):
5417 Create missing boundary elements
5420 elements: elements whose boundary is to be checked:
5421 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5422 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5423 dimension: defines type of boundary elements to create, either of
5424 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5425 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5426 groupName: a name of group to store created boundary elements in,
5427 "" means not to create the group
5428 meshName: a name of new mesh to store created boundary elements in,
5429 "" means not to create the new mesh
5430 toCopyElements: if True, the checked elements will be copied into
5431 the new mesh else only boundary elements will be copied into the new mesh
5432 toCopyExistingBondary: if True, not only new but also pre-existing
5433 boundary elements will be copied into the new mesh
5436 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5439 unRegister = genObjUnRegister()
5440 if isinstance( elements, Mesh ):
5441 elements = elements.GetMesh()
5442 if ( isinstance( elements, list )):
5443 elemType = SMESH.ALL
5444 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5445 elements = self.editor.MakeIDSource(elements, elemType)
5446 unRegister.set( elements )
5447 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5448 toCopyElements,toCopyExistingBondary)
5449 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5452 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5453 toCopyAll=False, groups=[]):
5455 Create missing boundary elements around either the whole mesh or
5459 dimension: defines type of boundary elements to create, either of
5460 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5461 groupName: a name of group to store all boundary elements in,
5462 "" means not to create the group
5463 meshName: a name of a new mesh, which is a copy of the initial
5464 mesh + created boundary elements; "" means not to create the new mesh
5465 toCopyAll: if True, the whole initial mesh will be copied into
5466 the new mesh else only boundary elements will be copied into the new mesh
5467 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5470 tuple( long, mesh, group )
5471 - long - number of added boundary elements
5472 - mesh - the :class:`Mesh` where elements were added to
5473 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5476 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5478 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5479 return nb, mesh, group
5481 def RenumberNodes(self):
5483 Renumber mesh nodes to remove unused node IDs
5485 self.editor.RenumberNodes()
5487 def RenumberElements(self):
5489 Renumber mesh elements to remove unused element IDs
5491 self.editor.RenumberElements()
5493 def _getIdSourceList(self, arg, idType, unRegister):
5495 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5497 if arg and isinstance( arg, list ):
5498 if isinstance( arg[0], int ):
5499 arg = self.GetIDSource( arg, idType )
5500 unRegister.set( arg )
5501 elif isinstance( arg[0], Mesh ):
5502 arg[0] = arg[0].GetMesh()
5503 elif isinstance( arg, Mesh ):
5505 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5509 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5510 MakeGroups=False, TotalAngle=False):
5512 Generate new elements by rotation of the given elements and nodes around the axis
5515 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5516 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5517 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5518 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5519 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5520 which defines angle in degrees
5521 NbOfSteps: the number of steps
5522 Tolerance: tolerance
5523 MakeGroups: forces the generation of new groups from existing ones
5524 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5525 of all steps, else - size of each step
5528 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5531 unRegister = genObjUnRegister()
5532 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5533 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5534 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5536 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5537 Axis = self.smeshpyD.GetAxisStruct( Axis )
5538 if isinstance( Axis, list ):
5539 Axis = SMESH.AxisStruct( *Axis )
5541 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5542 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5543 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5544 self.mesh.SetParameters(Parameters)
5545 if TotalAngle and NbOfSteps:
5546 AngleInRadians /= NbOfSteps
5547 return self.editor.RotationSweepObjects( nodes, edges, faces,
5548 Axis, AngleInRadians,
5549 NbOfSteps, Tolerance, MakeGroups)
5551 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5552 MakeGroups=False, TotalAngle=False):
5554 Generate new elements by rotation of the elements around the axis
5557 IDsOfElements: the list of ids of elements to sweep
5558 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5559 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5560 NbOfSteps: the number of steps
5561 Tolerance: tolerance
5562 MakeGroups: forces the generation of new groups from existing ones
5563 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5564 of all steps, else - size of each step
5567 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5570 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5571 AngleInRadians, NbOfSteps, Tolerance,
5572 MakeGroups, TotalAngle)
5574 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5575 MakeGroups=False, TotalAngle=False):
5577 Generate new elements by rotation of the elements of object around the axis
5578 theObject object which elements should be sweeped.
5579 It can be a mesh, a sub mesh or a group.
5582 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5583 AngleInRadians: the angle of Rotation
5584 NbOfSteps: number of steps
5585 Tolerance: tolerance
5586 MakeGroups: forces the generation of new groups from existing ones
5587 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5588 of all steps, else - size of each step
5591 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5594 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5595 AngleInRadians, NbOfSteps, Tolerance,
5596 MakeGroups, TotalAngle )
5598 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5599 MakeGroups=False, TotalAngle=False):
5601 Generate new elements by rotation of the elements of object around the axis
5602 theObject object which elements should be sweeped.
5603 It can be a mesh, a sub mesh or a group.
5606 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5607 AngleInRadians: the angle of Rotation
5608 NbOfSteps: number of steps
5609 Tolerance: tolerance
5610 MakeGroups: forces the generation of new groups from existing ones
5611 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5612 of all steps, else - size of each step
5615 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5616 empty list otherwise
5619 return self.RotationSweepObjects([],theObject,[], Axis,
5620 AngleInRadians, NbOfSteps, Tolerance,
5621 MakeGroups, TotalAngle)
5623 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5624 MakeGroups=False, TotalAngle=False):
5626 Generate new elements by rotation of the elements of object around the axis
5627 theObject object which elements should be sweeped.
5628 It can be a mesh, a sub mesh or a group.
5631 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5632 AngleInRadians: the angle of Rotation
5633 NbOfSteps: number of steps
5634 Tolerance: tolerance
5635 MakeGroups: forces the generation of new groups from existing ones
5636 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5637 of all steps, else - size of each step
5640 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5643 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5644 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5646 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5647 scaleFactors=[], linearVariation=False, basePoint=[],
5648 angles=[], anglesVariation=False):
5650 Generate new elements by extrusion of the given elements and nodes
5653 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5654 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5655 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5656 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5657 the direction and value of extrusion for one step (the total extrusion
5658 length will be NbOfSteps * ||StepVector||)
5659 NbOfSteps: the number of steps
5660 MakeGroups: forces the generation of new groups from existing ones
5661 scaleFactors: optional scale factors to apply during extrusion
5662 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5663 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5664 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5665 nodes and elements being extruded is used as the scaling center.
5668 - a list of tree components of the point or
5671 angles: list of angles in radians. Nodes at each extrusion step are rotated
5672 around *basePoint*, additionally to previous steps.
5673 anglesVariation: forces the computation of rotation angles as linear
5674 variation of the given *angles* along path steps
5676 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5678 Example: :ref:`tui_extrusion`
5680 unRegister = genObjUnRegister()
5681 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5682 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5683 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5685 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5686 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5687 if isinstance( StepVector, list ):
5688 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5690 if isinstance( basePoint, int):
5691 xyz = self.GetNodeXYZ( basePoint )
5693 raise RuntimeError("Invalid node ID: %s" % basePoint)
5695 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5696 basePoint = self.geompyD.PointCoordinates( basePoint )
5698 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5699 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5700 angles,angleParameters,hasVars = ParseAngles(angles)
5701 Parameters = StepVector.PS.parameters + var_separator + \
5702 Parameters + var_separator + \
5703 scaleParameters + var_separator + angleParameters
5704 self.mesh.SetParameters(Parameters)
5706 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5707 StepVector, NbOfSteps, MakeGroups,
5708 scaleFactors, linearVariation, basePoint,
5709 angles, anglesVariation )
5712 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5714 Generate new elements by extrusion of the elements with given ids
5717 IDsOfElements: the list of ids of elements or nodes for extrusion
5718 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5719 the direction and value of extrusion for one step (the total extrusion
5720 length will be NbOfSteps * ||StepVector||)
5721 NbOfSteps: the number of steps
5722 MakeGroups: forces the generation of new groups from existing ones
5723 IsNodes: is True if elements with given ids are nodes
5726 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5728 Example: :ref:`tui_extrusion`
5731 if IsNodes: n = IDsOfElements
5732 else : e,f, = IDsOfElements,IDsOfElements
5733 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5735 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5736 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5738 Generate new elements by extrusion along the normal to a discretized surface or wire
5741 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5742 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5743 StepSize: length of one extrusion step (the total extrusion
5744 length will be *NbOfSteps* *StepSize*).
5745 NbOfSteps: number of extrusion steps.
5746 ByAverageNormal: if True each node is translated by *StepSize*
5747 along the average of the normal vectors to the faces sharing the node;
5748 else each node is translated along the same average normal till
5749 intersection with the plane got by translation of the face sharing
5750 the node along its own normal by *StepSize*.
5751 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5752 for every node of *Elements*.
5753 MakeGroups: forces generation of new groups from existing ones.
5754 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5755 is not yet implemented. This parameter is used if *Elements* contains
5756 both faces and edges, i.e. *Elements* is a Mesh.
5759 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5760 empty list otherwise.
5761 Example: :ref:`tui_extrusion`
5764 unRegister = genObjUnRegister()
5765 if isinstance( Elements, Mesh ):
5766 Elements = [ Elements.GetMesh() ]
5767 if isinstance( Elements, list ):
5769 raise RuntimeError("Elements empty!")
5770 if isinstance( Elements[0], Mesh ):
5771 Elements = [ Elements[0].GetMesh() ]
5772 if isinstance( Elements[0], int ):
5773 Elements = self.GetIDSource( Elements, SMESH.ALL )
5774 unRegister.set( Elements )
5775 if not isinstance( Elements, list ):
5776 Elements = [ Elements ]
5777 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5778 self.mesh.SetParameters(Parameters)
5779 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5780 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5782 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5784 Generate new elements by extrusion of the elements or nodes which belong to the object
5787 theObject: the object whose elements or nodes should be processed.
5788 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5789 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5790 the direction and value of extrusion for one step (the total extrusion
5791 length will be NbOfSteps * ||StepVector||)
5792 NbOfSteps: the number of steps
5793 MakeGroups: forces the generation of new groups from existing ones
5794 IsNodes: is True if elements to extrude are nodes
5797 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5798 Example: :ref:`tui_extrusion`
5802 if IsNodes: n = theObject
5803 else : e,f, = theObject,theObject
5804 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5806 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5808 Generate new elements by extrusion of edges which belong to the object
5811 theObject: object whose 1D elements should be processed.
5812 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5813 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5814 the direction and value of extrusion for one step (the total extrusion
5815 length will be NbOfSteps * ||StepVector||)
5816 NbOfSteps: the number of steps
5817 MakeGroups: to generate new groups from existing ones
5820 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5821 Example: :ref:`tui_extrusion`
5824 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5826 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5828 Generate new elements by extrusion of faces which belong to the object
5831 theObject: object whose 2D elements should be processed.
5832 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5833 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5834 the direction and value of extrusion for one step (the total extrusion
5835 length will be NbOfSteps * ||StepVector||)
5836 NbOfSteps: the number of steps
5837 MakeGroups: forces the generation of new groups from existing ones
5840 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5841 Example: :ref:`tui_extrusion`
5844 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5846 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5847 ExtrFlags, SewTolerance, MakeGroups=False):
5849 Generate new elements by extrusion of the elements with given ids
5852 IDsOfElements: is ids of elements
5853 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5854 the direction and value of extrusion for one step (the total extrusion
5855 length will be NbOfSteps * ||StepVector||)
5856 NbOfSteps: the number of steps
5857 ExtrFlags: sets flags for extrusion
5858 SewTolerance: uses for comparing locations of nodes if flag
5859 EXTRUSION_FLAG_SEW is set
5860 MakeGroups: forces the generation of new groups from existing ones
5863 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5866 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5867 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5868 if isinstance( StepVector, list ):
5869 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5870 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5871 ExtrFlags, SewTolerance, MakeGroups)
5873 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5874 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5875 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5876 ScaleFactors=[], ScalesVariation=False):
5878 Generate new elements by extrusion of the given elements and nodes along the path.
5879 The path of extrusion must be a meshed edge.
5882 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5883 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5884 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5885 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5886 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
5887 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5888 HasAngles: not used obsolete
5889 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5890 around *basePoint*, additionally to previous steps.
5891 LinearVariation: forces the computation of rotation angles as linear
5892 variation of the given Angles along path steps
5893 HasRefPoint: allows using the reference point
5894 RefPoint: optional scaling and rotation center (mass center of the extruded
5895 elements by default). The User can specify any point as the Reference Point.
5896 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5897 MakeGroups: forces the generation of new groups from existing ones
5898 ScaleFactors: optional scale factors to apply during extrusion
5899 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5900 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5903 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5904 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5905 Example: :ref:`tui_extrusion_along_path`
5908 unRegister = genObjUnRegister()
5909 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5910 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5911 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5913 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5914 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5915 if isinstance( RefPoint, list ):
5916 if not RefPoint: RefPoint = [0,0,0]
5917 RefPoint = SMESH.PointStruct( *RefPoint )
5918 if isinstance( PathObject, Mesh ):
5919 PathObject = PathObject.GetMesh()
5920 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5921 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5922 Parameters = AnglesParameters + var_separator + \
5923 RefPoint.parameters + var_separator + ScalesParameters
5924 self.mesh.SetParameters(Parameters)
5925 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5926 PathObject, PathShape, NodeStart,
5927 HasAngles, Angles, LinearVariation,
5928 HasRefPoint, RefPoint, MakeGroups,
5929 ScaleFactors, ScalesVariation)
5931 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5932 HasAngles=False, Angles=[], LinearVariation=False,
5933 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5934 ElemType=SMESH.FACE):
5936 Generate new elements by extrusion of the given elements.
5937 The path of extrusion must be a meshed edge.
5940 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5941 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5942 NodeStart: the start node from Path. Defines the direction of extrusion
5943 HasAngles: not used obsolete
5944 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5945 around *basePoint*, additionally to previous steps.
5946 LinearVariation: forces the computation of rotation angles as linear
5947 variation of the given Angles along path steps
5948 HasRefPoint: allows using the reference point
5949 RefPoint: the reference point around which the elements are rotated (the mass
5950 center of the elements by default).
5951 The User can specify any point as the Reference Point.
5952 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5953 MakeGroups: forces the generation of new groups from existing ones
5954 ElemType: type of elements for extrusion (if param Base is a mesh)
5957 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5958 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5959 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5961 Example: :ref:`tui_extrusion_along_path`
5965 if ElemType == SMESH.NODE: n = Base
5966 if ElemType == SMESH.EDGE: e = Base
5967 if ElemType == SMESH.FACE: f = Base
5968 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5969 HasAngles, Angles, LinearVariation,
5970 HasRefPoint, RefPoint, MakeGroups)
5971 if MakeGroups: return gr,er
5974 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5975 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5976 MakeGroups=False, LinearVariation=False):
5978 Generate new elements by extrusion of the given elements.
5979 The path of extrusion must be a meshed edge.
5982 IDsOfElements: ids of elements
5983 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5984 PathShape: shape (edge) defines the sub-mesh for the path
5985 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5986 HasAngles: not used obsolete
5987 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5988 around *basePoint*, additionally to previous steps.
5989 HasRefPoint: allows using the reference point
5990 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5991 The User can specify any point as the Reference Point.
5992 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5993 MakeGroups: forces the generation of new groups from existing ones
5994 LinearVariation: forces the computation of rotation angles as linear
5995 variation of the given Angles along path steps
5998 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5999 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6000 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6001 Example: :ref:`tui_extrusion_along_path`
6004 if not IDsOfElements:
6005 IDsOfElements = [ self.GetMesh() ]
6006 n,e,f = [],IDsOfElements,IDsOfElements
6007 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
6008 NodeStart, HasAngles, Angles,
6010 HasRefPoint, RefPoint, MakeGroups)
6011 if MakeGroups: return gr,er
6014 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
6015 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6016 MakeGroups=False, LinearVariation=False):
6018 Generate new elements by extrusion of the elements which belong to the object.
6019 The path of extrusion must be a meshed edge.
6022 theObject: the object whose elements should be processed.
6023 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6024 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6025 PathShape: shape (edge) defines the sub-mesh for the path
6026 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6027 HasAngles: not used obsolete
6028 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6029 around *basePoint*, additionally to previous steps.
6030 HasRefPoint: allows using the reference point
6031 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6032 The User can specify any point as the Reference Point.
6033 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6034 MakeGroups: forces the generation of new groups from existing ones
6035 LinearVariation: forces the computation of rotation angles as linear
6036 variation of the given Angles along path steps
6039 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6040 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6041 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6042 Example: :ref:`tui_extrusion_along_path`
6045 n,e,f = [],theObject,theObject
6046 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6047 HasAngles, Angles, LinearVariation,
6048 HasRefPoint, RefPoint, MakeGroups)
6049 if MakeGroups: return gr,er
6052 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
6053 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6054 MakeGroups=False, LinearVariation=False):
6056 Generate new elements by extrusion of mesh segments which belong to the object.
6057 The path of extrusion must be a meshed edge.
6060 theObject: the object whose 1D elements should be processed.
6061 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6062 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6063 PathShape: shape (edge) defines the sub-mesh for the path
6064 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6065 HasAngles: not used obsolete
6066 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6067 around *basePoint*, additionally to previous steps.
6068 HasRefPoint: allows using the reference point
6069 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6070 The User can specify any point as the Reference Point.
6071 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6072 MakeGroups: forces the generation of new groups from existing ones
6073 LinearVariation: forces the computation of rotation angles as linear
6074 variation of the given Angles along path steps
6077 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6078 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6079 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6080 Example: :ref:`tui_extrusion_along_path`
6083 n,e,f = [],theObject,[]
6084 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6085 HasAngles, Angles, LinearVariation,
6086 HasRefPoint, RefPoint, MakeGroups)
6087 if MakeGroups: return gr,er
6090 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6091 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6092 MakeGroups=False, LinearVariation=False):
6094 Generate new elements by extrusion of faces which belong to the object.
6095 The path of extrusion must be a meshed edge.
6098 theObject: the object whose 2D elements should be processed.
6099 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6100 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6101 PathShape: shape (edge) defines the sub-mesh for the path
6102 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6103 HasAngles: not used obsolete
6104 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6105 around *basePoint*, additionally to previous steps.
6106 HasRefPoint: allows using the reference point
6107 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6108 The User can specify any point as the Reference Point.
6109 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6110 MakeGroups: forces the generation of new groups from existing ones
6111 LinearVariation: forces the computation of rotation angles as linear
6112 variation of the given Angles along path steps
6115 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6116 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6117 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6118 Example: :ref:`tui_extrusion_along_path`
6121 n,e,f = [],[],theObject
6122 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6123 HasAngles, Angles, LinearVariation,
6124 HasRefPoint, RefPoint, MakeGroups)
6125 if MakeGroups: return gr,er
6128 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6130 Create a symmetrical copy of mesh elements
6133 IDsOfElements: list of elements ids
6134 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6135 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6136 If the *Mirror* is a geom object this parameter is unnecessary
6137 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6138 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6141 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6144 if IDsOfElements == []:
6145 IDsOfElements = self.GetElementsId()
6146 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6147 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6148 theMirrorType = Mirror._mirrorType
6150 self.mesh.SetParameters(Mirror.parameters)
6151 if Copy and MakeGroups:
6152 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6153 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6156 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6158 Create a new mesh by a symmetrical copy of mesh elements
6161 IDsOfElements: the list of elements ids
6162 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6163 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6164 If the *Mirror* is a geom object this parameter is unnecessary
6165 MakeGroups: to generate new groups from existing ones
6166 NewMeshName: a name of the new mesh to create
6169 instance of class :class:`Mesh`
6172 if IDsOfElements == []:
6173 IDsOfElements = self.GetElementsId()
6174 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6175 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6176 theMirrorType = Mirror._mirrorType
6178 self.mesh.SetParameters(Mirror.parameters)
6179 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6180 MakeGroups, NewMeshName)
6181 return Mesh(self.smeshpyD,self.geompyD,mesh)
6183 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6185 Create a symmetrical copy of the object
6188 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6189 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6190 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6191 If the *Mirror* is a geom object this parameter is unnecessary
6192 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6193 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6196 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6199 if ( isinstance( theObject, Mesh )):
6200 theObject = theObject.GetMesh()
6201 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6202 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6203 theMirrorType = Mirror._mirrorType
6205 self.mesh.SetParameters(Mirror.parameters)
6206 if Copy and MakeGroups:
6207 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6208 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6211 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6213 Create a new mesh by a symmetrical copy of the object
6216 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6217 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6218 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6219 If the *Mirror* is a geom object this parameter is unnecessary
6220 MakeGroups: forces the generation of new groups from existing ones
6221 NewMeshName: the name of the new mesh to create
6224 instance of class :class:`Mesh`
6227 if ( isinstance( theObject, Mesh )):
6228 theObject = theObject.GetMesh()
6229 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6230 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6231 theMirrorType = Mirror._mirrorType
6233 self.mesh.SetParameters(Mirror.parameters)
6234 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6235 MakeGroups, NewMeshName)
6236 return Mesh( self.smeshpyD,self.geompyD,mesh )
6238 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6240 Translate the elements
6243 IDsOfElements: list of elements ids
6244 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6245 Copy: allows copying the translated elements
6246 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6249 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6252 if IDsOfElements == []:
6253 IDsOfElements = self.GetElementsId()
6254 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6255 Vector = self.smeshpyD.GetDirStruct(Vector)
6256 if isinstance( Vector, list ):
6257 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6258 self.mesh.SetParameters(Vector.PS.parameters)
6259 if Copy and MakeGroups:
6260 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6261 self.editor.Translate(IDsOfElements, Vector, Copy)
6264 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6266 Create a new mesh of translated elements
6269 IDsOfElements: list of elements ids
6270 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6271 MakeGroups: forces the generation of new groups from existing ones
6272 NewMeshName: the name of the newly created mesh
6275 instance of class :class:`Mesh`
6278 if IDsOfElements == []:
6279 IDsOfElements = self.GetElementsId()
6280 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6281 Vector = self.smeshpyD.GetDirStruct(Vector)
6282 if isinstance( Vector, list ):
6283 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6284 self.mesh.SetParameters(Vector.PS.parameters)
6285 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6286 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6288 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6290 Translate the object
6293 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6294 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6295 Copy: allows copying the translated elements
6296 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6299 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6302 if ( isinstance( theObject, Mesh )):
6303 theObject = theObject.GetMesh()
6304 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6305 Vector = self.smeshpyD.GetDirStruct(Vector)
6306 if isinstance( Vector, list ):
6307 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6308 self.mesh.SetParameters(Vector.PS.parameters)
6309 if Copy and MakeGroups:
6310 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6311 self.editor.TranslateObject(theObject, Vector, Copy)
6314 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6316 Create a new mesh from the translated object
6319 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6320 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6321 MakeGroups: forces the generation of new groups from existing ones
6322 NewMeshName: the name of the newly created mesh
6325 instance of class :class:`Mesh`
6328 if isinstance( theObject, Mesh ):
6329 theObject = theObject.GetMesh()
6330 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6331 Vector = self.smeshpyD.GetDirStruct(Vector)
6332 if isinstance( Vector, list ):
6333 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6334 self.mesh.SetParameters(Vector.PS.parameters)
6335 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6336 return Mesh( self.smeshpyD, self.geompyD, mesh )
6340 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6345 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6346 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6347 theScaleFact: list of 1-3 scale factors for axises
6348 Copy: allows copying the translated elements
6349 MakeGroups: forces the generation of new groups from existing
6353 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6354 empty list otherwise
6356 unRegister = genObjUnRegister()
6357 if ( isinstance( theObject, Mesh )):
6358 theObject = theObject.GetMesh()
6359 if ( isinstance( theObject, list )):
6360 theObject = self.GetIDSource(theObject, SMESH.ALL)
6361 unRegister.set( theObject )
6362 if ( isinstance( thePoint, list )):
6363 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6364 if ( isinstance( theScaleFact, float )):
6365 theScaleFact = [theScaleFact]
6366 if ( isinstance( theScaleFact, int )):
6367 theScaleFact = [ float(theScaleFact)]
6369 self.mesh.SetParameters(thePoint.parameters)
6371 if Copy and MakeGroups:
6372 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6373 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6376 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6378 Create a new mesh from the translated object
6381 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6382 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6383 theScaleFact: list of 1-3 scale factors for axises
6384 MakeGroups: forces the generation of new groups from existing ones
6385 NewMeshName: the name of the newly created mesh
6388 instance of class :class:`Mesh`
6390 unRegister = genObjUnRegister()
6391 if (isinstance(theObject, Mesh)):
6392 theObject = theObject.GetMesh()
6393 if ( isinstance( theObject, list )):
6394 theObject = self.GetIDSource(theObject,SMESH.ALL)
6395 unRegister.set( theObject )
6396 if ( isinstance( thePoint, list )):
6397 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6398 if ( isinstance( theScaleFact, float )):
6399 theScaleFact = [theScaleFact]
6400 if ( isinstance( theScaleFact, int )):
6401 theScaleFact = [ float(theScaleFact)]
6403 self.mesh.SetParameters(thePoint.parameters)
6404 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6405 MakeGroups, NewMeshName)
6406 return Mesh( self.smeshpyD, self.geompyD, mesh )
6410 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6415 IDsOfElements: list of elements ids
6416 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6417 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6418 Copy: allows copying the rotated elements
6419 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6422 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6426 if IDsOfElements == []:
6427 IDsOfElements = self.GetElementsId()
6428 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6429 Axis = self.smeshpyD.GetAxisStruct(Axis)
6430 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6431 Parameters = Axis.parameters + var_separator + Parameters
6432 self.mesh.SetParameters(Parameters)
6433 if Copy and MakeGroups:
6434 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6435 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6438 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6440 Create a new mesh of rotated elements
6443 IDsOfElements: list of element ids
6444 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6445 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6446 MakeGroups: forces the generation of new groups from existing ones
6447 NewMeshName: the name of the newly created mesh
6450 instance of class :class:`Mesh`
6453 if IDsOfElements == []:
6454 IDsOfElements = self.GetElementsId()
6455 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6456 Axis = self.smeshpyD.GetAxisStruct(Axis)
6457 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6458 Parameters = Axis.parameters + var_separator + Parameters
6459 self.mesh.SetParameters(Parameters)
6460 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6461 MakeGroups, NewMeshName)
6462 return Mesh( self.smeshpyD, self.geompyD, mesh )
6464 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6469 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6470 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6471 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6472 Copy: allows copying the rotated elements
6473 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6476 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6479 if (isinstance(theObject, Mesh)):
6480 theObject = theObject.GetMesh()
6481 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6482 Axis = self.smeshpyD.GetAxisStruct(Axis)
6483 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6484 Parameters = Axis.parameters + ":" + Parameters
6485 self.mesh.SetParameters(Parameters)
6486 if Copy and MakeGroups:
6487 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6488 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6491 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6493 Create a new mesh from the rotated object
6496 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6497 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6498 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6499 MakeGroups: forces the generation of new groups from existing ones
6500 NewMeshName: the name of the newly created mesh
6503 instance of class :class:`Mesh`
6506 if (isinstance( theObject, Mesh )):
6507 theObject = theObject.GetMesh()
6508 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6509 Axis = self.smeshpyD.GetAxisStruct(Axis)
6510 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6511 Parameters = Axis.parameters + ":" + Parameters
6512 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6513 MakeGroups, NewMeshName)
6514 self.mesh.SetParameters(Parameters)
6515 return Mesh( self.smeshpyD, self.geompyD, mesh )
6517 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6519 Create an offset mesh from the given 2D object
6522 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6523 theValue (float): signed offset size
6524 MakeGroups (boolean): forces the generation of new groups from existing ones
6525 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6526 False means to remove original elements.
6527 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6530 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6533 if isinstance( theObject, Mesh ):
6534 theObject = theObject.GetMesh()
6535 theValue,Parameters,hasVars = ParseParameters(Value)
6536 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6537 self.mesh.SetParameters(Parameters)
6539 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6542 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6544 Find groups of adjacent nodes within Tolerance.
6547 Tolerance (float): the value of tolerance
6548 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6549 corner and medium nodes in separate groups thus preventing
6550 their further merge.
6553 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6556 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6558 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6559 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6561 Find groups of adjacent nodes within Tolerance.
6564 Tolerance: the value of tolerance
6565 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6566 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6567 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6568 corner and medium nodes in separate groups thus preventing
6569 their further merge.
6572 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6575 unRegister = genObjUnRegister()
6576 if not isinstance( SubMeshOrGroup, list ):
6577 SubMeshOrGroup = [ SubMeshOrGroup ]
6578 for i,obj in enumerate( SubMeshOrGroup ):
6579 if isinstance( obj, Mesh ):
6580 SubMeshOrGroup = [ obj.GetMesh() ]
6582 if isinstance( obj, int ):
6583 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6584 unRegister.set( SubMeshOrGroup )
6587 if not isinstance( exceptNodes, list ):
6588 exceptNodes = [ exceptNodes ]
6589 if exceptNodes and isinstance( exceptNodes[0], int ):
6590 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6591 unRegister.set( exceptNodes )
6593 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6594 exceptNodes, SeparateCornerAndMediumNodes)
6596 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6601 GroupsOfNodes: a list of groups of nodes IDs for merging.
6602 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6603 in all elements and mesh groups by nodes 1 and 25 correspondingly
6604 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6605 If *NodesToKeep* does not include a node to keep for some group to merge,
6606 then the first node in the group is kept.
6607 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6611 This operation can create gaps in numeration of nodes or elements.
6612 Call :meth:`RenumberElements` to remove the gaps.
6614 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6616 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6618 Find the elements built on the same nodes.
6621 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6622 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6626 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6629 unRegister = genObjUnRegister()
6630 if MeshOrSubMeshOrGroup is None:
6631 MeshOrSubMeshOrGroup = [ self.mesh ]
6632 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6633 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6634 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6635 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6636 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6637 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6638 unRegister.set( MeshOrSubMeshOrGroup )
6639 for item in MeshOrSubMeshOrGroup:
6640 if isinstance( item, Mesh ):
6641 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6643 if not isinstance( exceptElements, list ):
6644 exceptElements = [ exceptElements ]
6645 if exceptElements and isinstance( exceptElements[0], int ):
6646 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6647 unRegister.set( exceptElements )
6649 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6651 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6653 Merge elements in each given group.
6656 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6657 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6658 replaced in all mesh groups by elements 1 and 25)
6659 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6660 If *ElementsToKeep* does not include an element to keep for some group to merge,
6661 then the first element in the group is kept.
6664 This operation can create gaps in numeration of elements.
6665 Call :meth:`RenumberElements` to remove the gaps.
6668 unRegister = genObjUnRegister()
6670 if not isinstance( ElementsToKeep, list ):
6671 ElementsToKeep = [ ElementsToKeep ]
6672 if isinstance( ElementsToKeep[0], int ):
6673 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6674 unRegister.set( ElementsToKeep )
6676 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6678 def MergeEqualElements(self):
6680 Leave one element and remove all other elements built on the same nodes.
6683 This operation can create gaps in numeration of elements.
6684 Call :meth:`RenumberElements` to remove the gaps.
6687 self.editor.MergeEqualElements()
6689 def FindFreeBorders(self, ClosedOnly=True):
6691 Returns all or only closed free borders
6694 list of SMESH.FreeBorder's
6697 return self.editor.FindFreeBorders( ClosedOnly )
6699 def FillHole(self, holeNodes, groupName=""):
6701 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6704 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6705 must describe all sequential nodes of the hole border. The first and the last
6706 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6707 groupName (string): name of a group to add new faces
6709 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6713 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6714 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6715 if not isinstance( holeNodes, SMESH.FreeBorder ):
6716 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6717 return self.editor.FillHole( holeNodes, groupName )
6719 def FindCoincidentFreeBorders (self, tolerance=0.):
6721 Return groups of FreeBorder's coincident within the given tolerance.
6724 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6725 size of elements adjacent to free borders being compared is used.
6728 SMESH.CoincidentFreeBorders structure
6731 return self.editor.FindCoincidentFreeBorders( tolerance )
6733 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6735 Sew FreeBorder's of each group
6738 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6739 where each enclosed list contains node IDs of a group of coincident free
6740 borders such that each consequent triple of IDs within a group describes
6741 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6742 last node of a border.
6743 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6744 groups of coincident free borders, each group including two borders.
6745 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6746 polygons if a node of opposite border falls on a face edge, else such
6747 faces are split into several ones.
6748 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6749 polyhedra if a node of opposite border falls on a volume edge, else such
6750 volumes, if any, remain intact and the mesh becomes non-conformal.
6753 a number of successfully sewed groups
6756 This operation can create gaps in numeration of nodes or elements.
6757 Call :meth:`RenumberElements` to remove the gaps.
6760 if freeBorders and isinstance( freeBorders, list ):
6761 # construct SMESH.CoincidentFreeBorders
6762 if isinstance( freeBorders[0], int ):
6763 freeBorders = [freeBorders]
6765 coincidentGroups = []
6766 for nodeList in freeBorders:
6767 if not nodeList or len( nodeList ) % 3:
6768 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6771 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6772 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6773 nodeList = nodeList[3:]
6775 coincidentGroups.append( group )
6777 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6779 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6781 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6782 FirstNodeID2, SecondNodeID2, LastNodeID2,
6783 CreatePolygons, CreatePolyedrs):
6788 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6791 This operation can create gaps in numeration of nodes or elements.
6792 Call :meth:`RenumberElements` to remove the gaps.
6795 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6796 FirstNodeID2, SecondNodeID2, LastNodeID2,
6797 CreatePolygons, CreatePolyedrs)
6799 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6800 FirstNodeID2, SecondNodeID2):
6802 Sew conform free borders
6805 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6808 This operation can create gaps in numeration of elements.
6809 Call :meth:`RenumberElements` to remove the gaps.
6812 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6813 FirstNodeID2, SecondNodeID2)
6815 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6816 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6821 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6824 This operation can create gaps in numeration of elements.
6825 Call :meth:`RenumberElements` to remove the gaps.
6828 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6829 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6831 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6832 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6833 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6835 Sew two sides of a mesh. The nodes belonging to Side1 are
6836 merged with the nodes of elements of Side2.
6837 The number of elements in theSide1 and in theSide2 must be
6838 equal and they should have similar nodal connectivity.
6839 The nodes to merge should belong to side borders and
6840 the first node should be linked to the second.
6843 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6846 This operation can create gaps in numeration of nodes.
6847 Call :meth:`RenumberElements` to remove the gaps.
6850 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6851 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6852 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6854 def ChangeElemNodes(self, ide, newIDs):
6856 Set new nodes for the given element. Number of nodes should be kept.
6863 False if the number of nodes does not correspond to the type of element
6866 return self.editor.ChangeElemNodes(ide, newIDs)
6868 def GetLastCreatedNodes(self):
6870 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6871 created, this method return the list of their IDs.
6872 If new nodes were not created - return empty list
6875 the list of integer values (can be empty)
6878 return self.editor.GetLastCreatedNodes()
6880 def GetLastCreatedElems(self):
6882 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6883 created this method return the list of their IDs.
6884 If new elements were not created - return empty list
6887 the list of integer values (can be empty)
6890 return self.editor.GetLastCreatedElems()
6892 def ClearLastCreated(self):
6894 Forget what nodes and elements were created by the last mesh edition operation
6897 self.editor.ClearLastCreated()
6899 def DoubleElements(self, theElements, theGroupName=""):
6901 Create duplicates of given elements, i.e. create new elements based on the
6902 same nodes as the given ones.
6905 theElements: container of elements to duplicate. It can be a
6906 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6907 or a list of element IDs. If *theElements* is
6908 a :class:`Mesh`, elements of highest dimension are duplicated
6909 theGroupName: a name of group to contain the generated elements.
6910 If a group with such a name already exists, the new elements
6911 are added to the existing group, else a new group is created.
6912 If *theGroupName* is empty, new elements are not added
6916 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6917 None if *theGroupName* == "".
6920 unRegister = genObjUnRegister()
6921 if isinstance( theElements, Mesh ):
6922 theElements = theElements.mesh
6923 elif isinstance( theElements, list ):
6924 theElements = self.GetIDSource( theElements, SMESH.ALL )
6925 unRegister.set( theElements )
6926 return self.editor.DoubleElements(theElements, theGroupName)
6928 def DoubleNodes(self, theNodes, theModifiedElems):
6930 Create a hole in a mesh by doubling the nodes of some particular elements
6933 theNodes: IDs of nodes to be doubled
6934 theModifiedElems: IDs of elements to be updated by the new (doubled)
6935 nodes. If list of element identifiers is empty then nodes are doubled but
6936 they not assigned to elements
6939 True if operation has been completed successfully, False otherwise
6942 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6944 def DoubleNode(self, theNodeId, theModifiedElems):
6946 Create a hole in a mesh by doubling the nodes of some particular elements.
6947 This method provided for convenience works as :meth:`DoubleNodes`.
6950 theNodeId: IDs of node to double
6951 theModifiedElems: IDs of elements to update
6954 True if operation has been completed successfully, False otherwise
6957 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6959 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6961 Create a hole in a mesh by doubling the nodes of some particular elements.
6962 This method provided for convenience works as :meth:`DoubleNodes`.
6965 theNodes: group of nodes to double.
6966 theModifiedElems: group of elements to update.
6967 theMakeGroup: forces the generation of a group containing new nodes.
6970 True or a created group if operation has been completed successfully,
6971 False or None otherwise
6975 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6976 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6978 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6980 Create a hole in a mesh by doubling the nodes of some particular elements.
6981 This method provided for convenience works as :meth:`DoubleNodes`.
6984 theNodes: list of groups of nodes to double.
6985 theModifiedElems: list of groups of elements to update.
6986 theMakeGroup: forces the generation of a group containing new nodes.
6989 True if operation has been completed successfully, False otherwise
6993 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6994 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6996 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6998 Create a hole in a mesh by doubling the nodes of some particular elements
7001 theElems: the list of elements (edges or faces) to replicate.
7002 The nodes for duplication could be found from these elements
7003 theNodesNot: list of nodes NOT to replicate
7004 theAffectedElems: the list of elements (cells and edges) to which the
7005 replicated nodes should be associated to
7008 True if operation has been completed successfully, False otherwise
7011 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
7013 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
7015 Create a hole in a mesh by doubling the nodes of some particular elements
7018 theElems: the list of elements (edges or faces) to replicate.
7019 The nodes for duplication could be found from these elements
7020 theNodesNot: list of nodes NOT to replicate
7021 theShape: shape to detect affected elements (element which geometric center
7022 located on or inside shape).
7023 The replicated nodes should be associated to affected elements.
7026 True if operation has been completed successfully, False otherwise
7029 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
7031 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
7032 theMakeGroup=False, theMakeNodeGroup=False):
7034 Create a hole in a mesh by doubling the nodes of some particular elements.
7035 This method provided for convenience works as :meth:`DoubleNodes`.
7038 theElems: group of of elements (edges or faces) to replicate.
7039 theNodesNot: group of nodes NOT to replicate.
7040 theAffectedElems: group of elements to which the replicated nodes
7041 should be associated to.
7042 theMakeGroup: forces the generation of a group containing new elements.
7043 theMakeNodeGroup: forces the generation of a group containing new nodes.
7046 True or created groups (one or two) if operation has been completed successfully,
7047 False or None otherwise
7050 if theMakeGroup or theMakeNodeGroup:
7051 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
7053 theMakeGroup, theMakeNodeGroup)
7054 if theMakeGroup and theMakeNodeGroup:
7057 return twoGroups[ int(theMakeNodeGroup) ]
7058 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7060 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7062 Create a hole in a mesh by doubling the nodes of some particular elements.
7063 This method provided for convenience works as :meth:`DoubleNodes`.
7066 theElems: group of of elements (edges or faces) to replicate
7067 theNodesNot: group of nodes not to replicate
7068 theShape: shape to detect affected elements (element which geometric center
7069 located on or inside shape).
7070 The replicated nodes should be associated to affected elements
7073 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7075 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7076 theMakeGroup=False, theMakeNodeGroup=False):
7078 Create a hole in a mesh by doubling the nodes of some particular elements.
7079 This method provided for convenience works as :meth:`DoubleNodes`.
7082 theElems: list of groups of elements (edges or faces) to replicate
7083 theNodesNot: list of groups of nodes NOT to replicate
7084 theAffectedElems: group of elements to which the replicated nodes
7085 should be associated to
7086 theMakeGroup: forces generation of a group containing new elements.
7087 theMakeNodeGroup: forces generation of a group containing new nodes
7090 True or created groups (one or two) if operation has been completed successfully,
7091 False or None otherwise
7094 if theMakeGroup or theMakeNodeGroup:
7095 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7097 theMakeGroup, theMakeNodeGroup)
7098 if theMakeGroup and theMakeNodeGroup:
7101 return twoGroups[ int(theMakeNodeGroup) ]
7102 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7104 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7106 Create a hole in a mesh by doubling the nodes of some particular elements.
7107 This method provided for convenience works as :meth:`DoubleNodes`.
7110 theElems: list of groups of elements (edges or faces) to replicate
7111 theNodesNot: list of groups of nodes NOT to replicate
7112 theShape: shape to detect affected elements (element which geometric center
7113 located on or inside shape).
7114 The replicated nodes should be associated to affected elements
7117 True if operation has been completed successfully, False otherwise
7120 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7122 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7124 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7125 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7128 theElems: list of groups of nodes or elements (edges or faces) to replicate
7129 theNodesNot: list of groups of nodes NOT to replicate
7130 theShape: shape to detect affected elements (element which geometric center
7131 located on or inside shape).
7132 The replicated nodes should be associated to affected elements
7135 groups of affected elements in order: volumes, faces, edges
7138 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7140 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7143 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7144 The list of groups must describe a partition of the mesh volumes.
7145 The nodes of the internal faces at the boundaries of the groups are doubled.
7146 In option, the internal faces are replaced by flat elements.
7147 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7150 theDomains: list of groups of volumes
7151 createJointElems: if True, create the elements
7152 onAllBoundaries: if True, the nodes and elements are also created on
7153 the boundary between *theDomains* and the rest mesh
7156 True if operation has been completed successfully, False otherwise
7159 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7161 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7163 Double nodes on some external faces and create flat elements.
7164 Flat elements are mainly used by some types of mechanic calculations.
7166 Each group of the list must be constituted of faces.
7167 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7170 theGroupsOfFaces: list of groups of faces
7173 True if operation has been completed successfully, False otherwise
7176 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7178 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7180 Identify all the elements around a geom shape, get the faces delimiting the hole
7182 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7184 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7186 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7187 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7188 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7189 If there are several paths connecting a pair of points, the shortest path is
7190 selected by the module. Position of the cutting plane is defined by the two
7191 points and an optional vector lying on the plane specified by a PolySegment.
7192 By default the vector is defined by Mesh module as following. A middle point
7193 of the two given points is computed. The middle point is projected to the mesh.
7194 The vector goes from the middle point to the projection point. In case of planar
7195 mesh, the vector is normal to the mesh.
7197 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7200 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7201 groupName: optional name of a group where created mesh segments will be added.
7204 editor = self.editor
7206 editor = self.mesh.GetMeshEditPreviewer()
7207 segmentsRes = editor.MakePolyLine( segments, groupName )
7208 for i, seg in enumerate( segmentsRes ):
7209 segments[i].vector = seg.vector
7211 return editor.GetPreviewData()
7214 def MakeSlot(self, segmentGroup, width ):
7216 Create a slot of given width around given 1D elements lying on a triangle mesh.
7217 The slot is constructed by cutting faces by cylindrical surfaces made
7218 around each segment. Segments are expected to be created by MakePolyLine().
7221 FaceEdge's located at the slot boundary
7223 return self.editor.MakeSlot( segmentGroup, width )
7225 def GetFunctor(self, funcType ):
7227 Return a cached numerical functor by its type.
7230 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7231 Note that not all items correspond to numerical functors.
7234 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7237 fn = self.functors[ funcType._v ]
7239 fn = self.smeshpyD.GetFunctor(funcType)
7240 fn.SetMesh(self.mesh)
7241 self.functors[ funcType._v ] = fn
7244 def FunctorValue(self, funcType, elemId, isElem=True):
7246 Return value of a functor for a given element
7249 funcType: an item of :class:`SMESH.FunctorType` enum.
7250 elemId: element or node ID
7251 isElem: *elemId* is ID of element or node
7254 the functor value or zero in case of invalid arguments
7257 fn = self.GetFunctor( funcType )
7258 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7259 val = fn.GetValue(elemId)
7264 def GetLength(self, elemId=None):
7266 Get length of given 1D elements or of all 1D mesh elements
7269 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.
7272 Sum of lengths of given elements
7277 length = self.smeshpyD.GetLength(self)
7278 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7279 length = self.smeshpyD.GetLength(elemId)
7282 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7284 length += self.smeshpyD.GetLength(obj)
7285 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7286 unRegister = genObjUnRegister()
7287 obj = self.GetIDSource( elemId )
7288 unRegister.set( obj )
7289 length = self.smeshpyD.GetLength( obj )
7291 length = self.FunctorValue(SMESH.FT_Length, elemId)
7294 def GetArea(self, elemId=None):
7296 Get area of given 2D elements or of all 2D mesh elements
7299 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.
7302 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7307 area = self.smeshpyD.GetArea(self)
7308 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7309 area = self.smeshpyD.GetArea(elemId)
7312 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7314 area += self.smeshpyD.GetArea(obj)
7315 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7316 unRegister = genObjUnRegister()
7317 obj = self.GetIDSource( elemId )
7318 unRegister.set( obj )
7319 area = self.smeshpyD.GetArea( obj )
7321 area = self.FunctorValue(SMESH.FT_Area, elemId)
7324 def GetVolume(self, elemId=None):
7326 Get volume of given 3D elements or of all 3D mesh elements
7329 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.
7332 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7337 volume= self.smeshpyD.GetVolume(self)
7338 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7339 volume= self.smeshpyD.GetVolume(elemId)
7342 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7344 volume+= self.smeshpyD.GetVolume(obj)
7345 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7346 unRegister = genObjUnRegister()
7347 obj = self.GetIDSource( elemId )
7348 unRegister.set( obj )
7349 volume= self.smeshpyD.GetVolume( obj )
7351 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7354 def GetAngle(self, node1, node2, node3 ):
7356 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7359 node1,node2,node3: IDs of the three nodes
7362 Angle in radians [0,PI]. -1 if failure case.
7364 p1 = self.GetNodeXYZ( node1 )
7365 p2 = self.GetNodeXYZ( node2 )
7366 p3 = self.GetNodeXYZ( node3 )
7367 if p1 and p2 and p3:
7368 return self.smeshpyD.GetAngle( p1,p2,p3 )
7372 def GetMaxElementLength(self, elemId):
7374 Get maximum element length.
7377 elemId: mesh element ID
7380 element's maximum length value
7383 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7384 ftype = SMESH.FT_MaxElementLength3D
7386 ftype = SMESH.FT_MaxElementLength2D
7387 return self.FunctorValue(ftype, elemId)
7389 def GetAspectRatio(self, elemId):
7391 Get aspect ratio of 2D or 3D element.
7394 elemId: mesh element ID
7397 element's aspect ratio value
7400 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7401 ftype = SMESH.FT_AspectRatio3D
7403 ftype = SMESH.FT_AspectRatio
7404 return self.FunctorValue(ftype, elemId)
7406 def GetWarping(self, elemId):
7408 Get warping angle of 2D element.
7411 elemId: mesh element ID
7414 element's warping angle value
7417 return self.FunctorValue(SMESH.FT_Warping, elemId)
7419 def GetMinimumAngle(self, elemId):
7421 Get minimum angle of 2D element.
7424 elemId: mesh element ID
7427 element's minimum angle value
7430 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7432 def GetTaper(self, elemId):
7434 Get taper of 2D element.
7437 elemId: mesh element ID
7440 element's taper value
7443 return self.FunctorValue(SMESH.FT_Taper, elemId)
7445 def GetSkew(self, elemId):
7447 Get skew of 2D element.
7450 elemId: mesh element ID
7453 element's skew value
7456 return self.FunctorValue(SMESH.FT_Skew, elemId)
7458 def GetMinMax(self, funType, meshPart=None):
7460 Return minimal and maximal value of a given functor.
7463 funType (SMESH.FunctorType): a functor type.
7464 Note that not all items of :class:`SMESH.FunctorType` corresponds
7465 to numerical functors.
7466 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7472 unRegister = genObjUnRegister()
7473 if isinstance( meshPart, list ):
7474 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7475 unRegister.set( meshPart )
7476 if isinstance( meshPart, Mesh ):
7477 meshPart = meshPart.mesh
7478 fun = self.GetFunctor( funType )
7481 if hasattr( meshPart, "SetMesh" ):
7482 meshPart.SetMesh( self.mesh ) # set mesh to filter
7483 hist = fun.GetLocalHistogram( 1, False, meshPart )
7485 hist = fun.GetHistogram( 1, False )
7487 return hist[0].min, hist[0].max
7490 pass # end of Mesh class
7493 class meshProxy(SMESH._objref_SMESH_Mesh):
7495 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7496 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7498 def __init__(self,*args):
7499 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7500 def __deepcopy__(self, memo=None):
7501 new = self.__class__(self)
7503 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7504 if len( args ) == 3:
7505 args += SMESH.ALL_NODES, True
7506 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7507 def ExportToMEDX(self, *args): # function removed
7508 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7509 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7510 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7511 def ExportToMED(self, *args): # function removed
7512 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7513 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7515 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7517 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7518 def ExportPartToMED(self, *args): # 'version' parameter removed
7519 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7520 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7521 def ExportMED(self, *args): # signature of method changed
7522 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7524 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7526 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7527 def ExportUNV(self, *args): # renumber arg added
7528 if len( args ) == 1:
7530 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
7531 def ExportDAT(self, *args): # renumber arg added
7532 if len( args ) == 1:
7534 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
7536 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7539 class submeshProxy(SMESH._objref_SMESH_subMesh):
7542 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7544 def __init__(self,*args):
7545 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7547 def __deepcopy__(self, memo=None):
7548 new = self.__class__(self)
7551 def Compute(self,refresh=False):
7553 Compute the sub-mesh and return the status of the computation
7556 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7561 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7562 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7566 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7568 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7570 if salome.sg.hasDesktop():
7571 if refresh: salome.sg.updateObjBrowser()
7576 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7579 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7581 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7582 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7585 def __init__(self,*args):
7586 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7588 def __getattr__(self, name ): # method called if an attribute not found
7589 if not self.mesh: # look for name() method in Mesh class
7590 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7591 if hasattr( self.mesh, name ):
7592 return getattr( self.mesh, name )
7593 if name == "ExtrusionAlongPathObjX":
7594 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7595 print("meshEditor: attribute '%s' NOT FOUND" % name)
7597 def __deepcopy__(self, memo=None):
7598 new = self.__class__(self)
7600 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7601 if len( args ) == 1: args += False,
7602 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7603 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7604 if len( args ) == 2: args += False,
7605 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7606 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7607 if len( args ) == 1:
7608 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7609 NodesToKeep = args[1]
7610 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7611 unRegister = genObjUnRegister()
7613 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7614 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7615 if not isinstance( NodesToKeep, list ):
7616 NodesToKeep = [ NodesToKeep ]
7617 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7619 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7621 class Pattern(SMESH._objref_SMESH_Pattern):
7623 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7624 variables in some methods
7627 def LoadFromFile(self, patternTextOrFile ):
7628 text = patternTextOrFile
7629 if os.path.exists( text ):
7630 text = open( patternTextOrFile ).read()
7632 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7634 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7635 decrFun = lambda i: i-1
7636 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7637 theMesh.SetParameters(Parameters)
7638 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7640 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7641 decrFun = lambda i: i-1
7642 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7643 theMesh.SetParameters(Parameters)
7644 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7646 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7647 if isinstance( mesh, Mesh ):
7648 mesh = mesh.GetMesh()
7649 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7651 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7653 Registering the new proxy for Pattern
7658 Private class used to bind methods creating algorithms to the class Mesh
7661 def __init__(self, method):
7663 self.defaultAlgoType = ""
7664 self.algoTypeToClass = {}
7665 self.method = method
7667 def add(self, algoClass):
7669 Store a python class of algorithm
7671 if inspect.isclass(algoClass) and \
7672 hasattr( algoClass, "algoType"):
7673 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7674 if not self.defaultAlgoType and \
7675 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7676 self.defaultAlgoType = algoClass.algoType
7677 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7679 def copy(self, mesh):
7681 Create a copy of self and assign mesh to the copy
7684 other = algoCreator( self.method )
7685 other.defaultAlgoType = self.defaultAlgoType
7686 other.algoTypeToClass = self.algoTypeToClass
7690 def __call__(self,algo="",geom=0,*args):
7692 Create an instance of algorithm
7696 if isinstance( algo, str ):
7698 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7699 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7704 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7706 elif not algoType and isinstance( geom, str ):
7711 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7713 elif isinstance( arg, str ) and not algoType:
7716 import traceback, sys
7717 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7718 sys.stderr.write( msg + '\n' )
7719 tb = traceback.extract_stack(None,2)
7720 traceback.print_list( [tb[0]] )
7722 algoType = self.defaultAlgoType
7723 if not algoType and self.algoTypeToClass:
7724 algoType = sorted( self.algoTypeToClass.keys() )[0]
7725 if algoType in self.algoTypeToClass:
7726 #print("Create algo",algoType)
7727 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7728 raise RuntimeError( "No class found for algo type %s" % algoType)
7731 class hypMethodWrapper:
7733 Private class used to substitute and store variable parameters of hypotheses.
7736 def __init__(self, hyp, method):
7738 self.method = method
7739 #print("REBIND:", method.__name__)
7742 def __call__(self,*args):
7744 call a method of hypothesis with calling SetVarParameter() before
7748 return self.method( self.hyp, *args ) # hypothesis method with no args
7750 #print("MethWrapper.__call__", self.method.__name__, args)
7752 parsed = ParseParameters(*args) # replace variables with their values
7753 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7754 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7755 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7756 # maybe there is a replaced string arg which is not variable
7757 result = self.method( self.hyp, *args )
7758 except ValueError as detail: # raised by ParseParameters()
7760 result = self.method( self.hyp, *args )
7761 except omniORB.CORBA.BAD_PARAM:
7762 raise ValueError(detail) # wrong variable name
7767 class genObjUnRegister:
7769 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7772 def __init__(self, genObj=None):
7773 self.genObjList = []
7777 def set(self, genObj):
7778 "Store one or a list of of SALOME.GenericObj'es"
7779 if isinstance( genObj, list ):
7780 self.genObjList.extend( genObj )
7782 self.genObjList.append( genObj )
7786 for genObj in self.genObjList:
7787 if genObj and hasattr( genObj, "UnRegister" ):
7790 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7792 Bind methods creating mesher plug-ins to the Mesh class
7795 # print("pluginName: ", pluginName)
7796 pluginBuilderName = pluginName + "Builder"
7798 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7799 except Exception as e:
7800 from salome_utils import verbose
7801 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7803 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7804 plugin = eval( pluginBuilderName )
7805 # print(" plugin:" , str(plugin))
7807 # add methods creating algorithms to Mesh
7808 for k in dir( plugin ):
7809 if k[0] == '_': continue
7810 algo = getattr( plugin, k )
7811 #print(" algo:", str(algo))
7812 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7813 #print(" meshMethod:" , str(algo.meshMethod))
7814 if not hasattr( Mesh, algo.meshMethod ):
7815 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7817 _mmethod = getattr( Mesh, algo.meshMethod )
7818 if hasattr( _mmethod, "add" ):