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):
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)
1882 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1883 geom = self.mesh.GetShapeToMesh()
1886 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1888 ok = self.smeshpyD.Compute(self.mesh, geom)
1889 except SALOME.SALOME_Exception as ex:
1890 print("Mesh computation failed, exception caught:")
1891 print(" ", ex.details.text)
1894 print("Mesh computation failed, exception caught:")
1895 traceback.print_exc()
1899 # Treat compute errors
1900 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1902 for err in computeErrors:
1903 if self.mesh.HasShapeToMesh():
1904 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1906 stdErrors = ["OK", #COMPERR_OK
1907 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1908 "std::exception", #COMPERR_STD_EXCEPTION
1909 "OCC exception", #COMPERR_OCC_EXCEPTION
1910 "..", #COMPERR_SLM_EXCEPTION
1911 "Unknown exception", #COMPERR_EXCEPTION
1912 "Memory allocation problem", #COMPERR_MEMORY_PB
1913 "Algorithm failed", #COMPERR_ALGO_FAILED
1914 "Unexpected geometry", #COMPERR_BAD_SHAPE
1915 "Warning", #COMPERR_WARNING
1916 "Computation cancelled",#COMPERR_CANCELED
1917 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1919 if err.code < len(stdErrors): errText = stdErrors[err.code]
1921 errText = "code %s" % -err.code
1922 if errText: errText += ". "
1923 errText += err.comment
1924 if allReasons: allReasons += "\n"
1926 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1928 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1932 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1934 if err.isGlobalAlgo:
1942 reason = '%s %sD algorithm is missing' % (glob, dim)
1943 elif err.state == HYP_MISSING:
1944 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1945 % (glob, dim, name, dim))
1946 elif err.state == HYP_NOTCONFORM:
1947 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1948 elif err.state == HYP_BAD_PARAMETER:
1949 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1950 % ( glob, dim, name ))
1951 elif err.state == HYP_BAD_GEOMETRY:
1952 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1953 'geometry' % ( glob, dim, name ))
1954 elif err.state == HYP_HIDDEN_ALGO:
1955 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1956 'algorithm of upper dimension generating %sD mesh'
1957 % ( glob, dim, name, glob, dim ))
1959 reason = ("For unknown reason. "
1960 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1962 if allReasons: allReasons += "\n"
1963 allReasons += "- " + reason
1965 if not ok or allReasons != "":
1966 msg = '"' + GetName(self.mesh) + '"'
1967 if ok: msg += " has been computed with warnings"
1968 else: msg += " has not been computed"
1969 if allReasons != "": msg += ":"
1975 if salome.sg.hasDesktop():
1976 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1977 if refresh: salome.sg.updateObjBrowser()
1981 def GetComputeErrors(self, shape=0 ):
1983 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1987 shape = self.mesh.GetShapeToMesh()
1988 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1990 def GetSubShapeName(self, subShapeID ):
1992 Return a name of a sub-shape by its ID.
1993 Possible variants (for *subShapeID* == 3):
1995 - **"Face_12"** - published sub-shape
1996 - **FACE #3** - not published sub-shape
1997 - **sub-shape #3** - invalid sub-shape ID
1998 - **#3** - error in this function
2001 subShapeID: a unique ID of a sub-shape
2004 a string describing the sub-shape
2008 if not self.mesh.HasShapeToMesh():
2012 mainIOR = salome.orb.object_to_string( self.GetShape() )
2014 mainSO = s.FindObjectIOR(mainIOR)
2017 shapeText = '"%s"' % mainSO.GetName()
2018 subIt = s.NewChildIterator(mainSO)
2020 subSO = subIt.Value()
2022 obj = subSO.GetObject()
2023 if not obj: continue
2024 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2027 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2030 if ids == subShapeID:
2031 shapeText = '"%s"' % subSO.GetName()
2034 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2036 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2038 shapeText = 'sub-shape #%s' % (subShapeID)
2040 shapeText = "#%s" % (subShapeID)
2043 def GetFailedShapes(self, publish=False):
2045 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2046 error of an algorithm
2049 publish: if *True*, the returned groups will be published in the study
2052 a list of GEOM groups each named after a failed algorithm
2057 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2058 for err in computeErrors:
2059 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2060 if not shape: continue
2061 if err.algoName in algo2shapes:
2062 algo2shapes[ err.algoName ].append( shape )
2064 algo2shapes[ err.algoName ] = [ shape ]
2068 for algoName, shapes in list(algo2shapes.items()):
2070 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2071 otherTypeShapes = []
2073 group = self.geompyD.CreateGroup( self.geom, groupType )
2074 for shape in shapes:
2075 if shape.GetShapeType() == shapes[0].GetShapeType():
2076 sameTypeShapes.append( shape )
2078 otherTypeShapes.append( shape )
2079 self.geompyD.UnionList( group, sameTypeShapes )
2081 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2083 group.SetName( algoName )
2084 groups.append( group )
2085 shapes = otherTypeShapes
2088 for group in groups:
2089 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2092 def GetMeshOrder(self):
2094 Return sub-mesh objects list in meshing order
2097 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2100 return self.mesh.GetMeshOrder()
2102 def SetMeshOrder(self, submeshes):
2104 Set priority of sub-meshes. It works in two ways:
2106 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2107 *several dimensions*, it sets the order in which the sub-meshes are computed.
2108 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2109 when looking for meshing parameters to apply to a sub-shape. To impose the
2110 order in which sub-meshes with uni-dimensional algorithms are computed,
2111 call **submesh.Compute()** in a desired order.
2114 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2116 Warning: the method is for setting the order for all sub-meshes at once:
2117 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2120 return self.mesh.SetMeshOrder(submeshes)
2122 def Clear(self, refresh=False):
2124 Remove all nodes and elements generated on geometry. Imported elements remain.
2127 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2131 if ( salome.sg.hasDesktop() ):
2132 if refresh: salome.sg.updateObjBrowser()
2134 def ClearSubMesh(self, geomId, refresh=False):
2136 Remove all nodes and elements of indicated shape
2139 geomId: the ID of a sub-shape to remove elements on
2140 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2143 self.mesh.ClearSubMesh(geomId)
2144 if salome.sg.hasDesktop():
2145 if refresh: salome.sg.updateObjBrowser()
2147 def AutomaticTetrahedralization(self, fineness=0):
2149 Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron
2152 fineness: [0.0,1.0] defines mesh fineness
2158 dim = self.MeshDimension()
2160 self.RemoveGlobalHypotheses()
2161 self.Segment().AutomaticLength(fineness)
2163 self.Triangle().LengthFromEdges()
2168 return self.Compute()
2170 def AutomaticHexahedralization(self, fineness=0):
2172 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2175 fineness: [0.0, 1.0] defines mesh fineness
2181 dim = self.MeshDimension()
2182 # assign the hypotheses
2183 self.RemoveGlobalHypotheses()
2184 self.Segment().AutomaticLength(fineness)
2191 return self.Compute()
2193 def AddHypothesis(self, hyp, geom=0):
2198 hyp: a hypothesis to assign
2199 geom: a subhape of mesh geometry
2202 :class:`SMESH.Hypothesis_Status`
2205 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2206 hyp, geom = geom, hyp
2207 if isinstance( hyp, Mesh_Algorithm ):
2208 hyp = hyp.GetAlgorithm()
2213 geom = self.mesh.GetShapeToMesh()
2216 if self.mesh.HasShapeToMesh():
2217 hyp_type = hyp.GetName()
2218 lib_name = hyp.GetLibName()
2219 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2220 # if checkAll and geom:
2221 # checkAll = geom.GetType() == 37
2223 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2225 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2226 status = self.mesh.AddHypothesis(geom, hyp)
2228 status = HYP_BAD_GEOMETRY, ""
2229 hyp_name = GetName( hyp )
2232 geom_name = geom.GetName()
2233 isAlgo = hyp._narrow( SMESH_Algo )
2234 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2237 def IsUsedHypothesis(self, hyp, geom):
2239 Return True if an algorithm or hypothesis is assigned to a given shape
2242 hyp: an algorithm or hypothesis to check
2243 geom: a subhape of mesh geometry
2249 if not hyp: # or not geom
2251 if isinstance( hyp, Mesh_Algorithm ):
2252 hyp = hyp.GetAlgorithm()
2254 hyps = self.GetHypothesisList(geom)
2256 if h.GetId() == hyp.GetId():
2260 def RemoveHypothesis(self, hyp, geom=0):
2262 Unassign a hypothesis
2265 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2266 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2269 :class:`SMESH.Hypothesis_Status`
2274 if isinstance( hyp, Mesh_Algorithm ):
2275 hyp = hyp.GetAlgorithm()
2281 if self.IsUsedHypothesis( hyp, shape ):
2282 return self.mesh.RemoveHypothesis( shape, hyp )
2283 hypName = GetName( hyp )
2284 geoName = GetName( shape )
2285 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2288 def GetHypothesisList(self, geom):
2290 Get the list of hypotheses added on a geometry
2293 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2296 the sequence of :class:`SMESH.SMESH_Hypothesis`
2299 return self.mesh.GetHypothesisList( geom )
2301 def RemoveGlobalHypotheses(self):
2303 Remove all global hypotheses
2306 current_hyps = self.mesh.GetHypothesisList( self.geom )
2307 for hyp in current_hyps:
2308 self.mesh.RemoveHypothesis( self.geom, hyp )
2312 def ExportMEDCoupling(self, *args, **kwargs):
2314 Export the mesh in a memory representation.
2317 auto_groups (boolean): parameter for creating/not creating
2318 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2319 the typical use is auto_groups=False.
2320 overwrite (boolean): parameter for overwriting/not overwriting the file
2321 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2322 to export instead of the mesh
2323 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2325 - 1D if all mesh nodes lie on OX coordinate axis, or
2326 - 2D if all mesh nodes lie on XOY coordinate plane, or
2327 - 3D in the rest cases.
2329 If *autoDimension* is *False*, the space dimension is always 3.
2330 fields: list of GEOM fields defined on the shape to mesh.
2331 geomAssocFields: each character of this string means a need to export a
2332 corresponding field; correspondence between fields and characters
2335 - 'v' stands for "_vertices_" field;
2336 - 'e' stands for "_edges_" field;
2337 - 'f' stands for "_faces_" field;
2338 - 's' stands for "_solids_" field.
2340 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2341 close to zero within a given tolerance, the coordinate is set to zero.
2342 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2343 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2345 auto_groups = args[0] if len(args) > 0 else False
2346 meshPart = args[1] if len(args) > 1 else None
2347 autoDimension = args[2] if len(args) > 2 else True
2348 fields = args[3] if len(args) > 3 else []
2349 geomAssocFields = args[4] if len(args) > 4 else ''
2350 z_tolerance = args[5] if len(args) > 5 else -1.
2351 saveNumbers = args[6] if len(args) > 6 else True
2352 # process keywords arguments
2353 auto_groups = kwargs.get("auto_groups", auto_groups)
2354 meshPart = kwargs.get("meshPart", meshPart)
2355 autoDimension = kwargs.get("autoDimension", autoDimension)
2356 fields = kwargs.get("fields", fields)
2357 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2358 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2359 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2361 # invoke engine's function
2362 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2363 unRegister = genObjUnRegister()
2364 if isinstance( meshPart, list ):
2365 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2366 unRegister.set( meshPart )
2368 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2369 self.mesh.SetParameters(Parameters)
2371 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2372 fields, geomAssocFields, z_tolerance,
2375 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2376 return medcoupling.MEDFileData.New(dab)
2378 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2380 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2381 return medcoupling.MEDFileMesh.New(dab)
2383 def ExportMED(self, *args, **kwargs):
2385 Export the mesh in a file in MED format
2386 allowing to overwrite the file if it exists or add the exported data to its contents
2389 fileName: is the file name
2390 auto_groups (boolean): parameter for creating/not creating
2391 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2392 the typical use is auto_groups=False.
2393 version (int): define the version (xy, where version is x.y.z) of MED file format.
2394 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2395 The rules of compatibility to write a mesh in an older version than
2396 the current version depend on the current version. For instance,
2397 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2398 or 3.2.1 or 3.3.1 formats.
2399 If the version is equal to -1, the version is not changed (default).
2400 overwrite (boolean): parameter for overwriting/not overwriting the file
2401 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2402 to export instead of the mesh
2403 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2405 - 1D if all mesh nodes lie on OX coordinate axis, or
2406 - 2D if all mesh nodes lie on XOY coordinate plane, or
2407 - 3D in the rest cases.
2409 If *autoDimension* is *False*, the space dimension is always 3.
2410 fields: list of GEOM fields defined on the shape to mesh.
2411 geomAssocFields: each character of this string means a need to export a
2412 corresponding field; correspondence between fields and characters
2415 - 'v' stands for "_vertices_" field;
2416 - 'e' stands for "_edges_" field;
2417 - 'f' stands for "_faces_" field;
2418 - 's' stands for "_solids_" field.
2420 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2421 close to zero within a given tolerance, the coordinate is set to zero.
2422 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2423 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2425 # process positional arguments
2426 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2428 auto_groups = args[1] if len(args) > 1 else False
2429 version = args[2] if len(args) > 2 else -1
2430 overwrite = args[3] if len(args) > 3 else True
2431 meshPart = args[4] if len(args) > 4 else None
2432 autoDimension = args[5] if len(args) > 5 else True
2433 fields = args[6] if len(args) > 6 else []
2434 geomAssocFields = args[7] if len(args) > 7 else ''
2435 z_tolerance = args[8] if len(args) > 8 else -1.
2436 saveNumbers = args[9] if len(args) > 9 else True
2437 # process keywords arguments
2438 auto_groups = kwargs.get("auto_groups", auto_groups)
2439 version = kwargs.get("version", version)
2440 version = kwargs.get("minor", version)
2441 overwrite = kwargs.get("overwrite", overwrite)
2442 meshPart = kwargs.get("meshPart", meshPart)
2443 autoDimension = kwargs.get("autoDimension", autoDimension)
2444 fields = kwargs.get("fields", fields)
2445 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2446 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2447 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2449 if isinstance( meshPart, Mesh):
2450 meshPart = meshPart.GetMesh()
2452 # invoke engine's function
2453 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2454 unRegister = genObjUnRegister()
2455 if isinstance( meshPart, list ):
2456 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2457 unRegister.set( meshPart )
2459 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2460 self.mesh.SetParameters(Parameters)
2462 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2463 version, overwrite, autoDimension,
2464 fields, geomAssocFields, z_tolerance, saveNumbers )
2466 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2468 def ExportDAT(self, f, meshPart=None, renumber=True):
2470 Export the mesh in a file in DAT format
2474 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2475 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2478 if meshPart or not renumber:
2479 unRegister = genObjUnRegister()
2480 if isinstance( meshPart, list ):
2481 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2482 unRegister.set( meshPart )
2483 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2485 self.mesh.ExportDAT( f, renumber )
2487 def ExportUNV(self, f, meshPart=None, renumber=True):
2489 Export the mesh in a file in UNV format
2493 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2494 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2497 if meshPart or not renumber:
2498 unRegister = genObjUnRegister()
2499 if isinstance( meshPart, list ):
2500 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2501 unRegister.set( meshPart )
2502 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2504 self.mesh.ExportUNV( f, renumber )
2506 def ExportSTL(self, f, ascii=1, meshPart=None):
2508 Export the mesh in a file in STL format
2512 ascii: defines the file encoding
2513 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2517 unRegister = genObjUnRegister()
2518 if isinstance( meshPart, list ):
2519 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2520 unRegister.set( meshPart )
2521 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2523 self.mesh.ExportSTL(f, ascii)
2525 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2527 Export the mesh in a file in CGNS format
2531 overwrite: boolean parameter for overwriting/not overwriting the file
2532 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2533 groupElemsByType: if True all elements of same entity type are exported at ones,
2534 else elements are exported in order of their IDs which can cause creation
2535 of multiple cgns sections
2538 unRegister = genObjUnRegister()
2539 if isinstance( meshPart, list ):
2540 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2541 unRegister.set( meshPart )
2542 if isinstance( meshPart, Mesh ):
2543 meshPart = meshPart.mesh
2545 meshPart = self.mesh
2546 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2548 def ExportGMF(self, f, meshPart=None):
2550 Export the mesh in a file in GMF format.
2551 GMF files must have .mesh extension for the ASCII format and .meshb for
2552 the bynary format. Other extensions are not allowed.
2556 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2559 unRegister = genObjUnRegister()
2560 if isinstance( meshPart, list ):
2561 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2562 unRegister.set( meshPart )
2563 if isinstance( meshPart, Mesh ):
2564 meshPart = meshPart.mesh
2566 meshPart = self.mesh
2567 self.mesh.ExportGMF(meshPart, f, True)
2569 def ExportToMED(self, *args, **kwargs):
2571 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2572 Export the mesh in a file in MED format
2573 allowing to overwrite the file if it exists or add the exported data to its contents
2576 fileName: the file name
2577 opt (boolean): parameter for creating/not creating
2578 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2579 overwrite: boolean parameter for overwriting/not overwriting the file
2580 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2582 - 1D if all mesh nodes lie on OX coordinate axis, or
2583 - 2D if all mesh nodes lie on XOY coordinate plane, or
2584 - 3D in the rest cases.
2586 If **autoDimension** is *False*, the space dimension is always 3.
2589 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2590 # process positional arguments
2591 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2593 auto_groups = args[1] if len(args) > 1 else False
2594 overwrite = args[2] if len(args) > 2 else True
2595 autoDimension = args[3] if len(args) > 3 else True
2596 # process keywords arguments
2597 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2598 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2599 overwrite = kwargs.get("overwrite", overwrite)
2600 autoDimension = kwargs.get("autoDimension", autoDimension)
2602 # invoke engine's function
2603 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2605 def ExportToMEDX(self, *args, **kwargs):
2607 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2608 Export the mesh in a file in MED format
2611 fileName: the file name
2612 opt (boolean): parameter for creating/not creating
2613 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2614 overwrite: boolean parameter for overwriting/not overwriting the file
2615 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2617 - 1D if all mesh nodes lie on OX coordinate axis, or
2618 - 2D if all mesh nodes lie on XOY coordinate plane, or
2619 - 3D in the rest cases.
2621 If **autoDimension** is *False*, the space dimension is always 3.
2624 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2625 # process positional arguments
2626 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2628 auto_groups = args[1] if len(args) > 1 else False
2629 overwrite = args[2] if len(args) > 2 else True
2630 autoDimension = args[3] if len(args) > 3 else True
2631 # process keywords arguments
2632 auto_groups = kwargs.get("auto_groups", auto_groups)
2633 overwrite = kwargs.get("overwrite", overwrite)
2634 autoDimension = kwargs.get("autoDimension", autoDimension)
2636 # invoke engine's function
2637 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2641 def Append(self, meshes, uniteIdenticalGroups = True,
2642 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2644 Append given meshes into this mesh.
2645 All groups of input meshes will be created in this mesh.
2648 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2649 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2650 mergeNodesAndElements: if True, equal nodes and elements are merged
2651 mergeTolerance: tolerance for merging nodes
2652 allGroups: forces creation of groups corresponding to every input mesh
2654 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2655 mergeNodesAndElements, mergeTolerance, allGroups,
2656 meshToAppendTo = self.GetMesh() )
2658 # Operations with groups:
2659 # ----------------------
2660 def CreateEmptyGroup(self, elementType, name):
2662 Create an empty standalone mesh group
2665 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2666 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2667 name: the name of the mesh group
2670 :class:`SMESH.SMESH_Group`
2673 return self.mesh.CreateGroup(elementType, name)
2675 def Group(self, grp, name=""):
2677 Create a mesh group based on the geometric object *grp*
2678 and give it a *name*.
2679 If *name* is not defined the name of the geometric group is used
2682 Works like :meth:`GroupOnGeom`.
2685 grp: a geometric group, a vertex, an edge, a face or a solid
2686 name: the name of the mesh group
2689 :class:`SMESH.SMESH_GroupOnGeom`
2692 return self.GroupOnGeom(grp, name)
2694 def GroupOnGeom(self, grp, name="", typ=None):
2696 Create a mesh group based on the geometrical object *grp*
2697 and give it a *name*.
2698 if *name* is not defined the name of the geometric group is used
2701 grp: a geometrical group, a vertex, an edge, a face or a solid
2702 name: the name of the mesh group
2703 typ: the type of elements in the group; either of
2704 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2705 automatically detected by the type of the geometry
2708 :class:`SMESH.SMESH_GroupOnGeom`
2711 AssureGeomPublished( self, grp, name )
2713 name = grp.GetName()
2715 typ = self._groupTypeFromShape( grp )
2716 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2718 def _groupTypeFromShape( self, shape ):
2720 Pivate method to get a type of group on geometry
2722 tgeo = str(shape.GetShapeType())
2723 if tgeo == "VERTEX":
2725 elif tgeo == "EDGE" or tgeo == "WIRE":
2727 elif tgeo == "FACE" or tgeo == "SHELL":
2729 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2731 elif tgeo == "COMPOUND":
2733 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2735 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2736 # simplification of access in geomBuilder: omniORB.registerObjref
2737 from SHAPERSTUDY_utils import getEngine
2740 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2742 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2743 return self._groupTypeFromShape( sub[0] )
2745 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2748 def GroupOnFilter(self, typ, name, filter):
2750 Create a mesh group with given *name* based on the *filter*.
2751 It is a special type of group dynamically updating it's contents during
2755 typ: the type of elements in the group; either of
2756 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2757 name: the name of the mesh group
2758 filter (SMESH.Filter): the filter defining group contents
2761 :class:`SMESH.SMESH_GroupOnFilter`
2764 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2766 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2768 Create a mesh group by the given ids of elements
2771 groupName: the name of the mesh group
2772 elementType: the type of elements in the group; either of
2773 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2774 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2777 :class:`SMESH.SMESH_Group`
2780 group = self.mesh.CreateGroup(elementType, groupName)
2781 if isinstance( elemIDs, Mesh ):
2782 elemIDs = elemIDs.GetMesh()
2783 if hasattr( elemIDs, "GetIDs" ):
2784 if hasattr( elemIDs, "SetMesh" ):
2785 elemIDs.SetMesh( self.GetMesh() )
2786 group.AddFrom( elemIDs )
2794 CritType=FT_Undefined,
2797 UnaryOp=FT_Undefined,
2800 Create a mesh group by the given conditions
2803 groupName: the name of the mesh group
2804 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2805 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2806 Note that the items starting from FT_LessThan are not suitable for CritType.
2807 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2808 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2809 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2810 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2811 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2814 :class:`SMESH.SMESH_GroupOnFilter`
2817 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2818 group = self.MakeGroupByCriterion(groupName, aCriterion)
2821 def MakeGroupByCriterion(self, groupName, Criterion):
2823 Create a mesh group by the given criterion
2826 groupName: the name of the mesh group
2827 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2830 :class:`SMESH.SMESH_GroupOnFilter`
2833 :meth:`smeshBuilder.GetCriterion`
2836 return self.MakeGroupByCriteria( groupName, [Criterion] )
2838 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2840 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2843 groupName: the name of the mesh group
2844 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2845 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2848 :class:`SMESH.SMESH_GroupOnFilter`
2851 :meth:`smeshBuilder.GetCriterion`
2854 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2855 group = self.MakeGroupByFilter(groupName, aFilter)
2858 def MakeGroupByFilter(self, groupName, theFilter):
2860 Create a mesh group by the given filter
2863 groupName (string): the name of the mesh group
2864 theFilter (SMESH.Filter): the filter
2867 :class:`SMESH.SMESH_GroupOnFilter`
2870 :meth:`smeshBuilder.GetFilter`
2873 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2874 #theFilter.SetMesh( self.mesh )
2875 #group.AddFrom( theFilter )
2876 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2879 def RemoveGroup(self, group):
2884 group (SMESH.SMESH_GroupBase): group to remove
2887 self.mesh.RemoveGroup(group)
2889 def RemoveGroupWithContents(self, group):
2891 Remove a group with its contents
2894 group (SMESH.SMESH_GroupBase): group to remove
2897 This operation can create gaps in numeration of nodes or elements.
2898 Call :meth:`RenumberElements` to remove the gaps.
2901 self.mesh.RemoveGroupWithContents(group)
2903 def GetGroups(self, elemType = SMESH.ALL):
2905 Get the list of groups existing in the mesh in the order of creation
2906 (starting from the oldest one)
2909 elemType (SMESH.ElementType): type of elements the groups contain;
2910 by default groups of elements of all types are returned
2913 a list of :class:`SMESH.SMESH_GroupBase`
2916 groups = self.mesh.GetGroups()
2917 if elemType == SMESH.ALL:
2921 if g.GetType() == elemType:
2922 typedGroups.append( g )
2929 Get the number of groups existing in the mesh
2932 the quantity of groups as an integer value
2935 return self.mesh.NbGroups()
2937 def GetGroupNames(self):
2939 Get the list of names of groups existing in the mesh
2945 groups = self.GetGroups()
2947 for group in groups:
2948 names.append(group.GetName())
2951 def GetGroupByName(self, name, elemType = None):
2953 Find groups by name and type
2956 name (string): name of the group of interest
2957 elemType (SMESH.ElementType): type of elements the groups contain;
2958 by default one group of any type is returned;
2959 if elemType == SMESH.ALL then all groups of any type are returned
2962 a list of :class:`SMESH.SMESH_GroupBase`
2966 for group in self.GetGroups():
2967 if group.GetName() == name:
2968 if elemType is None:
2970 if ( elemType == SMESH.ALL or
2971 group.GetType() == elemType ):
2972 groups.append( group )
2975 def UnionGroups(self, group1, group2, name):
2977 Produce a union of two groups.
2978 A new group is created. All mesh elements that are
2979 present in the initial groups are added to the new one
2982 group1 (SMESH.SMESH_GroupBase): a group
2983 group2 (SMESH.SMESH_GroupBase): another group
2986 instance of :class:`SMESH.SMESH_Group`
2989 return self.mesh.UnionGroups(group1, group2, name)
2991 def UnionListOfGroups(self, groups, name):
2993 Produce a union list of groups.
2994 New group is created. All mesh elements that are present in
2995 initial groups are added to the new one
2998 groups: list of :class:`SMESH.SMESH_GroupBase`
3001 instance of :class:`SMESH.SMESH_Group`
3003 return self.mesh.UnionListOfGroups(groups, name)
3005 def IntersectGroups(self, group1, group2, name):
3007 Prodice an intersection of two groups.
3008 A new group is created. All mesh elements that are common
3009 for the two initial groups are added to the new one.
3012 group1 (SMESH.SMESH_GroupBase): a group
3013 group2 (SMESH.SMESH_GroupBase): another group
3016 instance of :class:`SMESH.SMESH_Group`
3019 return self.mesh.IntersectGroups(group1, group2, name)
3021 def IntersectListOfGroups(self, groups, name):
3023 Produce an intersection of groups.
3024 New group is created. All mesh elements that are present in all
3025 initial groups simultaneously are added to the new one
3028 groups: a list of :class:`SMESH.SMESH_GroupBase`
3031 instance of :class:`SMESH.SMESH_Group`
3033 return self.mesh.IntersectListOfGroups(groups, name)
3035 def CutGroups(self, main_group, tool_group, name):
3037 Produce a cut of two groups.
3038 A new group is created. All mesh elements that are present in
3039 the main group but are not present in the tool group are added to the new one
3042 main_group (SMESH.SMESH_GroupBase): a group to cut from
3043 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3046 an instance of :class:`SMESH.SMESH_Group`
3049 return self.mesh.CutGroups(main_group, tool_group, name)
3051 def CutListOfGroups(self, main_groups, tool_groups, name):
3053 Produce a cut of groups.
3054 A new group is created. All mesh elements that are present in main groups
3055 but do not present in tool groups are added to the new one
3058 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3059 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3062 an instance of :class:`SMESH.SMESH_Group`
3065 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3067 def CreateDimGroup(self, groups, elemType, name,
3068 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3070 Create a standalone group of entities basing on nodes of other groups.
3073 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3074 elemType: a type of elements to include to the new group; either of
3075 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3076 name: a name of the new group.
3077 nbCommonNodes: a criterion of inclusion of an element to the new group
3078 basing on number of element nodes common with reference *groups*.
3079 Meaning of possible values are:
3081 - SMESH.ALL_NODES - include if all nodes are common,
3082 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3083 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3084 - SMEHS.MAJORITY - include if half of nodes or more are common.
3085 underlyingOnly: if *True* (default), an element is included to the
3086 new group provided that it is based on nodes of an element of *groups*;
3087 in this case the reference *groups* are supposed to be of higher dimension
3088 than *elemType*, which can be useful for example to get all faces lying on
3089 volumes of the reference *groups*.
3092 an instance of :class:`SMESH.SMESH_Group`
3095 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3097 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3099 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3101 Distribute all faces of the mesh among groups using sharp edges and optionally
3102 existing 1D elements as group boundaries.
3105 sharpAngle: edge is considered sharp if an angle between normals of
3106 adjacent faces is more than \a sharpAngle in degrees.
3107 createEdges (boolean): to create 1D elements for detected sharp edges.
3108 useExistingEdges (boolean): to use existing edges as group boundaries
3110 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3112 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3113 self.mesh.SetParameters(Parameters)
3114 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3116 def ConvertToStandalone(self, group):
3118 Convert group on geom into standalone group
3121 return self.mesh.ConvertToStandalone(group)
3123 # Get some info about mesh:
3124 # ------------------------
3126 def GetLog(self, clearAfterGet):
3128 Return the log of nodes and elements added or removed
3129 since the previous clear of the log.
3132 clearAfterGet: log is emptied after Get (safe if concurrents access)
3135 list of SMESH.log_block structures { commandType, number, coords, indexes }
3138 return self.mesh.GetLog(clearAfterGet)
3142 Clear the log of nodes and elements added or removed since the previous
3143 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3146 self.mesh.ClearLog()
3148 def SetAutoColor(self, theAutoColor):
3150 Toggle auto color mode on the object.
3151 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3154 theAutoColor (boolean): the flag which toggles auto color mode.
3157 self.mesh.SetAutoColor(theAutoColor)
3159 def GetAutoColor(self):
3161 Get flag of object auto color mode.
3167 return self.mesh.GetAutoColor()
3174 integer value, which is the internal Id of the mesh
3177 return self.mesh.GetId()
3179 def HasDuplicatedGroupNamesMED(self):
3181 Check the group names for duplications.
3182 Consider the maximum group name length stored in MED file.
3188 return self.mesh.HasDuplicatedGroupNamesMED()
3190 def GetMeshEditor(self):
3192 Obtain the mesh editor tool
3195 an instance of :class:`SMESH.SMESH_MeshEditor`
3200 def GetIDSource(self, ids, elemType = SMESH.ALL):
3202 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3203 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3207 elemType: type of elements; this parameter is used to distinguish
3208 IDs of nodes from IDs of elements; by default ids are treated as
3209 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3212 an instance of :class:`SMESH.SMESH_IDSource`
3215 call UnRegister() for the returned object as soon as it is no more useful::
3217 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3218 mesh.DoSomething( idSrc )
3222 if isinstance( ids, int ):
3224 return self.editor.MakeIDSource(ids, elemType)
3227 # Get information about mesh contents:
3228 # ------------------------------------
3230 def GetMeshInfo(self, obj = None):
3232 Get the mesh statistic.
3235 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3238 if not obj: obj = self.mesh
3239 return self.smeshpyD.GetMeshInfo(obj)
3243 Return the number of nodes in the mesh
3249 return self.mesh.NbNodes()
3251 def NbElements(self):
3253 Return the number of elements in the mesh
3259 return self.mesh.NbElements()
3261 def Nb0DElements(self):
3263 Return the number of 0d elements in the mesh
3269 return self.mesh.Nb0DElements()
3273 Return the number of ball discrete elements in the mesh
3279 return self.mesh.NbBalls()
3283 Return the number of edges in the mesh
3289 return self.mesh.NbEdges()
3291 def NbEdgesOfOrder(self, elementOrder):
3293 Return the number of edges with the given order in the mesh
3296 elementOrder: the order of elements
3297 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3303 return self.mesh.NbEdgesOfOrder(elementOrder)
3307 Return the number of faces in the mesh
3313 return self.mesh.NbFaces()
3315 def NbFacesOfOrder(self, elementOrder):
3317 Return the number of faces with the given order in the mesh
3320 elementOrder: the order of elements
3321 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3327 return self.mesh.NbFacesOfOrder(elementOrder)
3329 def NbTriangles(self):
3331 Return the number of triangles in the mesh
3337 return self.mesh.NbTriangles()
3339 def NbTrianglesOfOrder(self, elementOrder):
3341 Return the number of triangles with the given order in the mesh
3344 elementOrder: is the order of elements
3345 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3351 return self.mesh.NbTrianglesOfOrder(elementOrder)
3353 def NbBiQuadTriangles(self):
3355 Return the number of biquadratic triangles in the mesh
3361 return self.mesh.NbBiQuadTriangles()
3363 def NbQuadrangles(self):
3365 Return the number of quadrangles in the mesh
3371 return self.mesh.NbQuadrangles()
3373 def NbQuadranglesOfOrder(self, elementOrder):
3375 Return the number of quadrangles with the given order in the mesh
3378 elementOrder: the order of elements
3379 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3385 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3387 def NbBiQuadQuadrangles(self):
3389 Return the number of biquadratic quadrangles in the mesh
3395 return self.mesh.NbBiQuadQuadrangles()
3397 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3399 Return the number of polygons of given order in the mesh
3402 elementOrder: the order of elements
3403 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3409 return self.mesh.NbPolygonsOfOrder(elementOrder)
3411 def NbVolumes(self):
3413 Return the number of volumes in the mesh
3419 return self.mesh.NbVolumes()
3422 def NbVolumesOfOrder(self, elementOrder):
3424 Return the number of volumes with the given order in the mesh
3427 elementOrder: the order of elements
3428 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3434 return self.mesh.NbVolumesOfOrder(elementOrder)
3438 Return the number of tetrahedrons in the mesh
3444 return self.mesh.NbTetras()
3446 def NbTetrasOfOrder(self, elementOrder):
3448 Return the number of tetrahedrons with the given order in the mesh
3451 elementOrder: the order of elements
3452 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3458 return self.mesh.NbTetrasOfOrder(elementOrder)
3462 Return the number of hexahedrons in the mesh
3468 return self.mesh.NbHexas()
3470 def NbHexasOfOrder(self, elementOrder):
3472 Return the number of hexahedrons with the given order in the mesh
3475 elementOrder: the order of elements
3476 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3482 return self.mesh.NbHexasOfOrder(elementOrder)
3484 def NbTriQuadraticHexas(self):
3486 Return the number of triquadratic hexahedrons in the mesh
3492 return self.mesh.NbTriQuadraticHexas()
3494 def NbPyramids(self):
3496 Return the number of pyramids in the mesh
3502 return self.mesh.NbPyramids()
3504 def NbPyramidsOfOrder(self, elementOrder):
3506 Return the number of pyramids with the given order in the mesh
3509 elementOrder: the order of elements
3510 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3516 return self.mesh.NbPyramidsOfOrder(elementOrder)
3520 Return the number of prisms in the mesh
3526 return self.mesh.NbPrisms()
3528 def NbPrismsOfOrder(self, elementOrder):
3530 Return the number of prisms with the given order in the mesh
3533 elementOrder: the order of elements
3534 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3540 return self.mesh.NbPrismsOfOrder(elementOrder)
3542 def NbHexagonalPrisms(self):
3544 Return the number of hexagonal prisms in the mesh
3550 return self.mesh.NbHexagonalPrisms()
3552 def NbPolyhedrons(self):
3554 Return the number of polyhedrons in the mesh
3560 return self.mesh.NbPolyhedrons()
3562 def NbSubMesh(self):
3564 Return the number of submeshes in the mesh
3570 return self.mesh.NbSubMesh()
3572 def GetElementsId(self):
3574 Return the list of all mesh elements IDs
3577 the list of integer values
3580 :meth:`GetElementsByType`
3583 return self.mesh.GetElementsId()
3585 def GetElementsByType(self, elementType):
3587 Return the list of IDs of mesh elements with the given type
3590 elementType (SMESH.ElementType): the required type of elements
3593 list of integer values
3596 return self.mesh.GetElementsByType(elementType)
3598 def GetNodesId(self):
3600 Return the list of mesh nodes IDs
3603 the list of integer values
3606 return self.mesh.GetNodesId()
3608 # Get the information about mesh elements:
3609 # ------------------------------------
3611 def GetElementType(self, id, iselem=True):
3613 Return the type of mesh element or node
3616 the value from :class:`SMESH.ElementType` enumeration.
3617 Return SMESH.ALL if element or node with the given ID does not exist
3620 return self.mesh.GetElementType(id, iselem)
3622 def GetElementGeomType(self, id):
3624 Return the geometric type of mesh element
3627 the value from :class:`SMESH.EntityType` enumeration.
3630 return self.mesh.GetElementGeomType(id)
3632 def GetElementShape(self, id):
3634 Return the shape type of mesh element
3637 the value from :class:`SMESH.GeometryType` enumeration.
3640 return self.mesh.GetElementShape(id)
3642 def GetSubMeshElementsId(self, Shape):
3644 Return the list of sub-mesh elements IDs
3647 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3648 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3651 list of integer values
3654 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3655 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3658 return self.mesh.GetSubMeshElementsId(ShapeID)
3660 def GetSubMeshNodesId(self, Shape, all):
3662 Return the list of sub-mesh nodes IDs
3665 Shape: a geom object (sub-shape).
3666 *Shape* must be the sub-shape of a :meth:`GetShape`
3667 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3670 list of integer values
3673 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3674 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3677 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3679 def GetSubMeshElementType(self, Shape):
3681 Return type of elements on given shape
3684 Shape: a geom object (sub-shape).
3685 *Shape* must be a sub-shape of a ShapeToMesh()
3688 :class:`SMESH.ElementType`
3691 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3692 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3695 return self.mesh.GetSubMeshElementType(ShapeID)
3699 Get the mesh description
3705 return self.mesh.Dump()
3708 # Get the information about nodes and elements of a mesh by its IDs:
3709 # -----------------------------------------------------------
3711 def GetNodeXYZ(self, id):
3713 Get XYZ coordinates of a node.
3714 If there is no node for the given ID - return an empty list
3717 list of float values
3720 return self.mesh.GetNodeXYZ(id)
3722 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3724 Return list of IDs of inverse elements for the given node.
3725 If there is no node for the given ID - return an empty list
3729 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3732 list of integer values
3735 return self.mesh.GetNodeInverseElements(id,elemType)
3737 def GetNodePosition(self,NodeID):
3739 Return the position of a node on the shape
3742 :class:`SMESH.NodePosition`
3745 return self.mesh.GetNodePosition(NodeID)
3747 def GetElementPosition(self,ElemID):
3749 Return the position of an element on the shape
3752 :class:`SMESH.ElementPosition`
3755 return self.mesh.GetElementPosition(ElemID)
3757 def GetShapeID(self, id):
3759 Return the ID of the shape, on which the given node was generated.
3762 an integer value > 0 or -1 if there is no node for the given
3763 ID or the node is not assigned to any geometry
3766 return self.mesh.GetShapeID(id)
3768 def GetShapeIDForElem(self,id):
3770 Return the ID of the shape, on which the given element was generated.
3773 an integer value > 0 or -1 if there is no element for the given
3774 ID or the element is not assigned to any geometry
3777 return self.mesh.GetShapeIDForElem(id)
3779 def GetElemNbNodes(self, id):
3781 Return the number of nodes of the given element
3784 an integer value > 0 or -1 if there is no element for the given ID
3787 return self.mesh.GetElemNbNodes(id)
3789 def GetElemNode(self, id, index):
3791 Return the node ID the given (zero based) index for the given element.
3793 * If there is no element for the given ID - return -1.
3794 * If there is no node for the given index - return -2.
3797 id (int): element ID
3798 index (int): node index within the element
3801 an integer value (ID)
3804 :meth:`GetElemNodes`
3807 return self.mesh.GetElemNode(id, index)
3809 def GetElemNodes(self, id):
3811 Return the IDs of nodes of the given element
3814 a list of integer values
3817 return self.mesh.GetElemNodes(id)
3819 def IsMediumNode(self, elementID, nodeID):
3821 Return true if the given node is the medium node in the given quadratic element
3824 return self.mesh.IsMediumNode(elementID, nodeID)
3826 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3828 Return true if the given node is the medium node in one of quadratic elements
3831 nodeID: ID of the node
3832 elementType: the type of elements to check a state of the node, either of
3833 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3836 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3838 def ElemNbEdges(self, id):
3840 Return the number of edges for the given element
3843 return self.mesh.ElemNbEdges(id)
3845 def ElemNbFaces(self, id):
3847 Return the number of faces for the given element
3850 return self.mesh.ElemNbFaces(id)
3852 def GetElemFaceNodes(self,elemId, faceIndex):
3854 Return nodes of given face (counted from zero) for given volumic element.
3857 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3859 def GetFaceNormal(self, faceId, normalized=False):
3861 Return three components of normal of given mesh face
3862 (or an empty array in KO case)
3865 return self.mesh.GetFaceNormal(faceId,normalized)
3867 def FindElementByNodes(self, nodes):
3869 Return an element based on all given nodes.
3872 return self.mesh.FindElementByNodes(nodes)
3874 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3876 Return elements including all given nodes.
3879 return self.mesh.GetElementsByNodes( nodes, elemType )
3881 def IsPoly(self, id):
3883 Return true if the given element is a polygon
3886 return self.mesh.IsPoly(id)
3888 def IsQuadratic(self, id):
3890 Return true if the given element is quadratic
3893 return self.mesh.IsQuadratic(id)
3895 def GetBallDiameter(self, id):
3897 Return diameter of a ball discrete element or zero in case of an invalid *id*
3900 return self.mesh.GetBallDiameter(id)
3902 def BaryCenter(self, id):
3904 Return XYZ coordinates of the barycenter of the given element.
3905 If there is no element for the given ID - return an empty list
3908 a list of three double values
3911 :meth:`smeshBuilder.GetGravityCenter`
3914 return self.mesh.BaryCenter(id)
3916 def GetIdsFromFilter(self, filter, meshParts=[] ):
3918 Pass mesh elements through the given filter and return IDs of fitting elements
3921 filter: :class:`SMESH.Filter`
3922 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3928 :meth:`SMESH.Filter.GetIDs`
3929 :meth:`SMESH.Filter.GetElementsIdFromParts`
3932 filter.SetMesh( self.mesh )
3935 if isinstance( meshParts, Mesh ):
3936 filter.SetMesh( meshParts.GetMesh() )
3937 return theFilter.GetIDs()
3938 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3939 meshParts = [ meshParts ]
3940 return filter.GetElementsIdFromParts( meshParts )
3942 return filter.GetIDs()
3944 # Get mesh measurements information:
3945 # ------------------------------------
3947 def GetFreeBorders(self):
3949 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3950 Return a list of special structures (borders).
3953 a list of :class:`SMESH.FreeEdges.Border`
3956 aFilterMgr = self.smeshpyD.CreateFilterManager()
3957 aPredicate = aFilterMgr.CreateFreeEdges()
3958 aPredicate.SetMesh(self.mesh)
3959 aBorders = aPredicate.GetBorders()
3960 aFilterMgr.UnRegister()
3963 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3965 Get minimum distance between two nodes, elements or distance to the origin
3968 id1: first node/element id
3969 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3970 isElem1: *True* if *id1* is element id, *False* if it is node id
3971 isElem2: *True* if *id2* is element id, *False* if it is node id
3974 minimum distance value
3976 :meth:`GetMinDistance`
3979 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3980 return aMeasure.value
3982 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3984 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3987 id1: first node/element id
3988 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3989 isElem1: *True* if *id1* is element id, *False* if it is node id
3990 isElem2: *True* if *id2* is element id, *False* if it is node id
3993 :class:`SMESH.Measure` structure
3999 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
4001 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
4004 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
4006 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4011 aMeasurements = self.smeshpyD.CreateMeasurements()
4012 aMeasure = aMeasurements.MinDistance(id1, id2)
4013 genObjUnRegister([aMeasurements,id1, id2])
4016 def BoundingBox(self, objects=None, isElem=False):
4018 Get bounding box of the specified object(s)
4021 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4022 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4023 *False* specifies that *objects* are nodes
4026 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4029 :meth:`GetBoundingBox()`
4032 result = self.GetBoundingBox(objects, isElem)
4036 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4039 def GetBoundingBox(self, objects=None, isElem=False):
4041 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4044 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4045 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4046 False means that *objects* are nodes
4049 :class:`SMESH.Measure` structure
4052 :meth:`BoundingBox()`
4056 objects = [self.mesh]
4057 elif isinstance(objects, tuple):
4058 objects = list(objects)
4059 if not isinstance(objects, list):
4061 if len(objects) > 0 and isinstance(objects[0], int):
4064 unRegister = genObjUnRegister()
4066 if isinstance(o, Mesh):
4067 srclist.append(o.mesh)
4068 elif hasattr(o, "_narrow"):
4069 src = o._narrow(SMESH.SMESH_IDSource)
4070 if src: srclist.append(src)
4072 elif isinstance(o, list):
4074 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4076 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4077 unRegister.set( srclist[-1] )
4080 aMeasurements = self.smeshpyD.CreateMeasurements()
4081 unRegister.set( aMeasurements )
4082 aMeasure = aMeasurements.BoundingBox(srclist)
4085 # Mesh edition (SMESH_MeshEditor functionality):
4086 # ---------------------------------------------
4088 def RemoveElements(self, IDsOfElements):
4090 Remove the elements from the mesh by ids
4093 IDsOfElements: is a list of ids of elements to remove
4099 This operation can create gaps in numeration of elements.
4100 Call :meth:`RenumberElements` to remove the gaps.
4103 return self.editor.RemoveElements(IDsOfElements)
4105 def RemoveNodes(self, IDsOfNodes):
4107 Remove nodes from mesh by ids
4110 IDsOfNodes: is a list of ids of nodes to remove
4116 This operation can create gaps in numeration of nodes.
4117 Call :meth:`RenumberElements` to remove the gaps.
4120 return self.editor.RemoveNodes(IDsOfNodes)
4122 def RemoveNodeWithReconnection(self, nodeID ):
4124 Remove a node along with changing surrounding faces to cover a hole.
4127 nodeID: ID of node to remove
4130 return self.editor.RemoveNodeWithReconnection( nodeID )
4132 def RemoveOrphanNodes(self):
4134 Remove all orphan (free) nodes from mesh
4137 number of the removed nodes
4140 This operation can create gaps in numeration of nodes.
4141 Call :meth:`RenumberElements` to remove the gaps.
4144 return self.editor.RemoveOrphanNodes()
4146 def AddNode(self, x, y, z):
4148 Add a node to the mesh by coordinates
4154 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4155 if hasVars: self.mesh.SetParameters(Parameters)
4156 return self.editor.AddNode( x, y, z)
4158 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4160 Create a 0D element on a node with given number.
4163 IDOfNode: the ID of node for creation of the element.
4164 DuplicateElements: to add one more 0D element to a node or not
4167 ID of the new 0D element
4170 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4172 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4174 Create 0D elements on all nodes of the given elements except those
4175 nodes on which a 0D element already exists.
4178 theObject: an object on whose nodes 0D elements will be created.
4179 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4180 theGroupName: optional name of a group to add 0D elements created
4181 and/or found on nodes of *theObject*.
4182 DuplicateElements: to add one more 0D element to a node or not
4185 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4186 IDs of new and/or found 0D elements. IDs of 0D elements
4187 can be retrieved from the returned object by
4188 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4191 unRegister = genObjUnRegister()
4192 if isinstance( theObject, Mesh ):
4193 theObject = theObject.GetMesh()
4194 elif isinstance( theObject, list ):
4195 theObject = self.GetIDSource( theObject, SMESH.ALL )
4196 unRegister.set( theObject )
4197 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4199 def AddBall(self, IDOfNode, diameter):
4201 Create a ball element on a node with given ID.
4204 IDOfNode: the ID of node for creation of the element.
4205 diameter: the bal diameter.
4208 ID of the new ball element
4211 return self.editor.AddBall( IDOfNode, diameter )
4213 def AddEdge(self, IDsOfNodes):
4215 Create a linear or quadratic edge (this is determined
4216 by the number of given nodes).
4219 IDsOfNodes: list of node IDs for creation of the element.
4220 The order of nodes in this list should correspond to
4221 the :ref:`connectivity convention <connectivity_page>`.
4227 return self.editor.AddEdge(IDsOfNodes)
4229 def AddFace(self, IDsOfNodes):
4231 Create a linear or quadratic face (this is determined
4232 by the number of given nodes).
4235 IDsOfNodes: list of node IDs for creation of the element.
4236 The order of nodes in this list should correspond to
4237 the :ref:`connectivity convention <connectivity_page>`.
4243 return self.editor.AddFace(IDsOfNodes)
4245 def AddPolygonalFace(self, IdsOfNodes):
4247 Add a polygonal face defined by a list of node IDs
4250 IdsOfNodes: the list of node IDs for creation of the element.
4256 return self.editor.AddPolygonalFace(IdsOfNodes)
4258 def AddQuadPolygonalFace(self, IdsOfNodes):
4260 Add a quadratic polygonal face defined by a list of node IDs
4263 IdsOfNodes: the list of node IDs for creation of the element;
4264 corner nodes follow first.
4270 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4272 def AddVolume(self, IDsOfNodes):
4274 Create both simple and quadratic volume (this is determined
4275 by the number of given nodes).
4278 IDsOfNodes: list of node IDs for creation of the element.
4279 The order of nodes in this list should correspond to
4280 the :ref:`connectivity convention <connectivity_page>`.
4283 ID of the new volumic element
4286 return self.editor.AddVolume(IDsOfNodes)
4288 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4290 Create a volume of many faces, giving nodes for each face.
4293 IdsOfNodes: list of node IDs for volume creation, face by face.
4294 Quantities: list of integer values, Quantities[i]
4295 gives the quantity of nodes in face number i.
4298 ID of the new volumic element
4301 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4303 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4305 Create a volume of many faces, giving the IDs of the existing faces.
4308 The created volume will refer only to the nodes
4309 of the given faces, not to the faces themselves.
4312 IdsOfFaces: the list of face IDs for volume creation.
4315 ID of the new volumic element
4318 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4321 def SetNodeOnVertex(self, NodeID, Vertex):
4323 Bind a node to a vertex
4327 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4330 True if succeed else raises an exception
4333 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4334 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4338 self.editor.SetNodeOnVertex(NodeID, VertexID)
4339 except SALOME.SALOME_Exception as inst:
4340 raise ValueError(inst.details.text)
4344 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4346 Store the node position on an edge
4350 Edge: an edge (GEOM.GEOM_Object) or edge ID
4351 paramOnEdge: a parameter on the edge where the node is located
4354 True if succeed else raises an exception
4357 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4358 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4362 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4363 except SALOME.SALOME_Exception as inst:
4364 raise ValueError(inst.details.text)
4367 def SetNodeOnFace(self, NodeID, Face, u, v):
4369 Store node position on a face
4373 Face: a face (GEOM.GEOM_Object) or face ID
4374 u: U parameter on the face where the node is located
4375 v: V parameter on the face where the node is located
4378 True if succeed else raises an exception
4381 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4382 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4386 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4387 except SALOME.SALOME_Exception as inst:
4388 raise ValueError(inst.details.text)
4391 def SetNodeInVolume(self, NodeID, Solid):
4393 Bind a node to a solid
4397 Solid: a solid (GEOM.GEOM_Object) or solid ID
4400 True if succeed else raises an exception
4403 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4404 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4408 self.editor.SetNodeInVolume(NodeID, SolidID)
4409 except SALOME.SALOME_Exception as inst:
4410 raise ValueError(inst.details.text)
4413 def SetMeshElementOnShape(self, ElementID, Shape):
4415 Bind an element to a shape
4418 ElementID: an element ID
4419 Shape: a shape (GEOM.GEOM_Object) or shape ID
4422 True if succeed else raises an exception
4425 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4426 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4430 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4431 except SALOME.SALOME_Exception as inst:
4432 raise ValueError(inst.details.text)
4436 def MoveNode(self, NodeID, x, y, z):
4438 Move the node with the given id
4441 NodeID: the id of the node
4442 x: a new X coordinate
4443 y: a new Y coordinate
4444 z: a new Z coordinate
4447 True if succeed else False
4450 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4451 if hasVars: self.mesh.SetParameters(Parameters)
4452 return self.editor.MoveNode(NodeID, x, y, z)
4454 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4456 Find the node closest to a point and moves it to a point location
4459 x: the X coordinate of a point
4460 y: the Y coordinate of a point
4461 z: the Z coordinate of a point
4462 NodeID: if specified (>0), the node with this ID is moved,
4463 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4466 the ID of a moved node
4469 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4470 if hasVars: self.mesh.SetParameters(Parameters)
4471 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4473 def FindNodeClosestTo(self, x, y, z):
4475 Find the node closest to a point
4478 x: the X coordinate of a point
4479 y: the Y coordinate of a point
4480 z: the Z coordinate of a point
4486 return self.editor.FindNodeClosestTo(x, y, z)
4488 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4490 Find the elements where a point lays IN or ON
4493 x,y,z (float): coordinates of the point
4494 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4495 means elements of any type excluding nodes, discrete and 0D elements.
4496 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4499 list of IDs of found elements
4502 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4504 return self.editor.FindElementsByPoint(x, y, z, elementType)
4506 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4508 Project a point to a mesh object.
4509 Return ID of an element of given type where the given point is projected
4510 and coordinates of the projection point.
4511 In the case if nothing found, return -1 and []
4513 if isinstance( meshObject, Mesh ):
4514 meshObject = meshObject.GetMesh()
4516 meshObject = self.GetMesh()
4517 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4519 def GetPointState(self, x, y, z):
4521 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4522 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4523 UNKNOWN state means that either mesh is wrong or the analysis fails.
4526 return self.editor.GetPointState(x, y, z)
4528 def IsManifold(self):
4530 Check if a 2D mesh is manifold
4533 return self.editor.IsManifold()
4535 def IsCoherentOrientation2D(self):
4537 Check if orientation of 2D elements is coherent
4540 return self.editor.IsCoherentOrientation2D()
4542 def Get1DBranches( self, edges, startNode = 0 ):
4544 Partition given 1D elements into groups of contiguous edges.
4545 A node where number of meeting edges != 2 is a group end.
4546 An optional startNode is used to orient groups it belongs to.
4549 A list of edge groups and a list of corresponding node groups,
4550 where the group is a list of IDs of edges or nodes, like follows
4551 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4552 If a group is closed, the first and last nodes of the group are same.
4554 if isinstance( edges, Mesh ):
4555 edges = edges.GetMesh()
4556 unRegister = genObjUnRegister()
4557 if isinstance( edges, list ):
4558 edges = self.GetIDSource( edges, SMESH.EDGE )
4559 unRegister.set( edges )
4560 return self.editor.Get1DBranches( edges, startNode )
4562 def FindSharpEdges( self, angle, addExisting=False ):
4564 Return sharp edges of faces and non-manifold ones.
4565 Optionally add existing edges.
4568 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4569 addExisting: to return existing edges (1D elements) as well
4572 list of FaceEdge structures
4574 angle = ParseParameters( angle )[0]
4575 return self.editor.FindSharpEdges( angle, addExisting )
4577 def MeshToPassThroughAPoint(self, x, y, z):
4579 Find the node closest to a point and moves it to a point location
4582 x: the X coordinate of a point
4583 y: the Y coordinate of a point
4584 z: the Z coordinate of a point
4587 the ID of a moved node
4590 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4592 def InverseDiag(self, NodeID1, NodeID2):
4594 Replace two neighbour triangles sharing Node1-Node2 link
4595 with the triangles built on the same 4 nodes but having other common link.
4598 NodeID1: the ID of the first node
4599 NodeID2: the ID of the second node
4602 False if proper faces were not found
4604 return self.editor.InverseDiag(NodeID1, NodeID2)
4606 def DeleteDiag(self, NodeID1, NodeID2):
4608 Replace two neighbour triangles sharing *Node1-Node2* link
4609 with a quadrangle built on the same 4 nodes.
4612 NodeID1: ID of the first node
4613 NodeID2: ID of the second node
4616 False if proper faces were not found
4619 This operation can create gaps in numeration of elements.
4620 Call :meth:`RenumberElements` to remove the gaps.
4623 return self.editor.DeleteDiag(NodeID1, NodeID2)
4625 def AddNodeOnSegment(self, Node1, Node2, position = 0.5):
4627 Replace each triangle bound by Node1-Node2 segment with
4628 two triangles by connecting a node made on the link with a node
4629 opposite to the link.
4632 Node1: ID of the first node
4633 Node2: ID of the second node
4634 position: location [0,1] of the new node on the segment
4636 return self.editor.AddNodeOnSegment(Node1, Node2, position)
4638 def AddNodeOnFace(self, face, x, y, z):
4640 Split a face into triangles by adding a new node onto the face
4641 and connecting the new node with face nodes
4644 face: ID of the face
4645 x,y,z: coordinates of the new node
4647 return self.editor.AddNodeOnFace(face, x, y, z)
4649 def Reorient(self, IDsOfElements=None):
4651 Reorient elements by ids
4654 IDsOfElements: if undefined reorients all mesh elements
4657 True if succeed else False
4660 if IDsOfElements == None:
4661 IDsOfElements = self.GetElementsId()
4662 return self.editor.Reorient(IDsOfElements)
4664 def ReorientObject(self, theObject):
4666 Reorient all elements of the object
4669 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4672 True if succeed else False
4675 if ( isinstance( theObject, Mesh )):
4676 theObject = theObject.GetMesh()
4677 return self.editor.ReorientObject(theObject)
4679 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4681 Reorient faces contained in *the2DObject*.
4684 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4685 theDirection: a desired direction of normal of *theFace*.
4686 It can be either a GEOM vector or a list of coordinates [x,y,z].
4687 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4688 compared with theDirection. It can be either ID of face or a point
4689 by which the face will be found. The point can be given as either
4690 a GEOM vertex or a list of point coordinates.
4693 number of reoriented faces
4696 unRegister = genObjUnRegister()
4698 if isinstance( the2DObject, Mesh ):
4699 the2DObject = the2DObject.GetMesh()
4700 if isinstance( the2DObject, list ):
4701 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4702 unRegister.set( the2DObject )
4703 # check theDirection
4704 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4705 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4706 if isinstance( theDirection, list ):
4707 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4708 # prepare theFace and thePoint
4709 theFace = theFaceOrPoint
4710 thePoint = PointStruct(0,0,0)
4711 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4712 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4714 if isinstance( theFaceOrPoint, list ):
4715 thePoint = PointStruct( *theFaceOrPoint )
4717 if isinstance( theFaceOrPoint, PointStruct ):
4718 thePoint = theFaceOrPoint
4720 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4722 def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4724 Reorient faces contained in a list of *objectFaces*
4725 equally to faces contained in a list of *referenceFaces*.
4728 objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4729 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.
4732 number of reoriented faces.
4734 if not isinstance( objectFaces, list ):
4735 objectFaces = [ objectFaces ]
4736 for i,obj2D in enumerate( objectFaces ):
4737 if isinstance( obj2D, Mesh ):
4738 objectFaces[i] = obj2D.GetMesh()
4739 if not isinstance( referenceFaces, list ):
4740 referenceFaces = [ referenceFaces ]
4742 return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4745 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4747 Reorient faces according to adjacent volumes.
4750 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4751 either IDs of faces or face groups.
4752 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4753 theOutsideNormal: to orient faces to have their normals
4754 pointing either *outside* or *inside* the adjacent volumes.
4757 number of reoriented faces.
4760 unRegister = genObjUnRegister()
4762 if not isinstance( the2DObject, list ):
4763 the2DObject = [ the2DObject ]
4764 elif the2DObject and isinstance( the2DObject[0], int ):
4765 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4766 unRegister.set( the2DObject )
4767 the2DObject = [ the2DObject ]
4768 for i,obj2D in enumerate( the2DObject ):
4769 if isinstance( obj2D, Mesh ):
4770 the2DObject[i] = obj2D.GetMesh()
4771 if isinstance( obj2D, list ):
4772 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4773 unRegister.set( the2DObject[i] )
4775 if isinstance( the3DObject, Mesh ):
4776 the3DObject = the3DObject.GetMesh()
4777 if isinstance( the3DObject, list ):
4778 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4779 unRegister.set( the3DObject )
4780 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4782 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4784 Fuse the neighbouring triangles into quadrangles.
4787 IDsOfElements: The triangles to be fused.
4788 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4789 applied to possible quadrangles to choose a neighbour to fuse with.
4790 Note that not all items of :class:`SMESH.FunctorType` corresponds
4791 to numerical functors.
4792 MaxAngle: is the maximum angle between element normals at which the fusion
4793 is still performed; theMaxAngle is measured in radians.
4794 Also it could be a name of variable which defines angle in degrees.
4797 True in case of success, False otherwise.
4800 This operation can create gaps in numeration of elements.
4801 Call :meth:`RenumberElements` to remove the gaps.
4804 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4805 self.mesh.SetParameters(Parameters)
4806 if not IDsOfElements:
4807 IDsOfElements = self.GetElementsId()
4808 Functor = self.smeshpyD.GetFunctor(theCriterion)
4809 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4811 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4813 Fuse the neighbouring triangles of the object into quadrangles
4816 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4817 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4818 applied to possible quadrangles to choose a neighbour to fuse with.
4819 Note that not all items of :class:`SMESH.FunctorType` corresponds
4820 to numerical functors.
4821 MaxAngle: a max angle between element normals at which the fusion
4822 is still performed; theMaxAngle is measured in radians.
4825 True in case of success, False otherwise.
4828 This operation can create gaps in numeration of elements.
4829 Call :meth:`RenumberElements` to remove the gaps.
4832 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4833 self.mesh.SetParameters(Parameters)
4834 if isinstance( theObject, Mesh ):
4835 theObject = theObject.GetMesh()
4836 Functor = self.smeshpyD.GetFunctor(theCriterion)
4837 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4839 def QuadToTri (self, IDsOfElements, theCriterion = None):
4841 Split quadrangles into triangles.
4844 IDsOfElements: the faces to be splitted.
4845 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4846 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4847 value, then quadrangles will be split by the smallest diagonal.
4848 Note that not all items of :class:`SMESH.FunctorType` corresponds
4849 to numerical functors.
4852 True in case of success, False otherwise.
4855 This operation can create gaps in numeration of elements.
4856 Call :meth:`RenumberElements` to remove the gaps.
4858 if IDsOfElements == []:
4859 IDsOfElements = self.GetElementsId()
4860 if theCriterion is None:
4861 theCriterion = FT_MaxElementLength2D
4862 Functor = self.smeshpyD.GetFunctor(theCriterion)
4863 return self.editor.QuadToTri(IDsOfElements, Functor)
4865 def QuadToTriObject (self, theObject, theCriterion = None):
4867 Split quadrangles into triangles.
4870 theObject: the object from which the list of elements is taken,
4871 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4872 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4873 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4874 value, then quadrangles will be split by the smallest diagonal.
4875 Note that not all items of :class:`SMESH.FunctorType` corresponds
4876 to numerical functors.
4879 True in case of success, False otherwise.
4882 This operation can create gaps in numeration of elements.
4883 Call :meth:`RenumberElements` to remove the gaps.
4885 if ( isinstance( theObject, Mesh )):
4886 theObject = theObject.GetMesh()
4887 if theCriterion is None:
4888 theCriterion = FT_MaxElementLength2D
4889 Functor = self.smeshpyD.GetFunctor(theCriterion)
4890 return self.editor.QuadToTriObject(theObject, Functor)
4892 def QuadTo4Tri (self, theElements=[]):
4894 Split each of given quadrangles into 4 triangles. A node is added at the center of
4898 theElements: the faces to be splitted. This can be either
4899 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4900 or a list of face IDs. By default all quadrangles are split
4903 This operation can create gaps in numeration of elements.
4904 Call :meth:`RenumberElements` to remove the gaps.
4906 unRegister = genObjUnRegister()
4907 if isinstance( theElements, Mesh ):
4908 theElements = theElements.mesh
4909 elif not theElements:
4910 theElements = self.mesh
4911 elif isinstance( theElements, list ):
4912 theElements = self.GetIDSource( theElements, SMESH.FACE )
4913 unRegister.set( theElements )
4914 return self.editor.QuadTo4Tri( theElements )
4916 def SplitQuad (self, IDsOfElements, Diag13):
4918 Split quadrangles into triangles.
4921 IDsOfElements: the faces to be splitted
4922 Diag13 (boolean): is used to choose a diagonal for splitting.
4925 True in case of success, False otherwise.
4928 This operation can create gaps in numeration of elements.
4929 Call :meth:`RenumberElements` to remove the gaps.
4931 if IDsOfElements == []:
4932 IDsOfElements = self.GetElementsId()
4933 return self.editor.SplitQuad(IDsOfElements, Diag13)
4935 def SplitQuadObject (self, theObject, Diag13):
4937 Split quadrangles into triangles.
4940 theObject: the object from which the list of elements is taken,
4941 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4942 Diag13 (boolean): is used to choose a diagonal for splitting.
4945 True in case of success, False otherwise.
4948 This operation can create gaps in numeration of elements.
4949 Call :meth:`RenumberElements` to remove the gaps.
4951 if ( isinstance( theObject, Mesh )):
4952 theObject = theObject.GetMesh()
4953 return self.editor.SplitQuadObject(theObject, Diag13)
4955 def BestSplit (self, IDOfQuad, theCriterion):
4957 Find a better splitting of the given quadrangle.
4960 IDOfQuad: the ID of the quadrangle to be splitted.
4961 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4962 choose a diagonal for splitting.
4963 Note that not all items of :class:`SMESH.FunctorType` corresponds
4964 to numerical functors.
4967 * 1 if 1-3 diagonal is better,
4968 * 2 if 2-4 diagonal is better,
4969 * 0 if error occurs.
4972 This operation can create gaps in numeration of elements.
4973 Call :meth:`RenumberElements` to remove the gaps.
4975 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4977 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4979 Split volumic elements into tetrahedrons
4982 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4983 method: flags passing splitting method:
4984 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4985 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4988 This operation can create gaps in numeration of elements.
4989 Call :meth:`RenumberElements` to remove the gaps.
4991 unRegister = genObjUnRegister()
4992 if isinstance( elems, Mesh ):
4993 elems = elems.GetMesh()
4994 if ( isinstance( elems, list )):
4995 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4996 unRegister.set( elems )
4997 self.editor.SplitVolumesIntoTetra(elems, method)
5000 def SplitBiQuadraticIntoLinear(self, elems=None):
5002 Split bi-quadratic elements into linear ones without creation of additional nodes:
5004 - bi-quadratic triangle will be split into 3 linear quadrangles;
5005 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
5006 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
5008 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
5009 will be split in order to keep the mesh conformal.
5012 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
5013 if None (default), all bi-quadratic elements will be split
5016 This operation can create gaps in numeration of elements.
5017 Call :meth:`RenumberElements` to remove the gaps.
5019 unRegister = genObjUnRegister()
5020 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
5021 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
5022 unRegister.set( elems )
5024 elems = [ self.GetMesh() ]
5025 if isinstance( elems, Mesh ):
5026 elems = [ elems.GetMesh() ]
5027 if not isinstance( elems, list ):
5029 self.editor.SplitBiQuadraticIntoLinear( elems )
5031 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
5032 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
5034 Split hexahedra into prisms
5037 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5038 startHexPoint: a point used to find a hexahedron for which *facetNormal*
5039 gives a normal vector defining facets to split into triangles.
5040 *startHexPoint* can be either a triple of coordinates or a vertex.
5041 facetNormal: a normal to a facet to split into triangles of a
5042 hexahedron found by *startHexPoint*.
5043 *facetNormal* can be either a triple of coordinates or an edge.
5044 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
5045 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
5046 allDomains: if :code:`False`, only hexahedra adjacent to one closest
5047 to *startHexPoint* are split, else *startHexPoint*
5048 is used to find the facet to split in all domains present in *elems*.
5051 This operation can create gaps in numeration of elements.
5052 Call :meth:`RenumberElements` to remove the gaps.
5055 unRegister = genObjUnRegister()
5056 if isinstance( elems, Mesh ):
5057 elems = elems.GetMesh()
5058 if ( isinstance( elems, list )):
5059 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5060 unRegister.set( elems )
5063 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5064 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5065 elif isinstance( startHexPoint, list ):
5066 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5069 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5070 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5071 elif isinstance( facetNormal, list ):
5072 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5075 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5077 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5079 def SplitQuadsNearTriangularFacets(self):
5081 Split quadrangle faces near triangular facets of volumes
5084 This operation can create gaps in numeration of elements.
5085 Call :meth:`RenumberElements` to remove the gaps.
5087 faces_array = self.GetElementsByType(SMESH.FACE)
5088 for face_id in faces_array:
5089 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5090 quad_nodes = self.mesh.GetElemNodes(face_id)
5091 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5092 isVolumeFound = False
5093 for node1_elem in node1_elems:
5094 if not isVolumeFound:
5095 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5096 nb_nodes = self.GetElemNbNodes(node1_elem)
5097 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5098 volume_elem = node1_elem
5099 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5100 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5101 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5102 isVolumeFound = True
5103 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5104 self.SplitQuad([face_id], False) # diagonal 2-4
5105 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5106 isVolumeFound = True
5107 self.SplitQuad([face_id], True) # diagonal 1-3
5108 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5109 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5110 isVolumeFound = True
5111 self.SplitQuad([face_id], True) # diagonal 1-3
5113 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5115 Split hexahedrons into tetrahedrons.
5117 This operation uses :doc:`pattern_mapping` functionality for splitting.
5120 theObject: the object from which the list of hexahedrons is taken;
5121 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5122 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5123 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5124 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5125 key-point will be mapped into *theNode001*-th node of each volume.
5126 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5129 True in case of success, False otherwise.
5132 This operation can create gaps in numeration of elements.
5133 Call :meth:`RenumberElements` to remove the gaps.
5141 # (0,0,1) 4.---------.7 * |
5148 # (0,0,0) 0.---------.3
5149 pattern_tetra = "!!! Nb of points: \n 8 \n\
5159 !!! Indices of points of 6 tetras: \n\
5167 pattern = self.smeshpyD.GetPattern()
5168 isDone = pattern.LoadFromFile(pattern_tetra)
5170 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5173 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5174 isDone = pattern.MakeMesh(self.mesh, False, False)
5175 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5177 # split quafrangle faces near triangular facets of volumes
5178 self.SplitQuadsNearTriangularFacets()
5182 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5184 Split hexahedrons into prisms.
5186 Uses the :doc:`pattern_mapping` functionality for splitting.
5189 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5190 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5191 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5192 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5193 will be mapped into the *theNode001* -th node of each volume.
5194 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5197 True in case of success, False otherwise.
5200 This operation can create gaps in numeration of elements.
5201 Call :meth:`RenumberElements` to remove the gaps.
5203 # Pattern: 5.---------.6
5208 # (0,0,1) 4.---------.7 |
5215 # (0,0,0) 0.---------.3
5216 pattern_prism = "!!! Nb of points: \n 8 \n\
5226 !!! Indices of points of 2 prisms: \n\
5230 pattern = self.smeshpyD.GetPattern()
5231 isDone = pattern.LoadFromFile(pattern_prism)
5233 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5236 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5237 isDone = pattern.MakeMesh(self.mesh, False, False)
5238 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5240 # Split quafrangle faces near triangular facets of volumes
5241 self.SplitQuadsNearTriangularFacets()
5245 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5246 MaxNbOfIterations, MaxAspectRatio, Method):
5251 IDsOfElements: the list if ids of elements to smooth
5252 IDsOfFixedNodes: the list of ids of fixed nodes.
5253 Note that nodes built on edges and boundary nodes are always fixed.
5254 MaxNbOfIterations: the maximum number of iterations
5255 MaxAspectRatio: varies in range [1.0, inf]
5256 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5257 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5260 True in case of success, False otherwise.
5263 if IDsOfElements == []:
5264 IDsOfElements = self.GetElementsId()
5265 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5266 self.mesh.SetParameters(Parameters)
5267 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5268 MaxNbOfIterations, MaxAspectRatio, Method)
5270 def SmoothObject(self, theObject, IDsOfFixedNodes,
5271 MaxNbOfIterations, MaxAspectRatio, Method):
5273 Smooth elements which belong to the given object
5276 theObject: the object to smooth
5277 IDsOfFixedNodes: the list of ids of fixed nodes.
5278 Note that nodes built on edges and boundary nodes are always fixed.
5279 MaxNbOfIterations: the maximum number of iterations
5280 MaxAspectRatio: varies in range [1.0, inf]
5281 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5282 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5285 True in case of success, False otherwise.
5288 if ( isinstance( theObject, Mesh )):
5289 theObject = theObject.GetMesh()
5290 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5291 MaxNbOfIterations, MaxAspectRatio, Method)
5293 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5294 MaxNbOfIterations, MaxAspectRatio, Method):
5296 Parametrically smooth the given elements
5299 IDsOfElements: the list if ids of elements to smooth
5300 IDsOfFixedNodes: the list of ids of fixed nodes.
5301 Note that nodes built on edges and boundary nodes are always fixed.
5302 MaxNbOfIterations: the maximum number of iterations
5303 MaxAspectRatio: varies in range [1.0, inf]
5304 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5305 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5308 True in case of success, False otherwise.
5311 if IDsOfElements == []:
5312 IDsOfElements = self.GetElementsId()
5313 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5314 self.mesh.SetParameters(Parameters)
5315 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5316 MaxNbOfIterations, MaxAspectRatio, Method)
5318 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5319 MaxNbOfIterations, MaxAspectRatio, Method):
5321 Parametrically smooth the elements which belong to the given object
5324 theObject: the object to smooth
5325 IDsOfFixedNodes: the list of ids of fixed nodes.
5326 Note that nodes built on edges and boundary nodes are always fixed.
5327 MaxNbOfIterations: the maximum number of iterations
5328 MaxAspectRatio: varies in range [1.0, inf]
5329 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5330 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5333 True in case of success, False otherwise.
5336 if ( isinstance( theObject, Mesh )):
5337 theObject = theObject.GetMesh()
5338 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5339 MaxNbOfIterations, MaxAspectRatio, Method)
5341 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5343 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5344 them with quadratic with the same id.
5347 theForce3d: method of new node creation:
5349 * False - the medium node lies at the geometrical entity from which the mesh element is built
5350 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5351 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5352 theToBiQuad: If True, converts the mesh to bi-quadratic
5355 :class:`SMESH.ComputeError` which can hold a warning
5358 If *theSubMesh* is provided, the mesh can become non-conformal
5361 This operation can create gaps in numeration of nodes or elements.
5362 Call :meth:`RenumberElements` to remove the gaps.
5365 if isinstance( theSubMesh, Mesh ):
5366 theSubMesh = theSubMesh.mesh
5368 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5371 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5373 self.editor.ConvertToQuadratic(theForce3d)
5374 error = self.editor.GetLastError()
5375 if error and error.comment:
5376 print(error.comment)
5379 def ConvertFromQuadratic(self, theSubMesh=None):
5381 Convert the mesh from quadratic to ordinary,
5382 deletes old quadratic elements,
5383 replacing them with ordinary mesh elements with the same id.
5386 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5389 If *theSubMesh* is provided, the mesh can become non-conformal
5392 This operation can create gaps in numeration of nodes or elements.
5393 Call :meth:`RenumberElements` to remove the gaps.
5397 self.editor.ConvertFromQuadraticObject(theSubMesh)
5399 return self.editor.ConvertFromQuadratic()
5401 def Make2DMeshFrom3D(self):
5403 Create 2D mesh as skin on boundary faces of a 3D mesh
5406 True if operation has been completed successfully, False otherwise
5409 return self.editor.Make2DMeshFrom3D()
5411 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5412 toCopyElements=False, toCopyExistingBondary=False):
5414 Create missing boundary elements
5417 elements: elements whose boundary is to be checked:
5418 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5419 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5420 dimension: defines type of boundary elements to create, either of
5421 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5422 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5423 groupName: a name of group to store created boundary elements in,
5424 "" means not to create the group
5425 meshName: a name of new mesh to store created boundary elements in,
5426 "" means not to create the new mesh
5427 toCopyElements: if True, the checked elements will be copied into
5428 the new mesh else only boundary elements will be copied into the new mesh
5429 toCopyExistingBondary: if True, not only new but also pre-existing
5430 boundary elements will be copied into the new mesh
5433 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5436 unRegister = genObjUnRegister()
5437 if isinstance( elements, Mesh ):
5438 elements = elements.GetMesh()
5439 if ( isinstance( elements, list )):
5440 elemType = SMESH.ALL
5441 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5442 elements = self.editor.MakeIDSource(elements, elemType)
5443 unRegister.set( elements )
5444 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5445 toCopyElements,toCopyExistingBondary)
5446 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5449 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5450 toCopyAll=False, groups=[]):
5452 Create missing boundary elements around either the whole mesh or
5456 dimension: defines type of boundary elements to create, either of
5457 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5458 groupName: a name of group to store all boundary elements in,
5459 "" means not to create the group
5460 meshName: a name of a new mesh, which is a copy of the initial
5461 mesh + created boundary elements; "" means not to create the new mesh
5462 toCopyAll: if True, the whole initial mesh will be copied into
5463 the new mesh else only boundary elements will be copied into the new mesh
5464 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5467 tuple( long, mesh, group )
5468 - long - number of added boundary elements
5469 - mesh - the :class:`Mesh` where elements were added to
5470 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5473 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5475 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5476 return nb, mesh, group
5478 def RenumberNodes(self):
5480 Renumber mesh nodes to remove unused node IDs
5482 self.editor.RenumberNodes()
5484 def RenumberElements(self):
5486 Renumber mesh elements to remove unused element IDs
5488 self.editor.RenumberElements()
5490 def _getIdSourceList(self, arg, idType, unRegister):
5492 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5494 if arg and isinstance( arg, list ):
5495 if isinstance( arg[0], int ):
5496 arg = self.GetIDSource( arg, idType )
5497 unRegister.set( arg )
5498 elif isinstance( arg[0], Mesh ):
5499 arg[0] = arg[0].GetMesh()
5500 elif isinstance( arg, Mesh ):
5502 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5506 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5507 MakeGroups=False, TotalAngle=False):
5509 Generate new elements by rotation of the given elements and nodes around the axis
5512 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5513 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5514 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5515 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5516 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5517 which defines angle in degrees
5518 NbOfSteps: the number of steps
5519 Tolerance: tolerance
5520 MakeGroups: forces the generation of new groups from existing ones
5521 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5522 of all steps, else - size of each step
5525 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5528 unRegister = genObjUnRegister()
5529 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5530 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5531 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5533 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5534 Axis = self.smeshpyD.GetAxisStruct( Axis )
5535 if isinstance( Axis, list ):
5536 Axis = SMESH.AxisStruct( *Axis )
5538 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5539 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5540 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5541 self.mesh.SetParameters(Parameters)
5542 if TotalAngle and NbOfSteps:
5543 AngleInRadians /= NbOfSteps
5544 return self.editor.RotationSweepObjects( nodes, edges, faces,
5545 Axis, AngleInRadians,
5546 NbOfSteps, Tolerance, MakeGroups)
5548 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5549 MakeGroups=False, TotalAngle=False):
5551 Generate new elements by rotation of the elements around the axis
5554 IDsOfElements: the list of ids of elements to sweep
5555 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5556 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5557 NbOfSteps: the number of steps
5558 Tolerance: tolerance
5559 MakeGroups: forces the generation of new groups from existing ones
5560 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5561 of all steps, else - size of each step
5564 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5567 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5568 AngleInRadians, NbOfSteps, Tolerance,
5569 MakeGroups, TotalAngle)
5571 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5572 MakeGroups=False, TotalAngle=False):
5574 Generate new elements by rotation of the elements of object around the axis
5575 theObject object which elements should be sweeped.
5576 It can be a mesh, a sub mesh or a group.
5579 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5580 AngleInRadians: the angle of Rotation
5581 NbOfSteps: number of steps
5582 Tolerance: tolerance
5583 MakeGroups: forces the generation of new groups from existing ones
5584 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5585 of all steps, else - size of each step
5588 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5591 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5592 AngleInRadians, NbOfSteps, Tolerance,
5593 MakeGroups, TotalAngle )
5595 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5596 MakeGroups=False, TotalAngle=False):
5598 Generate new elements by rotation of the elements of object around the axis
5599 theObject object which elements should be sweeped.
5600 It can be a mesh, a sub mesh or a group.
5603 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5604 AngleInRadians: the angle of Rotation
5605 NbOfSteps: number of steps
5606 Tolerance: tolerance
5607 MakeGroups: forces the generation of new groups from existing ones
5608 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5609 of all steps, else - size of each step
5612 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5613 empty list otherwise
5616 return self.RotationSweepObjects([],theObject,[], Axis,
5617 AngleInRadians, NbOfSteps, Tolerance,
5618 MakeGroups, TotalAngle)
5620 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5621 MakeGroups=False, TotalAngle=False):
5623 Generate new elements by rotation of the elements of object around the axis
5624 theObject object which elements should be sweeped.
5625 It can be a mesh, a sub mesh or a group.
5628 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5629 AngleInRadians: the angle of Rotation
5630 NbOfSteps: number of steps
5631 Tolerance: tolerance
5632 MakeGroups: forces the generation of new groups from existing ones
5633 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5634 of all steps, else - size of each step
5637 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5640 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5641 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5643 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5644 scaleFactors=[], linearVariation=False, basePoint=[],
5645 angles=[], anglesVariation=False):
5647 Generate new elements by extrusion of the given elements and nodes
5650 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5651 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5652 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5653 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5654 the direction and value of extrusion for one step (the total extrusion
5655 length will be NbOfSteps * ||StepVector||)
5656 NbOfSteps: the number of steps
5657 MakeGroups: forces the generation of new groups from existing ones
5658 scaleFactors: optional scale factors to apply during extrusion
5659 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5660 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5661 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5662 nodes and elements being extruded is used as the scaling center.
5665 - a list of tree components of the point or
5668 angles: list of angles in radians. Nodes at each extrusion step are rotated
5669 around *basePoint*, additionally to previous steps.
5670 anglesVariation: forces the computation of rotation angles as linear
5671 variation of the given *angles* along path steps
5673 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5675 Example: :ref:`tui_extrusion`
5677 unRegister = genObjUnRegister()
5678 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5679 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5680 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5682 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5683 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5684 if isinstance( StepVector, list ):
5685 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5687 if isinstance( basePoint, int):
5688 xyz = self.GetNodeXYZ( basePoint )
5690 raise RuntimeError("Invalid node ID: %s" % basePoint)
5692 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5693 basePoint = self.geompyD.PointCoordinates( basePoint )
5695 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5696 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5697 angles,angleParameters,hasVars = ParseAngles(angles)
5698 Parameters = StepVector.PS.parameters + var_separator + \
5699 Parameters + var_separator + \
5700 scaleParameters + var_separator + angleParameters
5701 self.mesh.SetParameters(Parameters)
5703 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5704 StepVector, NbOfSteps, MakeGroups,
5705 scaleFactors, linearVariation, basePoint,
5706 angles, anglesVariation )
5709 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5711 Generate new elements by extrusion of the elements with given ids
5714 IDsOfElements: the list of ids of elements or nodes for extrusion
5715 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5716 the direction and value of extrusion for one step (the total extrusion
5717 length will be NbOfSteps * ||StepVector||)
5718 NbOfSteps: the number of steps
5719 MakeGroups: forces the generation of new groups from existing ones
5720 IsNodes: is True if elements with given ids are nodes
5723 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5725 Example: :ref:`tui_extrusion`
5728 if IsNodes: n = IDsOfElements
5729 else : e,f, = IDsOfElements,IDsOfElements
5730 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5732 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5733 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5735 Generate new elements by extrusion along the normal to a discretized surface or wire
5738 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5739 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5740 StepSize: length of one extrusion step (the total extrusion
5741 length will be *NbOfSteps* *StepSize*).
5742 NbOfSteps: number of extrusion steps.
5743 ByAverageNormal: if True each node is translated by *StepSize*
5744 along the average of the normal vectors to the faces sharing the node;
5745 else each node is translated along the same average normal till
5746 intersection with the plane got by translation of the face sharing
5747 the node along its own normal by *StepSize*.
5748 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5749 for every node of *Elements*.
5750 MakeGroups: forces generation of new groups from existing ones.
5751 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5752 is not yet implemented. This parameter is used if *Elements* contains
5753 both faces and edges, i.e. *Elements* is a Mesh.
5756 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5757 empty list otherwise.
5758 Example: :ref:`tui_extrusion`
5761 unRegister = genObjUnRegister()
5762 if isinstance( Elements, Mesh ):
5763 Elements = [ Elements.GetMesh() ]
5764 if isinstance( Elements, list ):
5766 raise RuntimeError("Elements empty!")
5767 if isinstance( Elements[0], Mesh ):
5768 Elements = [ Elements[0].GetMesh() ]
5769 if isinstance( Elements[0], int ):
5770 Elements = self.GetIDSource( Elements, SMESH.ALL )
5771 unRegister.set( Elements )
5772 if not isinstance( Elements, list ):
5773 Elements = [ Elements ]
5774 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5775 self.mesh.SetParameters(Parameters)
5776 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5777 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5779 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5781 Generate new elements by extrusion of the elements or nodes which belong to the object
5784 theObject: the object whose elements or nodes should be processed.
5785 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5786 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5787 the direction and value of extrusion for one step (the total extrusion
5788 length will be NbOfSteps * ||StepVector||)
5789 NbOfSteps: the number of steps
5790 MakeGroups: forces the generation of new groups from existing ones
5791 IsNodes: is True if elements to extrude are nodes
5794 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5795 Example: :ref:`tui_extrusion`
5799 if IsNodes: n = theObject
5800 else : e,f, = theObject,theObject
5801 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5803 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5805 Generate new elements by extrusion of edges which belong to the object
5808 theObject: object whose 1D elements should be processed.
5809 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5810 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5811 the direction and value of extrusion for one step (the total extrusion
5812 length will be NbOfSteps * ||StepVector||)
5813 NbOfSteps: the number of steps
5814 MakeGroups: to generate new groups from existing ones
5817 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5818 Example: :ref:`tui_extrusion`
5821 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5823 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5825 Generate new elements by extrusion of faces which belong to the object
5828 theObject: object whose 2D elements should be processed.
5829 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5830 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5831 the direction and value of extrusion for one step (the total extrusion
5832 length will be NbOfSteps * ||StepVector||)
5833 NbOfSteps: the number of steps
5834 MakeGroups: forces the generation of new groups from existing ones
5837 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5838 Example: :ref:`tui_extrusion`
5841 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5843 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5844 ExtrFlags, SewTolerance, MakeGroups=False):
5846 Generate new elements by extrusion of the elements with given ids
5849 IDsOfElements: is ids of elements
5850 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5851 the direction and value of extrusion for one step (the total extrusion
5852 length will be NbOfSteps * ||StepVector||)
5853 NbOfSteps: the number of steps
5854 ExtrFlags: sets flags for extrusion
5855 SewTolerance: uses for comparing locations of nodes if flag
5856 EXTRUSION_FLAG_SEW is set
5857 MakeGroups: forces the generation of new groups from existing ones
5860 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5863 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5864 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5865 if isinstance( StepVector, list ):
5866 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5867 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5868 ExtrFlags, SewTolerance, MakeGroups)
5870 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5871 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5872 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5873 ScaleFactors=[], ScalesVariation=False):
5875 Generate new elements by extrusion of the given elements and nodes along the path.
5876 The path of extrusion must be a meshed edge.
5879 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5880 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5881 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5882 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5883 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
5884 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5885 HasAngles: not used obsolete
5886 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5887 around *basePoint*, additionally to previous steps.
5888 LinearVariation: forces the computation of rotation angles as linear
5889 variation of the given Angles along path steps
5890 HasRefPoint: allows using the reference point
5891 RefPoint: optional scaling and rotation center (mass center of the extruded
5892 elements by default). The User can specify any point as the Reference Point.
5893 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5894 MakeGroups: forces the generation of new groups from existing ones
5895 ScaleFactors: optional scale factors to apply during extrusion
5896 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5897 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5900 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5901 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5902 Example: :ref:`tui_extrusion_along_path`
5905 unRegister = genObjUnRegister()
5906 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5907 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5908 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5910 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5911 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5912 if isinstance( RefPoint, list ):
5913 if not RefPoint: RefPoint = [0,0,0]
5914 RefPoint = SMESH.PointStruct( *RefPoint )
5915 if isinstance( PathObject, Mesh ):
5916 PathObject = PathObject.GetMesh()
5917 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5918 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5919 Parameters = AnglesParameters + var_separator + \
5920 RefPoint.parameters + var_separator + ScalesParameters
5921 self.mesh.SetParameters(Parameters)
5922 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5923 PathObject, PathShape, NodeStart,
5924 HasAngles, Angles, LinearVariation,
5925 HasRefPoint, RefPoint, MakeGroups,
5926 ScaleFactors, ScalesVariation)
5928 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5929 HasAngles=False, Angles=[], LinearVariation=False,
5930 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5931 ElemType=SMESH.FACE):
5933 Generate new elements by extrusion of the given elements.
5934 The path of extrusion must be a meshed edge.
5937 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5938 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5939 NodeStart: the start node from Path. Defines the direction of extrusion
5940 HasAngles: not used obsolete
5941 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5942 around *basePoint*, additionally to previous steps.
5943 LinearVariation: forces the computation of rotation angles as linear
5944 variation of the given Angles along path steps
5945 HasRefPoint: allows using the reference point
5946 RefPoint: the reference point around which the elements are rotated (the mass
5947 center of the elements by default).
5948 The User can specify any point as the Reference Point.
5949 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5950 MakeGroups: forces the generation of new groups from existing ones
5951 ElemType: type of elements for extrusion (if param Base is a mesh)
5954 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5955 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5956 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5958 Example: :ref:`tui_extrusion_along_path`
5962 if ElemType == SMESH.NODE: n = Base
5963 if ElemType == SMESH.EDGE: e = Base
5964 if ElemType == SMESH.FACE: f = Base
5965 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5966 HasAngles, Angles, LinearVariation,
5967 HasRefPoint, RefPoint, MakeGroups)
5968 if MakeGroups: return gr,er
5971 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5972 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5973 MakeGroups=False, LinearVariation=False):
5975 Generate new elements by extrusion of the given elements.
5976 The path of extrusion must be a meshed edge.
5979 IDsOfElements: ids of elements
5980 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5981 PathShape: shape (edge) defines the sub-mesh for the path
5982 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5983 HasAngles: not used obsolete
5984 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5985 around *basePoint*, additionally to previous steps.
5986 HasRefPoint: allows using the reference point
5987 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5988 The User can specify any point as the Reference Point.
5989 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5990 MakeGroups: forces the generation of new groups from existing ones
5991 LinearVariation: forces the computation of rotation angles as linear
5992 variation of the given Angles along path steps
5995 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5996 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5997 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5998 Example: :ref:`tui_extrusion_along_path`
6001 if not IDsOfElements:
6002 IDsOfElements = [ self.GetMesh() ]
6003 n,e,f = [],IDsOfElements,IDsOfElements
6004 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
6005 NodeStart, HasAngles, Angles,
6007 HasRefPoint, RefPoint, MakeGroups)
6008 if MakeGroups: return gr,er
6011 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
6012 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6013 MakeGroups=False, LinearVariation=False):
6015 Generate new elements by extrusion of the elements which belong to the object.
6016 The path of extrusion must be a meshed edge.
6019 theObject: the object whose elements should be processed.
6020 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6021 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6022 PathShape: shape (edge) defines the sub-mesh for the path
6023 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6024 HasAngles: not used obsolete
6025 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6026 around *basePoint*, additionally to previous steps.
6027 HasRefPoint: allows using the reference point
6028 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6029 The User can specify any point as the Reference Point.
6030 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6031 MakeGroups: forces the generation of new groups from existing ones
6032 LinearVariation: forces the computation of rotation angles as linear
6033 variation of the given Angles along path steps
6036 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6037 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6038 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6039 Example: :ref:`tui_extrusion_along_path`
6042 n,e,f = [],theObject,theObject
6043 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6044 HasAngles, Angles, LinearVariation,
6045 HasRefPoint, RefPoint, MakeGroups)
6046 if MakeGroups: return gr,er
6049 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
6050 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6051 MakeGroups=False, LinearVariation=False):
6053 Generate new elements by extrusion of mesh segments which belong to the object.
6054 The path of extrusion must be a meshed edge.
6057 theObject: the object whose 1D elements should be processed.
6058 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6059 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6060 PathShape: shape (edge) defines the sub-mesh for the path
6061 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6062 HasAngles: not used obsolete
6063 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6064 around *basePoint*, additionally to previous steps.
6065 HasRefPoint: allows using the reference point
6066 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6067 The User can specify any point as the Reference Point.
6068 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6069 MakeGroups: forces the generation of new groups from existing ones
6070 LinearVariation: forces the computation of rotation angles as linear
6071 variation of the given Angles along path steps
6074 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6075 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6076 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6077 Example: :ref:`tui_extrusion_along_path`
6080 n,e,f = [],theObject,[]
6081 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6082 HasAngles, Angles, LinearVariation,
6083 HasRefPoint, RefPoint, MakeGroups)
6084 if MakeGroups: return gr,er
6087 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6088 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6089 MakeGroups=False, LinearVariation=False):
6091 Generate new elements by extrusion of faces which belong to the object.
6092 The path of extrusion must be a meshed edge.
6095 theObject: the object whose 2D elements should be processed.
6096 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6097 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6098 PathShape: shape (edge) defines the sub-mesh for the path
6099 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6100 HasAngles: not used obsolete
6101 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6102 around *basePoint*, additionally to previous steps.
6103 HasRefPoint: allows using the reference point
6104 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6105 The User can specify any point as the Reference Point.
6106 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6107 MakeGroups: forces the generation of new groups from existing ones
6108 LinearVariation: forces the computation of rotation angles as linear
6109 variation of the given Angles along path steps
6112 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6113 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6114 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6115 Example: :ref:`tui_extrusion_along_path`
6118 n,e,f = [],[],theObject
6119 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6120 HasAngles, Angles, LinearVariation,
6121 HasRefPoint, RefPoint, MakeGroups)
6122 if MakeGroups: return gr,er
6125 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6127 Create a symmetrical copy of mesh elements
6130 IDsOfElements: list of elements ids
6131 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6132 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6133 If the *Mirror* is a geom object this parameter is unnecessary
6134 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6135 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6138 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6141 if IDsOfElements == []:
6142 IDsOfElements = self.GetElementsId()
6143 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6144 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6145 theMirrorType = Mirror._mirrorType
6147 self.mesh.SetParameters(Mirror.parameters)
6148 if Copy and MakeGroups:
6149 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6150 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6153 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6155 Create a new mesh by a symmetrical copy of mesh elements
6158 IDsOfElements: the list of elements ids
6159 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6160 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6161 If the *Mirror* is a geom object this parameter is unnecessary
6162 MakeGroups: to generate new groups from existing ones
6163 NewMeshName: a name of the new mesh to create
6166 instance of class :class:`Mesh`
6169 if IDsOfElements == []:
6170 IDsOfElements = self.GetElementsId()
6171 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6172 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6173 theMirrorType = Mirror._mirrorType
6175 self.mesh.SetParameters(Mirror.parameters)
6176 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6177 MakeGroups, NewMeshName)
6178 return Mesh(self.smeshpyD,self.geompyD,mesh)
6180 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6182 Create a symmetrical copy of the object
6185 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6186 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6187 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6188 If the *Mirror* is a geom object this parameter is unnecessary
6189 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6190 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6193 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6196 if ( isinstance( theObject, Mesh )):
6197 theObject = theObject.GetMesh()
6198 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6199 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6200 theMirrorType = Mirror._mirrorType
6202 self.mesh.SetParameters(Mirror.parameters)
6203 if Copy and MakeGroups:
6204 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6205 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6208 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6210 Create a new mesh by a symmetrical copy of the object
6213 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6214 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6215 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6216 If the *Mirror* is a geom object this parameter is unnecessary
6217 MakeGroups: forces the generation of new groups from existing ones
6218 NewMeshName: the name of the new mesh to create
6221 instance of class :class:`Mesh`
6224 if ( isinstance( theObject, Mesh )):
6225 theObject = theObject.GetMesh()
6226 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6227 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6228 theMirrorType = Mirror._mirrorType
6230 self.mesh.SetParameters(Mirror.parameters)
6231 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6232 MakeGroups, NewMeshName)
6233 return Mesh( self.smeshpyD,self.geompyD,mesh )
6235 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6237 Translate the elements
6240 IDsOfElements: list of elements ids
6241 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6242 Copy: allows copying the translated elements
6243 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6246 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6249 if IDsOfElements == []:
6250 IDsOfElements = self.GetElementsId()
6251 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6252 Vector = self.smeshpyD.GetDirStruct(Vector)
6253 if isinstance( Vector, list ):
6254 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6255 self.mesh.SetParameters(Vector.PS.parameters)
6256 if Copy and MakeGroups:
6257 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6258 self.editor.Translate(IDsOfElements, Vector, Copy)
6261 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6263 Create a new mesh of translated elements
6266 IDsOfElements: list of elements ids
6267 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6268 MakeGroups: forces the generation of new groups from existing ones
6269 NewMeshName: the name of the newly created mesh
6272 instance of class :class:`Mesh`
6275 if IDsOfElements == []:
6276 IDsOfElements = self.GetElementsId()
6277 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6278 Vector = self.smeshpyD.GetDirStruct(Vector)
6279 if isinstance( Vector, list ):
6280 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6281 self.mesh.SetParameters(Vector.PS.parameters)
6282 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6283 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6285 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6287 Translate the object
6290 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6291 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6292 Copy: allows copying the translated elements
6293 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6296 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6299 if ( isinstance( theObject, Mesh )):
6300 theObject = theObject.GetMesh()
6301 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6302 Vector = self.smeshpyD.GetDirStruct(Vector)
6303 if isinstance( Vector, list ):
6304 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6305 self.mesh.SetParameters(Vector.PS.parameters)
6306 if Copy and MakeGroups:
6307 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6308 self.editor.TranslateObject(theObject, Vector, Copy)
6311 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6313 Create a new mesh from the translated object
6316 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6317 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6318 MakeGroups: forces the generation of new groups from existing ones
6319 NewMeshName: the name of the newly created mesh
6322 instance of class :class:`Mesh`
6325 if isinstance( theObject, Mesh ):
6326 theObject = theObject.GetMesh()
6327 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6328 Vector = self.smeshpyD.GetDirStruct(Vector)
6329 if isinstance( Vector, list ):
6330 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6331 self.mesh.SetParameters(Vector.PS.parameters)
6332 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6333 return Mesh( self.smeshpyD, self.geompyD, mesh )
6337 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6342 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6343 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6344 theScaleFact: list of 1-3 scale factors for axises
6345 Copy: allows copying the translated elements
6346 MakeGroups: forces the generation of new groups from existing
6350 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6351 empty list otherwise
6353 unRegister = genObjUnRegister()
6354 if ( isinstance( theObject, Mesh )):
6355 theObject = theObject.GetMesh()
6356 if ( isinstance( theObject, list )):
6357 theObject = self.GetIDSource(theObject, SMESH.ALL)
6358 unRegister.set( theObject )
6359 if ( isinstance( thePoint, list )):
6360 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6361 if ( isinstance( theScaleFact, float )):
6362 theScaleFact = [theScaleFact]
6363 if ( isinstance( theScaleFact, int )):
6364 theScaleFact = [ float(theScaleFact)]
6366 self.mesh.SetParameters(thePoint.parameters)
6368 if Copy and MakeGroups:
6369 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6370 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6373 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6375 Create a new mesh from the translated object
6378 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6379 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6380 theScaleFact: list of 1-3 scale factors for axises
6381 MakeGroups: forces the generation of new groups from existing ones
6382 NewMeshName: the name of the newly created mesh
6385 instance of class :class:`Mesh`
6387 unRegister = genObjUnRegister()
6388 if (isinstance(theObject, Mesh)):
6389 theObject = theObject.GetMesh()
6390 if ( isinstance( theObject, list )):
6391 theObject = self.GetIDSource(theObject,SMESH.ALL)
6392 unRegister.set( theObject )
6393 if ( isinstance( thePoint, list )):
6394 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6395 if ( isinstance( theScaleFact, float )):
6396 theScaleFact = [theScaleFact]
6397 if ( isinstance( theScaleFact, int )):
6398 theScaleFact = [ float(theScaleFact)]
6400 self.mesh.SetParameters(thePoint.parameters)
6401 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6402 MakeGroups, NewMeshName)
6403 return Mesh( self.smeshpyD, self.geompyD, mesh )
6407 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6412 IDsOfElements: list of elements ids
6413 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6414 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6415 Copy: allows copying the rotated elements
6416 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6419 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6423 if IDsOfElements == []:
6424 IDsOfElements = self.GetElementsId()
6425 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6426 Axis = self.smeshpyD.GetAxisStruct(Axis)
6427 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6428 Parameters = Axis.parameters + var_separator + Parameters
6429 self.mesh.SetParameters(Parameters)
6430 if Copy and MakeGroups:
6431 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6432 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6435 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6437 Create a new mesh of rotated elements
6440 IDsOfElements: list of element ids
6441 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6442 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6443 MakeGroups: forces the generation of new groups from existing ones
6444 NewMeshName: the name of the newly created mesh
6447 instance of class :class:`Mesh`
6450 if IDsOfElements == []:
6451 IDsOfElements = self.GetElementsId()
6452 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6453 Axis = self.smeshpyD.GetAxisStruct(Axis)
6454 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6455 Parameters = Axis.parameters + var_separator + Parameters
6456 self.mesh.SetParameters(Parameters)
6457 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6458 MakeGroups, NewMeshName)
6459 return Mesh( self.smeshpyD, self.geompyD, mesh )
6461 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6466 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6467 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6468 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6469 Copy: allows copying the rotated elements
6470 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6473 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6476 if (isinstance(theObject, Mesh)):
6477 theObject = theObject.GetMesh()
6478 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6479 Axis = self.smeshpyD.GetAxisStruct(Axis)
6480 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6481 Parameters = Axis.parameters + ":" + Parameters
6482 self.mesh.SetParameters(Parameters)
6483 if Copy and MakeGroups:
6484 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6485 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6488 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6490 Create a new mesh from the rotated object
6493 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6494 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6495 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6496 MakeGroups: forces the generation of new groups from existing ones
6497 NewMeshName: the name of the newly created mesh
6500 instance of class :class:`Mesh`
6503 if (isinstance( theObject, Mesh )):
6504 theObject = theObject.GetMesh()
6505 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6506 Axis = self.smeshpyD.GetAxisStruct(Axis)
6507 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6508 Parameters = Axis.parameters + ":" + Parameters
6509 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6510 MakeGroups, NewMeshName)
6511 self.mesh.SetParameters(Parameters)
6512 return Mesh( self.smeshpyD, self.geompyD, mesh )
6514 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6516 Create an offset mesh from the given 2D object
6519 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6520 theValue (float): signed offset size
6521 MakeGroups (boolean): forces the generation of new groups from existing ones
6522 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6523 False means to remove original elements.
6524 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6527 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6530 if isinstance( theObject, Mesh ):
6531 theObject = theObject.GetMesh()
6532 theValue,Parameters,hasVars = ParseParameters(Value)
6533 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6534 self.mesh.SetParameters(Parameters)
6536 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6539 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6541 Find groups of adjacent nodes within Tolerance.
6544 Tolerance (float): the value of tolerance
6545 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6546 corner and medium nodes in separate groups thus preventing
6547 their further merge.
6550 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6553 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6555 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6556 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6558 Find groups of adjacent nodes within Tolerance.
6561 Tolerance: the value of tolerance
6562 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6563 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6564 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6565 corner and medium nodes in separate groups thus preventing
6566 their further merge.
6569 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6572 unRegister = genObjUnRegister()
6573 if not isinstance( SubMeshOrGroup, list ):
6574 SubMeshOrGroup = [ SubMeshOrGroup ]
6575 for i,obj in enumerate( SubMeshOrGroup ):
6576 if isinstance( obj, Mesh ):
6577 SubMeshOrGroup = [ obj.GetMesh() ]
6579 if isinstance( obj, int ):
6580 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6581 unRegister.set( SubMeshOrGroup )
6584 if not isinstance( exceptNodes, list ):
6585 exceptNodes = [ exceptNodes ]
6586 if exceptNodes and isinstance( exceptNodes[0], int ):
6587 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6588 unRegister.set( exceptNodes )
6590 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6591 exceptNodes, SeparateCornerAndMediumNodes)
6593 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6598 GroupsOfNodes: a list of groups of nodes IDs for merging.
6599 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6600 in all elements and mesh groups by nodes 1 and 25 correspondingly
6601 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6602 If *NodesToKeep* does not include a node to keep for some group to merge,
6603 then the first node in the group is kept.
6604 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6608 This operation can create gaps in numeration of nodes or elements.
6609 Call :meth:`RenumberElements` to remove the gaps.
6611 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6613 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6615 Find the elements built on the same nodes.
6618 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6619 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6623 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6626 unRegister = genObjUnRegister()
6627 if MeshOrSubMeshOrGroup is None:
6628 MeshOrSubMeshOrGroup = [ self.mesh ]
6629 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6630 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6631 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6632 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6633 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6634 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6635 unRegister.set( MeshOrSubMeshOrGroup )
6636 for item in MeshOrSubMeshOrGroup:
6637 if isinstance( item, Mesh ):
6638 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6640 if not isinstance( exceptElements, list ):
6641 exceptElements = [ exceptElements ]
6642 if exceptElements and isinstance( exceptElements[0], int ):
6643 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6644 unRegister.set( exceptElements )
6646 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6648 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6650 Merge elements in each given group.
6653 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6654 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6655 replaced in all mesh groups by elements 1 and 25)
6656 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6657 If *ElementsToKeep* does not include an element to keep for some group to merge,
6658 then the first element in the group is kept.
6661 This operation can create gaps in numeration of elements.
6662 Call :meth:`RenumberElements` to remove the gaps.
6665 unRegister = genObjUnRegister()
6667 if not isinstance( ElementsToKeep, list ):
6668 ElementsToKeep = [ ElementsToKeep ]
6669 if isinstance( ElementsToKeep[0], int ):
6670 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6671 unRegister.set( ElementsToKeep )
6673 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6675 def MergeEqualElements(self):
6677 Leave one element and remove all other elements built on the same nodes.
6680 This operation can create gaps in numeration of elements.
6681 Call :meth:`RenumberElements` to remove the gaps.
6684 self.editor.MergeEqualElements()
6686 def FindFreeBorders(self, ClosedOnly=True):
6688 Returns all or only closed free borders
6691 list of SMESH.FreeBorder's
6694 return self.editor.FindFreeBorders( ClosedOnly )
6696 def FillHole(self, holeNodes, groupName=""):
6698 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6701 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6702 must describe all sequential nodes of the hole border. The first and the last
6703 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6704 groupName (string): name of a group to add new faces
6706 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6710 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6711 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6712 if not isinstance( holeNodes, SMESH.FreeBorder ):
6713 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6714 return self.editor.FillHole( holeNodes, groupName )
6716 def FindCoincidentFreeBorders (self, tolerance=0.):
6718 Return groups of FreeBorder's coincident within the given tolerance.
6721 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6722 size of elements adjacent to free borders being compared is used.
6725 SMESH.CoincidentFreeBorders structure
6728 return self.editor.FindCoincidentFreeBorders( tolerance )
6730 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6732 Sew FreeBorder's of each group
6735 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6736 where each enclosed list contains node IDs of a group of coincident free
6737 borders such that each consequent triple of IDs within a group describes
6738 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6739 last node of a border.
6740 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6741 groups of coincident free borders, each group including two borders.
6742 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6743 polygons if a node of opposite border falls on a face edge, else such
6744 faces are split into several ones.
6745 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6746 polyhedra if a node of opposite border falls on a volume edge, else such
6747 volumes, if any, remain intact and the mesh becomes non-conformal.
6750 a number of successfully sewed groups
6753 This operation can create gaps in numeration of nodes or elements.
6754 Call :meth:`RenumberElements` to remove the gaps.
6757 if freeBorders and isinstance( freeBorders, list ):
6758 # construct SMESH.CoincidentFreeBorders
6759 if isinstance( freeBorders[0], int ):
6760 freeBorders = [freeBorders]
6762 coincidentGroups = []
6763 for nodeList in freeBorders:
6764 if not nodeList or len( nodeList ) % 3:
6765 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6768 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6769 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6770 nodeList = nodeList[3:]
6772 coincidentGroups.append( group )
6774 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6776 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6778 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6779 FirstNodeID2, SecondNodeID2, LastNodeID2,
6780 CreatePolygons, CreatePolyedrs):
6785 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6788 This operation can create gaps in numeration of nodes or elements.
6789 Call :meth:`RenumberElements` to remove the gaps.
6792 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6793 FirstNodeID2, SecondNodeID2, LastNodeID2,
6794 CreatePolygons, CreatePolyedrs)
6796 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6797 FirstNodeID2, SecondNodeID2):
6799 Sew conform free borders
6802 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6805 This operation can create gaps in numeration of elements.
6806 Call :meth:`RenumberElements` to remove the gaps.
6809 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6810 FirstNodeID2, SecondNodeID2)
6812 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6813 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6818 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6821 This operation can create gaps in numeration of elements.
6822 Call :meth:`RenumberElements` to remove the gaps.
6825 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6826 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6828 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6829 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6830 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6832 Sew two sides of a mesh. The nodes belonging to Side1 are
6833 merged with the nodes of elements of Side2.
6834 The number of elements in theSide1 and in theSide2 must be
6835 equal and they should have similar nodal connectivity.
6836 The nodes to merge should belong to side borders and
6837 the first node should be linked to the second.
6840 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6843 This operation can create gaps in numeration of nodes.
6844 Call :meth:`RenumberElements` to remove the gaps.
6847 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6848 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6849 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6851 def ChangeElemNodes(self, ide, newIDs):
6853 Set new nodes for the given element. Number of nodes should be kept.
6860 False if the number of nodes does not correspond to the type of element
6863 return self.editor.ChangeElemNodes(ide, newIDs)
6865 def GetLastCreatedNodes(self):
6867 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6868 created, this method return the list of their IDs.
6869 If new nodes were not created - return empty list
6872 the list of integer values (can be empty)
6875 return self.editor.GetLastCreatedNodes()
6877 def GetLastCreatedElems(self):
6879 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6880 created this method return the list of their IDs.
6881 If new elements were not created - return empty list
6884 the list of integer values (can be empty)
6887 return self.editor.GetLastCreatedElems()
6889 def ClearLastCreated(self):
6891 Forget what nodes and elements were created by the last mesh edition operation
6894 self.editor.ClearLastCreated()
6896 def DoubleElements(self, theElements, theGroupName=""):
6898 Create duplicates of given elements, i.e. create new elements based on the
6899 same nodes as the given ones.
6902 theElements: container of elements to duplicate. It can be a
6903 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6904 or a list of element IDs. If *theElements* is
6905 a :class:`Mesh`, elements of highest dimension are duplicated
6906 theGroupName: a name of group to contain the generated elements.
6907 If a group with such a name already exists, the new elements
6908 are added to the existing group, else a new group is created.
6909 If *theGroupName* is empty, new elements are not added
6913 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6914 None if *theGroupName* == "".
6917 unRegister = genObjUnRegister()
6918 if isinstance( theElements, Mesh ):
6919 theElements = theElements.mesh
6920 elif isinstance( theElements, list ):
6921 theElements = self.GetIDSource( theElements, SMESH.ALL )
6922 unRegister.set( theElements )
6923 return self.editor.DoubleElements(theElements, theGroupName)
6925 def DoubleNodes(self, theNodes, theModifiedElems):
6927 Create a hole in a mesh by doubling the nodes of some particular elements
6930 theNodes: IDs of nodes to be doubled
6931 theModifiedElems: IDs of elements to be updated by the new (doubled)
6932 nodes. If list of element identifiers is empty then nodes are doubled but
6933 they not assigned to elements
6936 True if operation has been completed successfully, False otherwise
6939 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6941 def DoubleNode(self, theNodeId, theModifiedElems):
6943 Create a hole in a mesh by doubling the nodes of some particular elements.
6944 This method provided for convenience works as :meth:`DoubleNodes`.
6947 theNodeId: IDs of node to double
6948 theModifiedElems: IDs of elements to update
6951 True if operation has been completed successfully, False otherwise
6954 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6956 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6958 Create a hole in a mesh by doubling the nodes of some particular elements.
6959 This method provided for convenience works as :meth:`DoubleNodes`.
6962 theNodes: group of nodes to double.
6963 theModifiedElems: group of elements to update.
6964 theMakeGroup: forces the generation of a group containing new nodes.
6967 True or a created group if operation has been completed successfully,
6968 False or None otherwise
6972 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6973 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6975 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6977 Create a hole in a mesh by doubling the nodes of some particular elements.
6978 This method provided for convenience works as :meth:`DoubleNodes`.
6981 theNodes: list of groups of nodes to double.
6982 theModifiedElems: list of groups of elements to update.
6983 theMakeGroup: forces the generation of a group containing new nodes.
6986 True if operation has been completed successfully, False otherwise
6990 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6991 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6993 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6995 Create a hole in a mesh by doubling the nodes of some particular elements
6998 theElems: the list of elements (edges or faces) to replicate.
6999 The nodes for duplication could be found from these elements
7000 theNodesNot: list of nodes NOT to replicate
7001 theAffectedElems: the list of elements (cells and edges) to which the
7002 replicated nodes should be associated to
7005 True if operation has been completed successfully, False otherwise
7008 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
7010 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
7012 Create a hole in a mesh by doubling the nodes of some particular elements
7015 theElems: the list of elements (edges or faces) to replicate.
7016 The nodes for duplication could be found from these elements
7017 theNodesNot: list of nodes NOT to replicate
7018 theShape: shape to detect affected elements (element which geometric center
7019 located on or inside shape).
7020 The replicated nodes should be associated to affected elements.
7023 True if operation has been completed successfully, False otherwise
7026 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
7028 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
7029 theMakeGroup=False, theMakeNodeGroup=False):
7031 Create a hole in a mesh by doubling the nodes of some particular elements.
7032 This method provided for convenience works as :meth:`DoubleNodes`.
7035 theElems: group of of elements (edges or faces) to replicate.
7036 theNodesNot: group of nodes NOT to replicate.
7037 theAffectedElems: group of elements to which the replicated nodes
7038 should be associated to.
7039 theMakeGroup: forces the generation of a group containing new elements.
7040 theMakeNodeGroup: forces the generation of a group containing new nodes.
7043 True or created groups (one or two) if operation has been completed successfully,
7044 False or None otherwise
7047 if theMakeGroup or theMakeNodeGroup:
7048 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
7050 theMakeGroup, theMakeNodeGroup)
7051 if theMakeGroup and theMakeNodeGroup:
7054 return twoGroups[ int(theMakeNodeGroup) ]
7055 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7057 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7059 Create a hole in a mesh by doubling the nodes of some particular elements.
7060 This method provided for convenience works as :meth:`DoubleNodes`.
7063 theElems: group of of elements (edges or faces) to replicate
7064 theNodesNot: group of nodes not to replicate
7065 theShape: shape to detect affected elements (element which geometric center
7066 located on or inside shape).
7067 The replicated nodes should be associated to affected elements
7070 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7072 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7073 theMakeGroup=False, theMakeNodeGroup=False):
7075 Create a hole in a mesh by doubling the nodes of some particular elements.
7076 This method provided for convenience works as :meth:`DoubleNodes`.
7079 theElems: list of groups of elements (edges or faces) to replicate
7080 theNodesNot: list of groups of nodes NOT to replicate
7081 theAffectedElems: group of elements to which the replicated nodes
7082 should be associated to
7083 theMakeGroup: forces generation of a group containing new elements.
7084 theMakeNodeGroup: forces generation of a group containing new nodes
7087 True or created groups (one or two) if operation has been completed successfully,
7088 False or None otherwise
7091 if theMakeGroup or theMakeNodeGroup:
7092 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7094 theMakeGroup, theMakeNodeGroup)
7095 if theMakeGroup and theMakeNodeGroup:
7098 return twoGroups[ int(theMakeNodeGroup) ]
7099 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7101 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7103 Create a hole in a mesh by doubling the nodes of some particular elements.
7104 This method provided for convenience works as :meth:`DoubleNodes`.
7107 theElems: list of groups of elements (edges or faces) to replicate
7108 theNodesNot: list of groups of nodes NOT to replicate
7109 theShape: shape to detect affected elements (element which geometric center
7110 located on or inside shape).
7111 The replicated nodes should be associated to affected elements
7114 True if operation has been completed successfully, False otherwise
7117 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7119 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7121 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7122 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7125 theElems: list of groups of nodes or elements (edges or faces) to replicate
7126 theNodesNot: list of groups of nodes NOT to replicate
7127 theShape: shape to detect affected elements (element which geometric center
7128 located on or inside shape).
7129 The replicated nodes should be associated to affected elements
7132 groups of affected elements in order: volumes, faces, edges
7135 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7137 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7140 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7141 The list of groups must describe a partition of the mesh volumes.
7142 The nodes of the internal faces at the boundaries of the groups are doubled.
7143 In option, the internal faces are replaced by flat elements.
7144 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7147 theDomains: list of groups of volumes
7148 createJointElems: if True, create the elements
7149 onAllBoundaries: if True, the nodes and elements are also created on
7150 the boundary between *theDomains* and the rest mesh
7153 True if operation has been completed successfully, False otherwise
7156 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7158 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7160 Double nodes on some external faces and create flat elements.
7161 Flat elements are mainly used by some types of mechanic calculations.
7163 Each group of the list must be constituted of faces.
7164 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7167 theGroupsOfFaces: list of groups of faces
7170 True if operation has been completed successfully, False otherwise
7173 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7175 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7177 Identify all the elements around a geom shape, get the faces delimiting the hole
7179 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7181 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7183 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7184 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7185 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7186 If there are several paths connecting a pair of points, the shortest path is
7187 selected by the module. Position of the cutting plane is defined by the two
7188 points and an optional vector lying on the plane specified by a PolySegment.
7189 By default the vector is defined by Mesh module as following. A middle point
7190 of the two given points is computed. The middle point is projected to the mesh.
7191 The vector goes from the middle point to the projection point. In case of planar
7192 mesh, the vector is normal to the mesh.
7194 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7197 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7198 groupName: optional name of a group where created mesh segments will be added.
7201 editor = self.editor
7203 editor = self.mesh.GetMeshEditPreviewer()
7204 segmentsRes = editor.MakePolyLine( segments, groupName )
7205 for i, seg in enumerate( segmentsRes ):
7206 segments[i].vector = seg.vector
7208 return editor.GetPreviewData()
7211 def MakeSlot(self, segmentGroup, width ):
7213 Create a slot of given width around given 1D elements lying on a triangle mesh.
7214 The slot is constructed by cutting faces by cylindrical surfaces made
7215 around each segment. Segments are expected to be created by MakePolyLine().
7218 FaceEdge's located at the slot boundary
7220 return self.editor.MakeSlot( segmentGroup, width )
7222 def GetFunctor(self, funcType ):
7224 Return a cached numerical functor by its type.
7227 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7228 Note that not all items correspond to numerical functors.
7231 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7234 fn = self.functors[ funcType._v ]
7236 fn = self.smeshpyD.GetFunctor(funcType)
7237 fn.SetMesh(self.mesh)
7238 self.functors[ funcType._v ] = fn
7241 def FunctorValue(self, funcType, elemId, isElem=True):
7243 Return value of a functor for a given element
7246 funcType: an item of :class:`SMESH.FunctorType` enum.
7247 elemId: element or node ID
7248 isElem: *elemId* is ID of element or node
7251 the functor value or zero in case of invalid arguments
7254 fn = self.GetFunctor( funcType )
7255 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7256 val = fn.GetValue(elemId)
7261 def GetLength(self, elemId=None):
7263 Get length of given 1D elements or of all 1D mesh elements
7266 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.
7269 Sum of lengths of given elements
7274 length = self.smeshpyD.GetLength(self)
7275 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7276 length = self.smeshpyD.GetLength(elemId)
7279 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7281 length += self.smeshpyD.GetLength(obj)
7282 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7283 unRegister = genObjUnRegister()
7284 obj = self.GetIDSource( elemId )
7285 unRegister.set( obj )
7286 length = self.smeshpyD.GetLength( obj )
7288 length = self.FunctorValue(SMESH.FT_Length, elemId)
7291 def GetArea(self, elemId=None):
7293 Get area of given 2D elements or of all 2D mesh elements
7296 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.
7299 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7304 area = self.smeshpyD.GetArea(self)
7305 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7306 area = self.smeshpyD.GetArea(elemId)
7309 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7311 area += self.smeshpyD.GetArea(obj)
7312 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7313 unRegister = genObjUnRegister()
7314 obj = self.GetIDSource( elemId )
7315 unRegister.set( obj )
7316 area = self.smeshpyD.GetArea( obj )
7318 area = self.FunctorValue(SMESH.FT_Area, elemId)
7321 def GetVolume(self, elemId=None):
7323 Get volume of given 3D elements or of all 3D mesh elements
7326 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.
7329 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7334 volume= self.smeshpyD.GetVolume(self)
7335 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7336 volume= self.smeshpyD.GetVolume(elemId)
7339 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7341 volume+= self.smeshpyD.GetVolume(obj)
7342 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7343 unRegister = genObjUnRegister()
7344 obj = self.GetIDSource( elemId )
7345 unRegister.set( obj )
7346 volume= self.smeshpyD.GetVolume( obj )
7348 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7351 def GetAngle(self, node1, node2, node3 ):
7353 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7356 node1,node2,node3: IDs of the three nodes
7359 Angle in radians [0,PI]. -1 if failure case.
7361 p1 = self.GetNodeXYZ( node1 )
7362 p2 = self.GetNodeXYZ( node2 )
7363 p3 = self.GetNodeXYZ( node3 )
7364 if p1 and p2 and p3:
7365 return self.smeshpyD.GetAngle( p1,p2,p3 )
7369 def GetMaxElementLength(self, elemId):
7371 Get maximum element length.
7374 elemId: mesh element ID
7377 element's maximum length value
7380 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7381 ftype = SMESH.FT_MaxElementLength3D
7383 ftype = SMESH.FT_MaxElementLength2D
7384 return self.FunctorValue(ftype, elemId)
7386 def GetAspectRatio(self, elemId):
7388 Get aspect ratio of 2D or 3D element.
7391 elemId: mesh element ID
7394 element's aspect ratio value
7397 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7398 ftype = SMESH.FT_AspectRatio3D
7400 ftype = SMESH.FT_AspectRatio
7401 return self.FunctorValue(ftype, elemId)
7403 def GetWarping(self, elemId):
7405 Get warping angle of 2D element.
7408 elemId: mesh element ID
7411 element's warping angle value
7414 return self.FunctorValue(SMESH.FT_Warping, elemId)
7416 def GetMinimumAngle(self, elemId):
7418 Get minimum angle of 2D element.
7421 elemId: mesh element ID
7424 element's minimum angle value
7427 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7429 def GetTaper(self, elemId):
7431 Get taper of 2D element.
7434 elemId: mesh element ID
7437 element's taper value
7440 return self.FunctorValue(SMESH.FT_Taper, elemId)
7442 def GetSkew(self, elemId):
7444 Get skew of 2D element.
7447 elemId: mesh element ID
7450 element's skew value
7453 return self.FunctorValue(SMESH.FT_Skew, elemId)
7455 def GetMinMax(self, funType, meshPart=None):
7457 Return minimal and maximal value of a given functor.
7460 funType (SMESH.FunctorType): a functor type.
7461 Note that not all items of :class:`SMESH.FunctorType` corresponds
7462 to numerical functors.
7463 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7469 unRegister = genObjUnRegister()
7470 if isinstance( meshPart, list ):
7471 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7472 unRegister.set( meshPart )
7473 if isinstance( meshPart, Mesh ):
7474 meshPart = meshPart.mesh
7475 fun = self.GetFunctor( funType )
7478 if hasattr( meshPart, "SetMesh" ):
7479 meshPart.SetMesh( self.mesh ) # set mesh to filter
7480 hist = fun.GetLocalHistogram( 1, False, meshPart )
7482 hist = fun.GetHistogram( 1, False )
7484 return hist[0].min, hist[0].max
7487 pass # end of Mesh class
7490 class meshProxy(SMESH._objref_SMESH_Mesh):
7492 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7493 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7495 def __init__(self,*args):
7496 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7497 def __deepcopy__(self, memo=None):
7498 new = self.__class__(self)
7500 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7501 if len( args ) == 3:
7502 args += SMESH.ALL_NODES, True
7503 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7504 def ExportToMEDX(self, *args): # function removed
7505 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7506 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7507 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7508 def ExportToMED(self, *args): # function removed
7509 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7510 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7512 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7514 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7515 def ExportPartToMED(self, *args): # 'version' parameter removed
7516 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7517 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7518 def ExportMED(self, *args): # signature of method changed
7519 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7521 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7523 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7524 def ExportUNV(self, *args): # renumber arg added
7525 if len( args ) == 1:
7527 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
7528 def ExportDAT(self, *args): # renumber arg added
7529 if len( args ) == 1:
7531 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
7533 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7536 class submeshProxy(SMESH._objref_SMESH_subMesh):
7539 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7541 def __init__(self,*args):
7542 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7544 def __deepcopy__(self, memo=None):
7545 new = self.__class__(self)
7548 def Compute(self,refresh=False):
7550 Compute the sub-mesh and return the status of the computation
7553 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7558 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7559 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7563 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7565 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7567 if salome.sg.hasDesktop():
7568 if refresh: salome.sg.updateObjBrowser()
7573 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7576 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7578 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7579 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7582 def __init__(self,*args):
7583 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7585 def __getattr__(self, name ): # method called if an attribute not found
7586 if not self.mesh: # look for name() method in Mesh class
7587 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7588 if hasattr( self.mesh, name ):
7589 return getattr( self.mesh, name )
7590 if name == "ExtrusionAlongPathObjX":
7591 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7592 print("meshEditor: attribute '%s' NOT FOUND" % name)
7594 def __deepcopy__(self, memo=None):
7595 new = self.__class__(self)
7597 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7598 if len( args ) == 1: args += False,
7599 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7600 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7601 if len( args ) == 2: args += False,
7602 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7603 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7604 if len( args ) == 1:
7605 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7606 NodesToKeep = args[1]
7607 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7608 unRegister = genObjUnRegister()
7610 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7611 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7612 if not isinstance( NodesToKeep, list ):
7613 NodesToKeep = [ NodesToKeep ]
7614 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7616 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7618 class Pattern(SMESH._objref_SMESH_Pattern):
7620 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7621 variables in some methods
7624 def LoadFromFile(self, patternTextOrFile ):
7625 text = patternTextOrFile
7626 if os.path.exists( text ):
7627 text = open( patternTextOrFile ).read()
7629 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7631 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7632 decrFun = lambda i: i-1
7633 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7634 theMesh.SetParameters(Parameters)
7635 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7637 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7638 decrFun = lambda i: i-1
7639 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7640 theMesh.SetParameters(Parameters)
7641 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7643 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7644 if isinstance( mesh, Mesh ):
7645 mesh = mesh.GetMesh()
7646 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7648 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7650 Registering the new proxy for Pattern
7655 Private class used to bind methods creating algorithms to the class Mesh
7658 def __init__(self, method):
7660 self.defaultAlgoType = ""
7661 self.algoTypeToClass = {}
7662 self.method = method
7664 def add(self, algoClass):
7666 Store a python class of algorithm
7668 if inspect.isclass(algoClass) and \
7669 hasattr( algoClass, "algoType"):
7670 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7671 if not self.defaultAlgoType and \
7672 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7673 self.defaultAlgoType = algoClass.algoType
7674 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7676 def copy(self, mesh):
7678 Create a copy of self and assign mesh to the copy
7681 other = algoCreator( self.method )
7682 other.defaultAlgoType = self.defaultAlgoType
7683 other.algoTypeToClass = self.algoTypeToClass
7687 def __call__(self,algo="",geom=0,*args):
7689 Create an instance of algorithm
7693 if isinstance( algo, str ):
7695 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7696 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7701 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7703 elif not algoType and isinstance( geom, str ):
7708 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7710 elif isinstance( arg, str ) and not algoType:
7713 import traceback, sys
7714 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7715 sys.stderr.write( msg + '\n' )
7716 tb = traceback.extract_stack(None,2)
7717 traceback.print_list( [tb[0]] )
7719 algoType = self.defaultAlgoType
7720 if not algoType and self.algoTypeToClass:
7721 algoType = sorted( self.algoTypeToClass.keys() )[0]
7722 if algoType in self.algoTypeToClass:
7723 #print("Create algo",algoType)
7724 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7725 raise RuntimeError( "No class found for algo type %s" % algoType)
7728 class hypMethodWrapper:
7730 Private class used to substitute and store variable parameters of hypotheses.
7733 def __init__(self, hyp, method):
7735 self.method = method
7736 #print("REBIND:", method.__name__)
7739 def __call__(self,*args):
7741 call a method of hypothesis with calling SetVarParameter() before
7745 return self.method( self.hyp, *args ) # hypothesis method with no args
7747 #print("MethWrapper.__call__", self.method.__name__, args)
7749 parsed = ParseParameters(*args) # replace variables with their values
7750 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7751 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7752 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7753 # maybe there is a replaced string arg which is not variable
7754 result = self.method( self.hyp, *args )
7755 except ValueError as detail: # raised by ParseParameters()
7757 result = self.method( self.hyp, *args )
7758 except omniORB.CORBA.BAD_PARAM:
7759 raise ValueError(detail) # wrong variable name
7764 class genObjUnRegister:
7766 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7769 def __init__(self, genObj=None):
7770 self.genObjList = []
7774 def set(self, genObj):
7775 "Store one or a list of of SALOME.GenericObj'es"
7776 if isinstance( genObj, list ):
7777 self.genObjList.extend( genObj )
7779 self.genObjList.append( genObj )
7783 for genObj in self.genObjList:
7784 if genObj and hasattr( genObj, "UnRegister" ):
7787 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7789 Bind methods creating mesher plug-ins to the Mesh class
7792 # print("pluginName: ", pluginName)
7793 pluginBuilderName = pluginName + "Builder"
7795 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7796 except Exception as e:
7797 from salome_utils import verbose
7798 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7800 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7801 plugin = eval( pluginBuilderName )
7802 # print(" plugin:" , str(plugin))
7804 # add methods creating algorithms to Mesh
7805 for k in dir( plugin ):
7806 if k[0] == '_': continue
7807 algo = getattr( plugin, k )
7808 #print(" algo:", str(algo))
7809 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7810 #print(" meshMethod:" , str(algo.meshMethod))
7811 if not hasattr( Mesh, algo.meshMethod ):
7812 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7814 _mmethod = getattr( Mesh, algo.meshMethod )
7815 if hasattr( _mmethod, "add" ):