1 # Copyright (C) 2007-2021 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 CreateMeshesFromSAUV( self,theFileName ):
690 Create a Mesh object(s) importing data from the given SAUV file
693 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
696 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
697 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
698 return aMeshes, aStatus
700 def CreateMeshesFromSTL( self, theFileName ):
702 Create a Mesh object importing data from the given STL file
705 an instance of class :class:`Mesh`
708 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
709 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
712 def CreateMeshesFromCGNS( self, theFileName ):
714 Create Mesh objects importing data from the given CGNS file
717 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
720 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
721 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
722 return aMeshes, aStatus
724 def CreateMeshesFromGMF( self, theFileName ):
726 Create a Mesh object importing data from the given GMF file.
727 GMF files must have .mesh extension for the ASCII format and .meshb for
731 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
734 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
737 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
738 return Mesh(self, self.geompyD, aSmeshMesh), error
740 def Concatenate( self, meshes, uniteIdenticalGroups,
741 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
742 name = "", meshToAppendTo = None):
744 Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
745 All groups of input meshes will be present in the new mesh.
748 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
749 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
750 mergeNodesAndElements: if True, equal nodes and elements are merged
751 mergeTolerance: tolerance for merging nodes
752 allGroups: forces creation of groups corresponding to every input mesh
753 name: name of a new mesh
754 meshToAppendTo: a mesh to append all given meshes
757 an instance of class :class:`Mesh`
763 if not meshes: return None
764 if not isinstance( meshes, list ):
766 for i,m in enumerate( meshes ):
767 if isinstance( m, Mesh ):
768 meshes[i] = m.GetMesh()
769 mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
770 if hasattr(meshes[0], "SetParameters"):
771 meshes[0].SetParameters( Parameters )
773 meshes[0].GetMesh().SetParameters( Parameters )
774 if isinstance( meshToAppendTo, Mesh ):
775 meshToAppendTo = meshToAppendTo.GetMesh()
777 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
778 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
779 mergeTolerance,meshToAppendTo )
781 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
782 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
783 mergeTolerance,meshToAppendTo )
785 aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
788 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
790 Create a mesh by copying a part of another mesh.
793 meshPart: a part of mesh to copy, either
794 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
795 To copy nodes or elements not forming any mesh object,
796 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
797 meshName: a name of the new mesh
798 toCopyGroups: to create in the new mesh groups the copied elements belongs to
799 toKeepIDs: to preserve order of the copied elements or not
802 an instance of class :class:`Mesh`
805 if isinstance( meshPart, Mesh ):
806 meshPart = meshPart.GetMesh()
807 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
808 return Mesh(self, self.geompyD, mesh)
810 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
811 toReuseHypotheses=True, toCopyElements=True):
813 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
814 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
815 To facilitate and speed up the operation, consider using
816 "Set presentation parameters and sub-shapes from arguments" option in
817 a dialog of geometrical operation used to create the new geometry.
820 sourceMesh: the mesh to copy definition of.
821 newGeom: the new geometry.
822 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
823 toCopyGroups: to create groups in the new mesh.
824 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
825 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
828 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
829 *invalidEntries* are study entries of objects whose
830 counterparts are not found in the *newGeom*, followed by entries
831 of mesh sub-objects that are invalid because they depend on a not found
834 if isinstance( sourceMesh, Mesh ):
835 sourceMesh = sourceMesh.GetMesh()
837 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
838 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
842 return ( ok, Mesh(self, self.geompyD, newMesh),
843 newGroups, newSubMeshes, newHypotheses, invalidEntries )
845 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
847 Return IDs of sub-shapes
850 theMainObject (GEOM.GEOM_Object): a shape
851 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
853 the list of integer values
856 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
858 def GetPattern(self):
860 Create a pattern mapper.
863 an instance of :class:`SMESH.SMESH_Pattern`
865 :ref:`Example of Patterns usage <tui_pattern_mapping>`
868 return SMESH._objref_SMESH_Gen.GetPattern(self)
870 def SetBoundaryBoxSegmentation(self, nbSegments):
872 Set number of segments per diagonal of boundary box of geometry, by which
873 default segment length of appropriate 1D hypotheses is defined in GUI.
877 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
879 # Filtering. Auxiliary functions:
880 # ------------------------------
882 def GetEmptyCriterion(self):
884 Create an empty criterion
887 :class:`SMESH.Filter.Criterion`
890 Type = self.EnumToLong(FT_Undefined)
891 Compare = self.EnumToLong(FT_Undefined)
895 UnaryOp = self.EnumToLong(FT_Undefined)
896 BinaryOp = self.EnumToLong(FT_Undefined)
899 Precision = -1 ##@1e-07
900 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
901 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
903 def GetCriterion(self,elementType,
905 Compare = FT_EqualTo,
907 UnaryOp=FT_Undefined,
908 BinaryOp=FT_Undefined,
911 Create a criterion by the given parameters
912 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
915 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
916 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
917 Note that the items starting from FT_LessThan are not suitable for *CritType*.
918 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
919 Threshold: the threshold value (range of ids as string, shape, numeric)
920 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
921 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
923 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
924 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
927 :class:`SMESH.Filter.Criterion`
929 Example: :ref:`combining_filters`
932 if not CritType in SMESH.FunctorType._items:
933 raise TypeError("CritType should be of SMESH.FunctorType")
934 aCriterion = self.GetEmptyCriterion()
935 aCriterion.TypeOfElement = elementType
936 aCriterion.Type = self.EnumToLong(CritType)
937 aCriterion.Tolerance = Tolerance
939 aThreshold = Threshold
941 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
942 aCriterion.Compare = self.EnumToLong(Compare)
943 elif Compare == "=" or Compare == "==":
944 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
946 aCriterion.Compare = self.EnumToLong(FT_LessThan)
948 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
949 elif Compare != FT_Undefined:
950 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
953 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
954 FT_BelongToCylinder, FT_LyingOnGeom]:
955 # Check that Threshold is GEOM object
956 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
957 aCriterion.ThresholdStr = GetName(aThreshold)
958 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
959 if not aCriterion.ThresholdID:
960 name = aCriterion.ThresholdStr
962 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
963 geompyD = aThreshold.GetGen()
964 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
965 # or a name of GEOM object
966 elif isinstance( aThreshold, str ):
967 aCriterion.ThresholdStr = aThreshold
969 raise TypeError("The Threshold should be a shape.")
970 if isinstance(UnaryOp,float):
971 aCriterion.Tolerance = UnaryOp
972 UnaryOp = FT_Undefined
974 elif CritType == FT_BelongToMeshGroup:
975 # Check that Threshold is a group
976 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
977 if aThreshold.GetType() != elementType:
978 raise ValueError("Group type mismatches Element type")
979 aCriterion.ThresholdStr = aThreshold.GetName()
980 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
981 study = salome.myStudy
983 so = study.FindObjectIOR( aCriterion.ThresholdID )
987 aCriterion.ThresholdID = entry
989 raise TypeError("The Threshold should be a Mesh Group")
990 elif CritType == FT_RangeOfIds:
991 # Check that Threshold is string
992 if isinstance(aThreshold, str):
993 aCriterion.ThresholdStr = aThreshold
995 raise TypeError("The Threshold should be a string.")
996 elif CritType == FT_CoplanarFaces:
997 # Check the Threshold
998 if isinstance(aThreshold, int):
999 aCriterion.ThresholdID = str(aThreshold)
1000 elif isinstance(aThreshold, str):
1001 ID = int(aThreshold)
1003 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
1004 aCriterion.ThresholdID = aThreshold
1006 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1007 elif CritType == FT_ConnectedElements:
1008 # Check the Threshold
1009 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1010 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1011 if not aCriterion.ThresholdID:
1012 name = aThreshold.GetName()
1014 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1015 geompyD = aThreshold.GetGen()
1016 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
1017 elif isinstance(aThreshold, int): # node id
1018 aCriterion.Threshold = aThreshold
1019 elif isinstance(aThreshold, list): # 3 point coordinates
1020 if len( aThreshold ) < 3:
1021 raise ValueError("too few point coordinates, must be 3")
1022 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1023 elif isinstance(aThreshold, str):
1024 if aThreshold.isdigit():
1025 aCriterion.Threshold = aThreshold # node id
1027 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1029 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1030 "or a list of point coordinates and not '%s'"%aThreshold)
1031 elif CritType == FT_ElemGeomType:
1032 # Check the Threshold
1034 aCriterion.Threshold = self.EnumToLong(aThreshold)
1035 assert( aThreshold in SMESH.GeometryType._items )
1037 if isinstance(aThreshold, int):
1038 aCriterion.Threshold = aThreshold
1040 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1043 elif CritType == FT_EntityType:
1044 # Check the Threshold
1046 aCriterion.Threshold = self.EnumToLong(aThreshold)
1047 assert( aThreshold in SMESH.EntityType._items )
1049 if isinstance(aThreshold, int):
1050 aCriterion.Threshold = aThreshold
1052 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1056 elif CritType == FT_GroupColor:
1057 # Check the Threshold
1059 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1061 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1063 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1064 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1065 FT_BareBorderFace, FT_BareBorderVolume,
1066 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1067 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1068 # At this point the Threshold is unnecessary
1069 if aThreshold == FT_LogicalNOT:
1070 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1071 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1072 aCriterion.BinaryOp = aThreshold
1076 aThreshold = float(aThreshold)
1077 aCriterion.Threshold = aThreshold
1079 raise TypeError("The Threshold should be a number.")
1082 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1083 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1085 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1086 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1088 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1089 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1091 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1092 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1096 def GetFilter(self,elementType,
1097 CritType=FT_Undefined,
1100 UnaryOp=FT_Undefined,
1104 Create a filter with the given parameters
1107 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1108 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1109 Note that the items starting from FT_LessThan are not suitable for CritType.
1110 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1111 Threshold: the threshold value (range of ids as string, shape, numeric)
1112 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1113 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1114 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1115 mesh: the mesh to initialize the filter with
1118 :class:`SMESH.Filter`
1121 See :doc:`Filters usage examples <tui_filters>`
1124 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1125 aFilterMgr = self.CreateFilterManager()
1126 aFilter = aFilterMgr.CreateFilter()
1128 aCriteria.append(aCriterion)
1129 aFilter.SetCriteria(aCriteria)
1131 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1132 else : aFilter.SetMesh( mesh )
1133 aFilterMgr.UnRegister()
1136 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1138 Create a filter from criteria
1141 criteria: a list of :class:`SMESH.Filter.Criterion`
1142 binOp: binary operator used when binary operator of criteria is undefined
1145 :class:`SMESH.Filter`
1148 See :doc:`Filters usage examples <tui_filters>`
1151 for i in range( len( criteria ) - 1 ):
1152 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1153 criteria[i].BinaryOp = self.EnumToLong( binOp )
1154 aFilterMgr = self.CreateFilterManager()
1155 aFilter = aFilterMgr.CreateFilter()
1156 aFilter.SetCriteria(criteria)
1157 aFilterMgr.UnRegister()
1160 def GetFunctor(self,theCriterion):
1162 Create a numerical functor by its type
1165 theCriterion (SMESH.FunctorType): functor type.
1166 Note that not all items correspond to numerical functors.
1169 :class:`SMESH.NumericalFunctor`
1172 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1174 aFilterMgr = self.CreateFilterManager()
1176 if theCriterion == FT_AspectRatio:
1177 functor = aFilterMgr.CreateAspectRatio()
1178 elif theCriterion == FT_AspectRatio3D:
1179 functor = aFilterMgr.CreateAspectRatio3D()
1180 elif theCriterion == FT_Warping:
1181 functor = aFilterMgr.CreateWarping()
1182 elif theCriterion == FT_MinimumAngle:
1183 functor = aFilterMgr.CreateMinimumAngle()
1184 elif theCriterion == FT_Taper:
1185 functor = aFilterMgr.CreateTaper()
1186 elif theCriterion == FT_Skew:
1187 functor = aFilterMgr.CreateSkew()
1188 elif theCriterion == FT_Area:
1189 functor = aFilterMgr.CreateArea()
1190 elif theCriterion == FT_Volume3D:
1191 functor = aFilterMgr.CreateVolume3D()
1192 elif theCriterion == FT_MaxElementLength2D:
1193 functor = aFilterMgr.CreateMaxElementLength2D()
1194 elif theCriterion == FT_MaxElementLength3D:
1195 functor = aFilterMgr.CreateMaxElementLength3D()
1196 elif theCriterion == FT_MultiConnection:
1197 functor = aFilterMgr.CreateMultiConnection()
1198 elif theCriterion == FT_MultiConnection2D:
1199 functor = aFilterMgr.CreateMultiConnection2D()
1200 elif theCriterion == FT_Length:
1201 functor = aFilterMgr.CreateLength()
1202 elif theCriterion == FT_Length2D:
1203 functor = aFilterMgr.CreateLength2D()
1204 elif theCriterion == FT_Length3D:
1205 functor = aFilterMgr.CreateLength3D()
1206 elif theCriterion == FT_Deflection2D:
1207 functor = aFilterMgr.CreateDeflection2D()
1208 elif theCriterion == FT_NodeConnectivityNumber:
1209 functor = aFilterMgr.CreateNodeConnectivityNumber()
1210 elif theCriterion == FT_BallDiameter:
1211 functor = aFilterMgr.CreateBallDiameter()
1213 print("Error: given parameter is not numerical functor type.")
1214 aFilterMgr.UnRegister()
1217 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1222 theHType (string): mesh hypothesis type
1223 theLibName (string): mesh plug-in library name
1226 created hypothesis instance
1228 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1230 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1233 # wrap hypothesis methods
1234 for meth_name in dir( hyp.__class__ ):
1235 if not meth_name.startswith("Get") and \
1236 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1237 method = getattr ( hyp.__class__, meth_name )
1238 if callable(method):
1239 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1243 def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1245 Create hypothesis initialized according to parameters
1248 hypType (string): hypothesis type
1249 libName (string): plug-in library name
1250 mesh: optional mesh by which a hypotheses can initialize self
1251 shape: optional geometry by size of which a hypotheses can initialize self
1252 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1255 created hypothesis instance
1257 if isinstance( mesh, Mesh ):
1258 mesh = mesh.GetMesh()
1259 if isinstance( initParams, (bool,int)):
1260 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1261 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1262 mesh, shape, initParams )
1264 def GetMeshInfo(self, obj):
1266 Get the mesh statistic.
1269 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1272 if isinstance( obj, Mesh ):
1275 if hasattr(obj, "GetMeshInfo"):
1276 values = obj.GetMeshInfo()
1277 for i in range(SMESH.Entity_Last._v):
1278 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1282 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1284 Get minimum distance between two objects
1286 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1287 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1290 src1 (SMESH.SMESH_IDSource): first source object
1291 src2 (SMESH.SMESH_IDSource): second source object
1292 id1 (int): node/element id from the first source
1293 id2 (int): node/element id from the second (or first) source
1294 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1295 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1298 minimum distance value
1301 :meth:`GetMinDistance`
1304 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1308 result = result.value
1311 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1313 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1315 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1316 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1319 src1 (SMESH.SMESH_IDSource): first source object
1320 src2 (SMESH.SMESH_IDSource): second source object
1321 id1 (int): node/element id from the first source
1322 id2 (int): node/element id from the second (or first) source
1323 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1324 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1327 :class:`SMESH.Measure` structure or None if input data is invalid
1332 if isinstance(src1, Mesh): src1 = src1.mesh
1333 if isinstance(src2, Mesh): src2 = src2.mesh
1334 if src2 is None and id2 != 0: src2 = src1
1335 if not hasattr(src1, "_narrow"): return None
1336 src1 = src1._narrow(SMESH.SMESH_IDSource)
1337 if not src1: return None
1338 unRegister = genObjUnRegister()
1341 e = m.GetMeshEditor()
1343 src1 = e.MakeIDSource([id1], SMESH.FACE)
1345 src1 = e.MakeIDSource([id1], SMESH.NODE)
1346 unRegister.set( src1 )
1348 if hasattr(src2, "_narrow"):
1349 src2 = src2._narrow(SMESH.SMESH_IDSource)
1350 if src2 and id2 != 0:
1352 e = m.GetMeshEditor()
1354 src2 = e.MakeIDSource([id2], SMESH.FACE)
1356 src2 = e.MakeIDSource([id2], SMESH.NODE)
1357 unRegister.set( src2 )
1360 aMeasurements = self.CreateMeasurements()
1361 unRegister.set( aMeasurements )
1362 result = aMeasurements.MinDistance(src1, src2)
1365 def BoundingBox(self, objects):
1367 Get bounding box of the specified object(s)
1370 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1373 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1376 :meth:`GetBoundingBox`
1379 result = self.GetBoundingBox(objects)
1383 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1386 def GetBoundingBox(self, objects):
1388 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1391 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1394 :class:`SMESH.Measure` structure
1400 if isinstance(objects, tuple):
1401 objects = list(objects)
1402 if not isinstance(objects, list):
1406 if isinstance(o, Mesh):
1407 srclist.append(o.mesh)
1408 elif hasattr(o, "_narrow"):
1409 src = o._narrow(SMESH.SMESH_IDSource)
1410 if src: srclist.append(src)
1413 aMeasurements = self.CreateMeasurements()
1414 result = aMeasurements.BoundingBox(srclist)
1415 aMeasurements.UnRegister()
1418 def GetLength(self, obj):
1420 Get sum of lengths of all 1D elements in the mesh object.
1423 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1426 sum of lengths of all 1D elements
1429 if isinstance(obj, Mesh): obj = obj.mesh
1430 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1431 aMeasurements = self.CreateMeasurements()
1432 value = aMeasurements.Length(obj)
1433 aMeasurements.UnRegister()
1436 def GetArea(self, obj):
1438 Get sum of areas of all 2D elements in the mesh object.
1441 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1444 sum of areas of all 2D elements
1447 if isinstance(obj, Mesh): obj = obj.mesh
1448 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1449 aMeasurements = self.CreateMeasurements()
1450 value = aMeasurements.Area(obj)
1451 aMeasurements.UnRegister()
1454 def GetVolume(self, obj):
1456 Get sum of volumes of all 3D elements in the mesh object.
1459 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1462 sum of volumes of all 3D elements
1465 if isinstance(obj, Mesh): obj = obj.mesh
1466 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1467 aMeasurements = self.CreateMeasurements()
1468 value = aMeasurements.Volume(obj)
1469 aMeasurements.UnRegister()
1472 def GetGravityCenter(self, obj):
1474 Get gravity center of all nodes of a mesh object.
1477 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1480 Three components of the gravity center (x,y,z)
1483 :meth:`Mesh.BaryCenter`
1485 if isinstance(obj, Mesh): obj = obj.mesh
1486 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1487 aMeasurements = self.CreateMeasurements()
1488 pointStruct = aMeasurements.GravityCenter(obj)
1489 aMeasurements.UnRegister()
1490 return pointStruct.x, pointStruct.y, pointStruct.z
1492 def GetAngle(self, p1, p2, p3 ):
1494 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1497 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1503 if isinstance( p1, list ): p1 = PointStruct(*p1)
1504 if isinstance( p2, list ): p2 = PointStruct(*p2)
1505 if isinstance( p3, list ): p3 = PointStruct(*p3)
1507 aMeasurements = self.CreateMeasurements()
1508 angle = aMeasurements.Angle(p1,p2,p3)
1509 aMeasurements.UnRegister()
1514 pass # end of class smeshBuilder
1517 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1518 """Registering the new proxy for SMESH.SMESH_Gen"""
1521 def New( instance=None, instanceGeom=None):
1523 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1524 interface to create or load meshes.
1529 salome.salome_init()
1530 from salome.smesh import smeshBuilder
1531 smesh = smeshBuilder.New()
1534 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1535 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1537 :class:`smeshBuilder` instance
1542 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1544 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1549 smeshInst = smeshBuilder()
1550 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1551 smeshInst.init_smesh(instanceGeom)
1555 # Public class: Mesh
1556 # ==================
1559 class Mesh(metaclass = MeshMeta):
1561 This class allows defining and managing a mesh.
1562 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1563 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1564 new nodes and elements and by changing the existing entities), to get information
1565 about a mesh and to export a mesh in different formats.
1572 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1577 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1578 sets the GUI name of this mesh to *name*.
1581 smeshpyD: an instance of smeshBuilder class
1582 geompyD: an instance of geomBuilder class
1583 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1584 name: Study name of the mesh
1587 self.smeshpyD = smeshpyD
1588 self.geompyD = geompyD
1593 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1596 # publish geom of mesh (issue 0021122)
1597 if not self.geom.GetStudyEntry():
1601 geo_name = name + " shape"
1603 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1604 geompyD.addToStudy( self.geom, geo_name )
1605 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1607 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1610 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1612 self.smeshpyD.SetName(self.mesh, name)
1614 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1617 self.geom = self.mesh.GetShapeToMesh()
1619 self.editor = self.mesh.GetMeshEditor()
1620 self.functors = [None] * SMESH.FT_Undefined._v
1622 # set self to algoCreator's
1623 for attrName in dir(self):
1624 attr = getattr( self, attrName )
1625 if isinstance( attr, algoCreator ):
1626 setattr( self, attrName, attr.copy( self ))
1633 Destructor. Clean-up resources
1636 #self.mesh.UnRegister()
1640 def SetMesh(self, theMesh):
1642 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1645 theMesh: a :class:`SMESH.SMESH_Mesh` object
1647 # do not call Register() as this prevents mesh servant deletion at closing study
1648 #if self.mesh: self.mesh.UnRegister()
1651 #self.mesh.Register()
1652 self.geom = self.mesh.GetShapeToMesh()
1656 if salome.sg.hasDesktop():
1657 so = salome.ObjectToSObject( self.geom )
1658 comp = so.GetFatherComponent()
1659 if comp.ComponentDataType() == "SHAPERSTUDY":
1660 import shaperBuilder
1661 self.geompyD = shaperBuilder.New()
1664 if not self.geompyD:
1665 self.geompyD = self.geom.GetGen()
1670 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1673 a :class:`SMESH.SMESH_Mesh` object
1678 def GetEngine(self):
1680 Return a smeshBuilder instance created this mesh
1682 return self.smeshpyD
1684 def GetGeomEngine(self):
1686 Return a geomBuilder instance
1692 Get the name of the mesh
1695 the name of the mesh as a string
1698 name = GetName(self.GetMesh())
1701 def SetName(self, name):
1703 Set a name to the mesh
1706 name: a new name of the mesh
1709 self.smeshpyD.SetName(self.GetMesh(), name)
1711 def GetSubMesh(self, geom, name):
1713 Get a sub-mesh object associated to a *geom* geometrical object.
1716 geom: a geometrical object (shape)
1717 name: a name for the sub-mesh in the Object Browser
1720 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1721 which lies on the given shape
1724 A sub-mesh is implicitly created when a sub-shape is specified at
1725 creating an algorithm, for example::
1727 algo1D = mesh.Segment(geom=Edge_1)
1729 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1730 The created sub-mesh can be retrieved from the algorithm::
1732 submesh = algo1D.GetSubMesh()
1735 AssureGeomPublished( self, geom, name )
1736 submesh = self.mesh.GetSubMesh( geom, name )
1741 Return the shape associated to the mesh
1749 def SetShape(self, geom):
1751 Associate the given shape to the mesh (entails the recreation of the mesh)
1754 geom: the shape to be meshed (GEOM_Object)
1757 self.mesh = self.smeshpyD.CreateMesh(geom)
1759 def HasShapeToMesh(self):
1761 Return ``True`` if this mesh is based on geometry
1763 return self.mesh.HasShapeToMesh()
1767 Load mesh from the study after opening the study
1771 def IsReadyToCompute(self, theSubObject):
1773 Return true if the hypotheses are defined well
1776 theSubObject: a sub-shape of a mesh shape
1782 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1784 def GetAlgoState(self, theSubObject):
1786 Return errors of hypotheses definition.
1787 The list of errors is empty if everything is OK.
1790 theSubObject: a sub-shape of a mesh shape
1796 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1798 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1800 Return a geometrical object on which the given element was built.
1801 The returned geometrical object, if not nil, is either found in the
1802 study or published by this method with the given name
1805 theElementID: the id of the mesh element
1806 theGeomName: the user-defined name of the geometrical object
1809 GEOM.GEOM_Object instance
1812 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1814 def MeshDimension(self):
1816 Return the mesh dimension depending on the dimension of the underlying shape
1817 or, if the mesh is not based on any shape, basing on deimension of elements
1820 mesh dimension as an integer value [0,3]
1823 if self.mesh.HasShapeToMesh():
1824 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1825 if len( shells ) > 0 :
1827 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1829 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1834 if self.NbVolumes() > 0: return 3
1835 if self.NbFaces() > 0: return 2
1836 if self.NbEdges() > 0: return 1
1839 def Evaluate(self, geom=0):
1841 Evaluate size of prospective mesh on a shape
1844 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1845 To know predicted number of e.g. edges, inquire it this way::
1847 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1850 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1852 geom = self.mesh.GetShapeToMesh()
1855 return self.smeshpyD.Evaluate(self.mesh, geom)
1858 def Compute(self, geom=0, discardModifs=False, refresh=False):
1860 Compute the mesh and return the status of the computation
1863 geom: geomtrical shape on which mesh data should be computed
1864 discardModifs: if True and the mesh has been edited since
1865 a last total re-compute and that may prevent successful partial re-compute,
1866 then the mesh is cleaned before Compute()
1867 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1873 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1874 geom = self.mesh.GetShapeToMesh()
1877 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1879 ok = self.smeshpyD.Compute(self.mesh, geom)
1880 except SALOME.SALOME_Exception as ex:
1881 print("Mesh computation failed, exception caught:")
1882 print(" ", ex.details.text)
1885 print("Mesh computation failed, exception caught:")
1886 traceback.print_exc()
1890 # Treat compute errors
1891 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1893 for err in computeErrors:
1894 if self.mesh.HasShapeToMesh():
1895 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1897 stdErrors = ["OK", #COMPERR_OK
1898 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1899 "std::exception", #COMPERR_STD_EXCEPTION
1900 "OCC exception", #COMPERR_OCC_EXCEPTION
1901 "..", #COMPERR_SLM_EXCEPTION
1902 "Unknown exception", #COMPERR_EXCEPTION
1903 "Memory allocation problem", #COMPERR_MEMORY_PB
1904 "Algorithm failed", #COMPERR_ALGO_FAILED
1905 "Unexpected geometry", #COMPERR_BAD_SHAPE
1906 "Warning", #COMPERR_WARNING
1907 "Computation cancelled",#COMPERR_CANCELED
1908 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1910 if err.code < len(stdErrors): errText = stdErrors[err.code]
1912 errText = "code %s" % -err.code
1913 if errText: errText += ". "
1914 errText += err.comment
1915 if allReasons: allReasons += "\n"
1917 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1919 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1923 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1925 if err.isGlobalAlgo:
1933 reason = '%s %sD algorithm is missing' % (glob, dim)
1934 elif err.state == HYP_MISSING:
1935 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1936 % (glob, dim, name, dim))
1937 elif err.state == HYP_NOTCONFORM:
1938 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1939 elif err.state == HYP_BAD_PARAMETER:
1940 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1941 % ( glob, dim, name ))
1942 elif err.state == HYP_BAD_GEOMETRY:
1943 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1944 'geometry' % ( glob, dim, name ))
1945 elif err.state == HYP_HIDDEN_ALGO:
1946 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1947 'algorithm of upper dimension generating %sD mesh'
1948 % ( glob, dim, name, glob, dim ))
1950 reason = ("For unknown reason. "
1951 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1953 if allReasons: allReasons += "\n"
1954 allReasons += "- " + reason
1956 if not ok or allReasons != "":
1957 msg = '"' + GetName(self.mesh) + '"'
1958 if ok: msg += " has been computed with warnings"
1959 else: msg += " has not been computed"
1960 if allReasons != "": msg += ":"
1966 if salome.sg.hasDesktop():
1967 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1968 if refresh: salome.sg.updateObjBrowser()
1972 def GetComputeErrors(self, shape=0 ):
1974 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1978 shape = self.mesh.GetShapeToMesh()
1979 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1981 def GetSubShapeName(self, subShapeID ):
1983 Return a name of a sub-shape by its ID.
1984 Possible variants (for *subShapeID* == 3):
1986 - **"Face_12"** - published sub-shape
1987 - **FACE #3** - not published sub-shape
1988 - **sub-shape #3** - invalid sub-shape ID
1989 - **#3** - error in this function
1992 subShapeID: a unique ID of a sub-shape
1995 a string describing the sub-shape
1999 if not self.mesh.HasShapeToMesh():
2003 mainIOR = salome.orb.object_to_string( self.GetShape() )
2005 mainSO = s.FindObjectIOR(mainIOR)
2008 shapeText = '"%s"' % mainSO.GetName()
2009 subIt = s.NewChildIterator(mainSO)
2011 subSO = subIt.Value()
2013 obj = subSO.GetObject()
2014 if not obj: continue
2015 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2018 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2021 if ids == subShapeID:
2022 shapeText = '"%s"' % subSO.GetName()
2025 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2027 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2029 shapeText = 'sub-shape #%s' % (subShapeID)
2031 shapeText = "#%s" % (subShapeID)
2034 def GetFailedShapes(self, publish=False):
2036 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2037 error of an algorithm
2040 publish: if *True*, the returned groups will be published in the study
2043 a list of GEOM groups each named after a failed algorithm
2048 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2049 for err in computeErrors:
2050 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2051 if not shape: continue
2052 if err.algoName in algo2shapes:
2053 algo2shapes[ err.algoName ].append( shape )
2055 algo2shapes[ err.algoName ] = [ shape ]
2059 for algoName, shapes in list(algo2shapes.items()):
2061 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2062 otherTypeShapes = []
2064 group = self.geompyD.CreateGroup( self.geom, groupType )
2065 for shape in shapes:
2066 if shape.GetShapeType() == shapes[0].GetShapeType():
2067 sameTypeShapes.append( shape )
2069 otherTypeShapes.append( shape )
2070 self.geompyD.UnionList( group, sameTypeShapes )
2072 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2074 group.SetName( algoName )
2075 groups.append( group )
2076 shapes = otherTypeShapes
2079 for group in groups:
2080 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2083 def GetMeshOrder(self):
2085 Return sub-mesh objects list in meshing order
2088 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2091 return self.mesh.GetMeshOrder()
2093 def SetMeshOrder(self, submeshes):
2095 Set priority of sub-meshes. It works in two ways:
2097 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2098 *several dimensions*, it sets the order in which the sub-meshes are computed.
2099 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2100 when looking for meshing parameters to apply to a sub-shape. To impose the
2101 order in which sub-meshes with uni-dimensional algorithms are computed,
2102 call **submesh.Compute()** in a desired order.
2105 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2107 Warning: the method is for setting the order for all sub-meshes at once:
2108 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2111 return self.mesh.SetMeshOrder(submeshes)
2113 def Clear(self, refresh=False):
2115 Remove all nodes and elements generated on geometry. Imported elements remain.
2118 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2122 if ( salome.sg.hasDesktop() ):
2123 if refresh: salome.sg.updateObjBrowser()
2125 def ClearSubMesh(self, geomId, refresh=False):
2127 Remove all nodes and elements of indicated shape
2130 geomId: the ID of a sub-shape to remove elements on
2131 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2134 self.mesh.ClearSubMesh(geomId)
2135 if salome.sg.hasDesktop():
2136 if refresh: salome.sg.updateObjBrowser()
2138 def AutomaticTetrahedralization(self, fineness=0):
2140 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2143 fineness: [0.0,1.0] defines mesh fineness
2149 dim = self.MeshDimension()
2151 self.RemoveGlobalHypotheses()
2152 self.Segment().AutomaticLength(fineness)
2154 self.Triangle().LengthFromEdges()
2159 return self.Compute()
2161 def AutomaticHexahedralization(self, fineness=0):
2163 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2166 fineness: [0.0, 1.0] defines mesh fineness
2172 dim = self.MeshDimension()
2173 # assign the hypotheses
2174 self.RemoveGlobalHypotheses()
2175 self.Segment().AutomaticLength(fineness)
2182 return self.Compute()
2184 def AddHypothesis(self, hyp, geom=0):
2189 hyp: a hypothesis to assign
2190 geom: a subhape of mesh geometry
2193 :class:`SMESH.Hypothesis_Status`
2196 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2197 hyp, geom = geom, hyp
2198 if isinstance( hyp, Mesh_Algorithm ):
2199 hyp = hyp.GetAlgorithm()
2204 geom = self.mesh.GetShapeToMesh()
2207 if self.mesh.HasShapeToMesh():
2208 hyp_type = hyp.GetName()
2209 lib_name = hyp.GetLibName()
2210 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2211 # if checkAll and geom:
2212 # checkAll = geom.GetType() == 37
2214 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2216 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2217 status = self.mesh.AddHypothesis(geom, hyp)
2219 status = HYP_BAD_GEOMETRY, ""
2220 hyp_name = GetName( hyp )
2223 geom_name = geom.GetName()
2224 isAlgo = hyp._narrow( SMESH_Algo )
2225 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2228 def IsUsedHypothesis(self, hyp, geom):
2230 Return True if an algorithm or hypothesis is assigned to a given shape
2233 hyp: an algorithm or hypothesis to check
2234 geom: a subhape of mesh geometry
2240 if not hyp: # or not geom
2242 if isinstance( hyp, Mesh_Algorithm ):
2243 hyp = hyp.GetAlgorithm()
2245 hyps = self.GetHypothesisList(geom)
2247 if h.GetId() == hyp.GetId():
2251 def RemoveHypothesis(self, hyp, geom=0):
2253 Unassign a hypothesis
2256 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2257 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2260 :class:`SMESH.Hypothesis_Status`
2265 if isinstance( hyp, Mesh_Algorithm ):
2266 hyp = hyp.GetAlgorithm()
2272 if self.IsUsedHypothesis( hyp, shape ):
2273 return self.mesh.RemoveHypothesis( shape, hyp )
2274 hypName = GetName( hyp )
2275 geoName = GetName( shape )
2276 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2279 def GetHypothesisList(self, geom):
2281 Get the list of hypotheses added on a geometry
2284 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2287 the sequence of :class:`SMESH.SMESH_Hypothesis`
2290 return self.mesh.GetHypothesisList( geom )
2292 def RemoveGlobalHypotheses(self):
2294 Remove all global hypotheses
2297 current_hyps = self.mesh.GetHypothesisList( self.geom )
2298 for hyp in current_hyps:
2299 self.mesh.RemoveHypothesis( self.geom, hyp )
2302 def ExportMED(self, *args, **kwargs):
2304 Export the mesh in a file in MED format
2305 allowing to overwrite the file if it exists or add the exported data to its contents
2308 fileName: is the file name
2309 auto_groups (boolean): parameter for creating/not creating
2310 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2311 the typical use is auto_groups=False.
2312 version (int): define the version (xy, where version is x.y.z) of MED file format.
2313 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2314 The rules of compatibility to write a mesh in an older version than
2315 the current version depend on the current version. For instance,
2316 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2317 or 3.2.1 or 3.3.1 formats.
2318 If the version is equal to -1, the version is not changed (default).
2319 overwrite (boolean): parameter for overwriting/not overwriting the file
2320 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2321 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2323 - 1D if all mesh nodes lie on OX coordinate axis, or
2324 - 2D if all mesh nodes lie on XOY coordinate plane, or
2325 - 3D in the rest cases.
2327 If *autoDimension* is *False*, the space dimension is always 3.
2328 fields: list of GEOM fields defined on the shape to mesh.
2329 geomAssocFields: each character of this string means a need to export a
2330 corresponding field; correspondence between fields and characters
2333 - 'v' stands for "_vertices_" field;
2334 - 'e' stands for "_edges_" field;
2335 - 'f' stands for "_faces_" field;
2336 - 's' stands for "_solids_" field.
2338 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2339 close to zero within a given tolerance, the coordinate is set to zero.
2340 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2342 # process positional arguments
2343 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2345 auto_groups = args[1] if len(args) > 1 else False
2346 version = args[2] if len(args) > 2 else -1
2347 overwrite = args[3] if len(args) > 3 else True
2348 meshPart = args[4] if len(args) > 4 else None
2349 autoDimension = args[5] if len(args) > 5 else True
2350 fields = args[6] if len(args) > 6 else []
2351 geomAssocFields = args[7] if len(args) > 7 else ''
2352 z_tolerance = args[8] if len(args) > 8 else -1.
2353 # process keywords arguments
2354 auto_groups = kwargs.get("auto_groups", auto_groups)
2355 version = kwargs.get("version", version)
2356 version = kwargs.get("minor", version)
2357 overwrite = kwargs.get("overwrite", overwrite)
2358 meshPart = kwargs.get("meshPart", meshPart)
2359 autoDimension = kwargs.get("autoDimension", autoDimension)
2360 fields = kwargs.get("fields", fields)
2361 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2362 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2364 # invoke engine's function
2365 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2366 unRegister = genObjUnRegister()
2367 if isinstance( meshPart, list ):
2368 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2369 unRegister.set( meshPart )
2371 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2372 self.mesh.SetParameters(Parameters)
2374 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2375 version, overwrite, autoDimension,
2376 fields, geomAssocFields, z_tolerance)
2378 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2380 def ExportSAUV(self, f, auto_groups=0):
2382 Export the mesh in a file in SAUV format
2387 auto_groups: boolean parameter for creating/not creating
2388 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2389 the typical use is auto_groups=False.
2392 self.mesh.ExportSAUV(f, auto_groups)
2394 def ExportDAT(self, f, meshPart=None):
2396 Export the mesh in a file in DAT format
2400 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2404 unRegister = genObjUnRegister()
2405 if isinstance( meshPart, list ):
2406 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2407 unRegister.set( meshPart )
2408 self.mesh.ExportPartToDAT( meshPart, f )
2410 self.mesh.ExportDAT(f)
2412 def ExportUNV(self, f, meshPart=None):
2414 Export the mesh in a file in UNV format
2418 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2422 unRegister = genObjUnRegister()
2423 if isinstance( meshPart, list ):
2424 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2425 unRegister.set( meshPart )
2426 self.mesh.ExportPartToUNV( meshPart, f )
2428 self.mesh.ExportUNV(f)
2430 def ExportSTL(self, f, ascii=1, meshPart=None):
2432 Export the mesh in a file in STL format
2436 ascii: defines the file encoding
2437 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2441 unRegister = genObjUnRegister()
2442 if isinstance( meshPart, list ):
2443 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2444 unRegister.set( meshPart )
2445 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2447 self.mesh.ExportSTL(f, ascii)
2449 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2451 Export the mesh in a file in CGNS format
2455 overwrite: boolean parameter for overwriting/not overwriting the file
2456 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2457 groupElemsByType: if True all elements of same entity type are exported at ones,
2458 else elements are exported in order of their IDs which can cause creation
2459 of multiple cgns sections
2462 unRegister = genObjUnRegister()
2463 if isinstance( meshPart, list ):
2464 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2465 unRegister.set( meshPart )
2466 if isinstance( meshPart, Mesh ):
2467 meshPart = meshPart.mesh
2469 meshPart = self.mesh
2470 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2472 def ExportGMF(self, f, meshPart=None):
2474 Export the mesh in a file in GMF format.
2475 GMF files must have .mesh extension for the ASCII format and .meshb for
2476 the bynary format. Other extensions are not allowed.
2480 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2483 unRegister = genObjUnRegister()
2484 if isinstance( meshPart, list ):
2485 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2486 unRegister.set( meshPart )
2487 if isinstance( meshPart, Mesh ):
2488 meshPart = meshPart.mesh
2490 meshPart = self.mesh
2491 self.mesh.ExportGMF(meshPart, f, True)
2493 def ExportToMED(self, *args, **kwargs):
2495 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2496 Export the mesh in a file in MED format
2497 allowing to overwrite the file if it exists or add the exported data to its contents
2500 fileName: the file name
2501 opt (boolean): parameter for creating/not creating
2502 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2503 overwrite: boolean parameter for overwriting/not overwriting the file
2504 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2506 - 1D if all mesh nodes lie on OX coordinate axis, or
2507 - 2D if all mesh nodes lie on XOY coordinate plane, or
2508 - 3D in the rest cases.
2510 If **autoDimension** is *False*, the space dimension is always 3.
2513 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2514 # process positional arguments
2515 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2517 auto_groups = args[1] if len(args) > 1 else False
2518 overwrite = args[2] if len(args) > 2 else True
2519 autoDimension = args[3] if len(args) > 3 else True
2520 # process keywords arguments
2521 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2522 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2523 overwrite = kwargs.get("overwrite", overwrite)
2524 autoDimension = kwargs.get("autoDimension", autoDimension)
2526 # invoke engine's function
2527 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2529 def ExportToMEDX(self, *args, **kwargs):
2531 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2532 Export the mesh in a file in MED format
2535 fileName: the file name
2536 opt (boolean): parameter for creating/not creating
2537 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2538 overwrite: boolean parameter for overwriting/not overwriting the file
2539 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2541 - 1D if all mesh nodes lie on OX coordinate axis, or
2542 - 2D if all mesh nodes lie on XOY coordinate plane, or
2543 - 3D in the rest cases.
2545 If **autoDimension** is *False*, the space dimension is always 3.
2548 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2549 # process positional arguments
2550 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2552 auto_groups = args[1] if len(args) > 1 else False
2553 overwrite = args[2] if len(args) > 2 else True
2554 autoDimension = args[3] if len(args) > 3 else True
2555 # process keywords arguments
2556 auto_groups = kwargs.get("auto_groups", auto_groups)
2557 overwrite = kwargs.get("overwrite", overwrite)
2558 autoDimension = kwargs.get("autoDimension", autoDimension)
2560 # invoke engine's function
2561 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2565 def Append(self, meshes, uniteIdenticalGroups = True,
2566 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2568 Append given meshes into this mesh.
2569 All groups of input meshes will be created in this mesh.
2572 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2573 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2574 mergeNodesAndElements: if True, equal nodes and elements are merged
2575 mergeTolerance: tolerance for merging nodes
2576 allGroups: forces creation of groups corresponding to every input mesh
2578 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2579 mergeNodesAndElements, mergeTolerance, allGroups,
2580 meshToAppendTo = self.GetMesh() )
2582 # Operations with groups:
2583 # ----------------------
2584 def CreateEmptyGroup(self, elementType, name):
2586 Create an empty standalone mesh group
2589 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2590 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2591 name: the name of the mesh group
2594 :class:`SMESH.SMESH_Group`
2597 return self.mesh.CreateGroup(elementType, name)
2599 def Group(self, grp, name=""):
2601 Create a mesh group based on the geometric object *grp*
2602 and give it a *name*.
2603 If *name* is not defined the name of the geometric group is used
2606 Works like :meth:`GroupOnGeom`.
2609 grp: a geometric group, a vertex, an edge, a face or a solid
2610 name: the name of the mesh group
2613 :class:`SMESH.SMESH_GroupOnGeom`
2616 return self.GroupOnGeom(grp, name)
2618 def GroupOnGeom(self, grp, name="", typ=None):
2620 Create a mesh group based on the geometrical object *grp*
2621 and give it a *name*.
2622 if *name* is not defined the name of the geometric group is used
2625 grp: a geometrical group, a vertex, an edge, a face or a solid
2626 name: the name of the mesh group
2627 typ: the type of elements in the group; either of
2628 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2629 automatically detected by the type of the geometry
2632 :class:`SMESH.SMESH_GroupOnGeom`
2635 AssureGeomPublished( self, grp, name )
2637 name = grp.GetName()
2639 typ = self._groupTypeFromShape( grp )
2640 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2642 def _groupTypeFromShape( self, shape ):
2644 Pivate method to get a type of group on geometry
2646 tgeo = str(shape.GetShapeType())
2647 if tgeo == "VERTEX":
2649 elif tgeo == "EDGE" or tgeo == "WIRE":
2651 elif tgeo == "FACE" or tgeo == "SHELL":
2653 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2655 elif tgeo == "COMPOUND":
2657 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2659 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2660 # simplification of access in geomBuilder: omniORB.registerObjref
2661 from SHAPERSTUDY_utils import getEngine
2664 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2666 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2667 return self._groupTypeFromShape( sub[0] )
2669 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2672 def GroupOnFilter(self, typ, name, filter):
2674 Create a mesh group with given *name* based on the *filter*.
2675 It is a special type of group dynamically updating it's contents during
2679 typ: the type of elements in the group; either of
2680 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2681 name: the name of the mesh group
2682 filter (SMESH.Filter): the filter defining group contents
2685 :class:`SMESH.SMESH_GroupOnFilter`
2688 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2690 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2692 Create a mesh group by the given ids of elements
2695 groupName: the name of the mesh group
2696 elementType: the type of elements in the group; either of
2697 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2698 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2701 :class:`SMESH.SMESH_Group`
2704 group = self.mesh.CreateGroup(elementType, groupName)
2705 if isinstance( elemIDs, Mesh ):
2706 elemIDs = elemIDs.GetMesh()
2707 if hasattr( elemIDs, "GetIDs" ):
2708 if hasattr( elemIDs, "SetMesh" ):
2709 elemIDs.SetMesh( self.GetMesh() )
2710 group.AddFrom( elemIDs )
2718 CritType=FT_Undefined,
2721 UnaryOp=FT_Undefined,
2724 Create a mesh group by the given conditions
2727 groupName: the name of the mesh group
2728 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2729 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2730 Note that the items starting from FT_LessThan are not suitable for CritType.
2731 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2732 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2733 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2734 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2735 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2738 :class:`SMESH.SMESH_GroupOnFilter`
2741 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2742 group = self.MakeGroupByCriterion(groupName, aCriterion)
2745 def MakeGroupByCriterion(self, groupName, Criterion):
2747 Create a mesh group by the given criterion
2750 groupName: the name of the mesh group
2751 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2754 :class:`SMESH.SMESH_GroupOnFilter`
2757 :meth:`smeshBuilder.GetCriterion`
2760 return self.MakeGroupByCriteria( groupName, [Criterion] )
2762 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2764 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2767 groupName: the name of the mesh group
2768 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2769 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2772 :class:`SMESH.SMESH_GroupOnFilter`
2775 :meth:`smeshBuilder.GetCriterion`
2778 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2779 group = self.MakeGroupByFilter(groupName, aFilter)
2782 def MakeGroupByFilter(self, groupName, theFilter):
2784 Create a mesh group by the given filter
2787 groupName (string): the name of the mesh group
2788 theFilter (SMESH.Filter): the filter
2791 :class:`SMESH.SMESH_GroupOnFilter`
2794 :meth:`smeshBuilder.GetFilter`
2797 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2798 #theFilter.SetMesh( self.mesh )
2799 #group.AddFrom( theFilter )
2800 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2803 def RemoveGroup(self, group):
2808 group (SMESH.SMESH_GroupBase): group to remove
2811 self.mesh.RemoveGroup(group)
2813 def RemoveGroupWithContents(self, group):
2815 Remove a group with its contents
2818 group (SMESH.SMESH_GroupBase): group to remove
2821 This operation can create gaps in numeration of nodes or elements.
2822 Call :meth:`RenumberElements` to remove the gaps.
2825 self.mesh.RemoveGroupWithContents(group)
2827 def GetGroups(self, elemType = SMESH.ALL):
2829 Get the list of groups existing in the mesh in the order of creation
2830 (starting from the oldest one)
2833 elemType (SMESH.ElementType): type of elements the groups contain;
2834 by default groups of elements of all types are returned
2837 a list of :class:`SMESH.SMESH_GroupBase`
2840 groups = self.mesh.GetGroups()
2841 if elemType == SMESH.ALL:
2845 if g.GetType() == elemType:
2846 typedGroups.append( g )
2853 Get the number of groups existing in the mesh
2856 the quantity of groups as an integer value
2859 return self.mesh.NbGroups()
2861 def GetGroupNames(self):
2863 Get the list of names of groups existing in the mesh
2869 groups = self.GetGroups()
2871 for group in groups:
2872 names.append(group.GetName())
2875 def GetGroupByName(self, name, elemType = None):
2877 Find groups by name and type
2880 name (string): name of the group of interest
2881 elemType (SMESH.ElementType): type of elements the groups contain;
2882 by default one group of any type is returned;
2883 if elemType == SMESH.ALL then all groups of any type are returned
2886 a list of :class:`SMESH.SMESH_GroupBase`
2890 for group in self.GetGroups():
2891 if group.GetName() == name:
2892 if elemType is None:
2894 if ( elemType == SMESH.ALL or
2895 group.GetType() == elemType ):
2896 groups.append( group )
2899 def UnionGroups(self, group1, group2, name):
2901 Produce a union of two groups.
2902 A new group is created. All mesh elements that are
2903 present in the initial groups are added to the new one
2906 group1 (SMESH.SMESH_GroupBase): a group
2907 group2 (SMESH.SMESH_GroupBase): another group
2910 instance of :class:`SMESH.SMESH_Group`
2913 return self.mesh.UnionGroups(group1, group2, name)
2915 def UnionListOfGroups(self, groups, name):
2917 Produce a union list of groups.
2918 New group is created. All mesh elements that are present in
2919 initial groups are added to the new one
2922 groups: list of :class:`SMESH.SMESH_GroupBase`
2925 instance of :class:`SMESH.SMESH_Group`
2927 return self.mesh.UnionListOfGroups(groups, name)
2929 def IntersectGroups(self, group1, group2, name):
2931 Prodice an intersection of two groups.
2932 A new group is created. All mesh elements that are common
2933 for the two initial groups are added to the new one.
2936 group1 (SMESH.SMESH_GroupBase): a group
2937 group2 (SMESH.SMESH_GroupBase): another group
2940 instance of :class:`SMESH.SMESH_Group`
2943 return self.mesh.IntersectGroups(group1, group2, name)
2945 def IntersectListOfGroups(self, groups, name):
2947 Produce an intersection of groups.
2948 New group is created. All mesh elements that are present in all
2949 initial groups simultaneously are added to the new one
2952 groups: a list of :class:`SMESH.SMESH_GroupBase`
2955 instance of :class:`SMESH.SMESH_Group`
2957 return self.mesh.IntersectListOfGroups(groups, name)
2959 def CutGroups(self, main_group, tool_group, name):
2961 Produce a cut of two groups.
2962 A new group is created. All mesh elements that are present in
2963 the main group but are not present in the tool group are added to the new one
2966 main_group (SMESH.SMESH_GroupBase): a group to cut from
2967 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2970 an instance of :class:`SMESH.SMESH_Group`
2973 return self.mesh.CutGroups(main_group, tool_group, name)
2975 def CutListOfGroups(self, main_groups, tool_groups, name):
2977 Produce a cut of groups.
2978 A new group is created. All mesh elements that are present in main groups
2979 but do not present in tool groups are added to the new one
2982 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2983 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2986 an instance of :class:`SMESH.SMESH_Group`
2989 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2991 def CreateDimGroup(self, groups, elemType, name,
2992 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2994 Create a standalone group of entities basing on nodes of other groups.
2997 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2998 elemType: a type of elements to include to the new group; either of
2999 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3000 name: a name of the new group.
3001 nbCommonNodes: a criterion of inclusion of an element to the new group
3002 basing on number of element nodes common with reference *groups*.
3003 Meaning of possible values are:
3005 - SMESH.ALL_NODES - include if all nodes are common,
3006 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3007 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3008 - SMEHS.MAJORITY - include if half of nodes or more are common.
3009 underlyingOnly: if *True* (default), an element is included to the
3010 new group provided that it is based on nodes of an element of *groups*;
3011 in this case the reference *groups* are supposed to be of higher dimension
3012 than *elemType*, which can be useful for example to get all faces lying on
3013 volumes of the reference *groups*.
3016 an instance of :class:`SMESH.SMESH_Group`
3019 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3021 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3023 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3025 Distribute all faces of the mesh among groups using sharp edges and optionally
3026 existing 1D elements as group boundaries.
3029 sharpAngle: edge is considered sharp if an angle between normals of
3030 adjacent faces is more than \a sharpAngle in degrees.
3031 createEdges (boolean): to create 1D elements for detected sharp edges.
3032 useExistingEdges (boolean): to use existing edges as group boundaries
3034 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3036 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3037 self.mesh.SetParameters(Parameters)
3038 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3040 def ConvertToStandalone(self, group):
3042 Convert group on geom into standalone group
3045 return self.mesh.ConvertToStandalone(group)
3047 # Get some info about mesh:
3048 # ------------------------
3050 def GetLog(self, clearAfterGet):
3052 Return the log of nodes and elements added or removed
3053 since the previous clear of the log.
3056 clearAfterGet: log is emptied after Get (safe if concurrents access)
3059 list of SMESH.log_block structures { commandType, number, coords, indexes }
3062 return self.mesh.GetLog(clearAfterGet)
3066 Clear the log of nodes and elements added or removed since the previous
3067 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3070 self.mesh.ClearLog()
3072 def SetAutoColor(self, theAutoColor):
3074 Toggle auto color mode on the object.
3075 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3078 theAutoColor (boolean): the flag which toggles auto color mode.
3081 self.mesh.SetAutoColor(theAutoColor)
3083 def GetAutoColor(self):
3085 Get flag of object auto color mode.
3091 return self.mesh.GetAutoColor()
3098 integer value, which is the internal Id of the mesh
3101 return self.mesh.GetId()
3103 def HasDuplicatedGroupNamesMED(self):
3105 Check the group names for duplications.
3106 Consider the maximum group name length stored in MED file.
3112 return self.mesh.HasDuplicatedGroupNamesMED()
3114 def GetMeshEditor(self):
3116 Obtain the mesh editor tool
3119 an instance of :class:`SMESH.SMESH_MeshEditor`
3124 def GetIDSource(self, ids, elemType = SMESH.ALL):
3126 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3127 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3131 elemType: type of elements; this parameter is used to distinguish
3132 IDs of nodes from IDs of elements; by default ids are treated as
3133 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3136 an instance of :class:`SMESH.SMESH_IDSource`
3139 call UnRegister() for the returned object as soon as it is no more useful::
3141 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3142 mesh.DoSomething( idSrc )
3146 if isinstance( ids, int ):
3148 return self.editor.MakeIDSource(ids, elemType)
3151 # Get information about mesh contents:
3152 # ------------------------------------
3154 def GetMeshInfo(self, obj = None):
3156 Get the mesh statistic.
3159 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3162 if not obj: obj = self.mesh
3163 return self.smeshpyD.GetMeshInfo(obj)
3167 Return the number of nodes in the mesh
3173 return self.mesh.NbNodes()
3175 def NbElements(self):
3177 Return the number of elements in the mesh
3183 return self.mesh.NbElements()
3185 def Nb0DElements(self):
3187 Return the number of 0d elements in the mesh
3193 return self.mesh.Nb0DElements()
3197 Return the number of ball discrete elements in the mesh
3203 return self.mesh.NbBalls()
3207 Return the number of edges in the mesh
3213 return self.mesh.NbEdges()
3215 def NbEdgesOfOrder(self, elementOrder):
3217 Return the number of edges with the given order in the mesh
3220 elementOrder: the order of elements
3221 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3227 return self.mesh.NbEdgesOfOrder(elementOrder)
3231 Return the number of faces in the mesh
3237 return self.mesh.NbFaces()
3239 def NbFacesOfOrder(self, elementOrder):
3241 Return the number of faces with the given order in the mesh
3244 elementOrder: the order of elements
3245 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3251 return self.mesh.NbFacesOfOrder(elementOrder)
3253 def NbTriangles(self):
3255 Return the number of triangles in the mesh
3261 return self.mesh.NbTriangles()
3263 def NbTrianglesOfOrder(self, elementOrder):
3265 Return the number of triangles with the given order in the mesh
3268 elementOrder: is the order of elements
3269 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3275 return self.mesh.NbTrianglesOfOrder(elementOrder)
3277 def NbBiQuadTriangles(self):
3279 Return the number of biquadratic triangles in the mesh
3285 return self.mesh.NbBiQuadTriangles()
3287 def NbQuadrangles(self):
3289 Return the number of quadrangles in the mesh
3295 return self.mesh.NbQuadrangles()
3297 def NbQuadranglesOfOrder(self, elementOrder):
3299 Return the number of quadrangles with the given order in the mesh
3302 elementOrder: the order of elements
3303 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3309 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3311 def NbBiQuadQuadrangles(self):
3313 Return the number of biquadratic quadrangles in the mesh
3319 return self.mesh.NbBiQuadQuadrangles()
3321 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3323 Return the number of polygons of given order in the mesh
3326 elementOrder: the order of elements
3327 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3333 return self.mesh.NbPolygonsOfOrder(elementOrder)
3335 def NbVolumes(self):
3337 Return the number of volumes in the mesh
3343 return self.mesh.NbVolumes()
3346 def NbVolumesOfOrder(self, elementOrder):
3348 Return the number of volumes with the given order in the mesh
3351 elementOrder: the order of elements
3352 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3358 return self.mesh.NbVolumesOfOrder(elementOrder)
3362 Return the number of tetrahedrons in the mesh
3368 return self.mesh.NbTetras()
3370 def NbTetrasOfOrder(self, elementOrder):
3372 Return the number of tetrahedrons with the given order in the mesh
3375 elementOrder: the order of elements
3376 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3382 return self.mesh.NbTetrasOfOrder(elementOrder)
3386 Return the number of hexahedrons in the mesh
3392 return self.mesh.NbHexas()
3394 def NbHexasOfOrder(self, elementOrder):
3396 Return the number of hexahedrons with the given order in the mesh
3399 elementOrder: the order of elements
3400 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3406 return self.mesh.NbHexasOfOrder(elementOrder)
3408 def NbTriQuadraticHexas(self):
3410 Return the number of triquadratic hexahedrons in the mesh
3416 return self.mesh.NbTriQuadraticHexas()
3418 def NbPyramids(self):
3420 Return the number of pyramids in the mesh
3426 return self.mesh.NbPyramids()
3428 def NbPyramidsOfOrder(self, elementOrder):
3430 Return the number of pyramids with the given order in the mesh
3433 elementOrder: the order of elements
3434 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3440 return self.mesh.NbPyramidsOfOrder(elementOrder)
3444 Return the number of prisms in the mesh
3450 return self.mesh.NbPrisms()
3452 def NbPrismsOfOrder(self, elementOrder):
3454 Return the number of prisms with the given order in the mesh
3457 elementOrder: the order of elements
3458 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3464 return self.mesh.NbPrismsOfOrder(elementOrder)
3466 def NbHexagonalPrisms(self):
3468 Return the number of hexagonal prisms in the mesh
3474 return self.mesh.NbHexagonalPrisms()
3476 def NbPolyhedrons(self):
3478 Return the number of polyhedrons in the mesh
3484 return self.mesh.NbPolyhedrons()
3486 def NbSubMesh(self):
3488 Return the number of submeshes in the mesh
3494 return self.mesh.NbSubMesh()
3496 def GetElementsId(self):
3498 Return the list of all mesh elements IDs
3501 the list of integer values
3504 :meth:`GetElementsByType`
3507 return self.mesh.GetElementsId()
3509 def GetElementsByType(self, elementType):
3511 Return the list of IDs of mesh elements with the given type
3514 elementType (SMESH.ElementType): the required type of elements
3517 list of integer values
3520 return self.mesh.GetElementsByType(elementType)
3522 def GetNodesId(self):
3524 Return the list of mesh nodes IDs
3527 the list of integer values
3530 return self.mesh.GetNodesId()
3532 # Get the information about mesh elements:
3533 # ------------------------------------
3535 def GetElementType(self, id, iselem=True):
3537 Return the type of mesh element or node
3540 the value from :class:`SMESH.ElementType` enumeration.
3541 Return SMESH.ALL if element or node with the given ID does not exist
3544 return self.mesh.GetElementType(id, iselem)
3546 def GetElementGeomType(self, id):
3548 Return the geometric type of mesh element
3551 the value from :class:`SMESH.EntityType` enumeration.
3554 return self.mesh.GetElementGeomType(id)
3556 def GetElementShape(self, id):
3558 Return the shape type of mesh element
3561 the value from :class:`SMESH.GeometryType` enumeration.
3564 return self.mesh.GetElementShape(id)
3566 def GetSubMeshElementsId(self, Shape):
3568 Return the list of sub-mesh elements IDs
3571 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3572 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3575 list of integer values
3578 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3579 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3582 return self.mesh.GetSubMeshElementsId(ShapeID)
3584 def GetSubMeshNodesId(self, Shape, all):
3586 Return the list of sub-mesh nodes IDs
3589 Shape: a geom object (sub-shape).
3590 *Shape* must be the sub-shape of a :meth:`GetShape`
3591 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3594 list of integer values
3597 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3598 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3601 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3603 def GetSubMeshElementType(self, Shape):
3605 Return type of elements on given shape
3608 Shape: a geom object (sub-shape).
3609 *Shape* must be a sub-shape of a ShapeToMesh()
3612 :class:`SMESH.ElementType`
3615 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3616 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3619 return self.mesh.GetSubMeshElementType(ShapeID)
3623 Get the mesh description
3629 return self.mesh.Dump()
3632 # Get the information about nodes and elements of a mesh by its IDs:
3633 # -----------------------------------------------------------
3635 def GetNodeXYZ(self, id):
3637 Get XYZ coordinates of a node.
3638 If there is no node for the given ID - return an empty list
3641 list of float values
3644 return self.mesh.GetNodeXYZ(id)
3646 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3648 Return list of IDs of inverse elements for the given node.
3649 If there is no node for the given ID - return an empty list
3653 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3656 list of integer values
3659 return self.mesh.GetNodeInverseElements(id,elemType)
3661 def GetNodePosition(self,NodeID):
3663 Return the position of a node on the shape
3666 :class:`SMESH.NodePosition`
3669 return self.mesh.GetNodePosition(NodeID)
3671 def GetElementPosition(self,ElemID):
3673 Return the position of an element on the shape
3676 :class:`SMESH.ElementPosition`
3679 return self.mesh.GetElementPosition(ElemID)
3681 def GetShapeID(self, id):
3683 Return the ID of the shape, on which the given node was generated.
3686 an integer value > 0 or -1 if there is no node for the given
3687 ID or the node is not assigned to any geometry
3690 return self.mesh.GetShapeID(id)
3692 def GetShapeIDForElem(self,id):
3694 Return the ID of the shape, on which the given element was generated.
3697 an integer value > 0 or -1 if there is no element for the given
3698 ID or the element is not assigned to any geometry
3701 return self.mesh.GetShapeIDForElem(id)
3703 def GetElemNbNodes(self, id):
3705 Return the number of nodes of the given element
3708 an integer value > 0 or -1 if there is no element for the given ID
3711 return self.mesh.GetElemNbNodes(id)
3713 def GetElemNode(self, id, index):
3715 Return the node ID the given (zero based) index for the given element.
3717 * If there is no element for the given ID - return -1.
3718 * If there is no node for the given index - return -2.
3721 id (int): element ID
3722 index (int): node index within the element
3725 an integer value (ID)
3728 :meth:`GetElemNodes`
3731 return self.mesh.GetElemNode(id, index)
3733 def GetElemNodes(self, id):
3735 Return the IDs of nodes of the given element
3738 a list of integer values
3741 return self.mesh.GetElemNodes(id)
3743 def IsMediumNode(self, elementID, nodeID):
3745 Return true if the given node is the medium node in the given quadratic element
3748 return self.mesh.IsMediumNode(elementID, nodeID)
3750 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3752 Return true if the given node is the medium node in one of quadratic elements
3755 nodeID: ID of the node
3756 elementType: the type of elements to check a state of the node, either of
3757 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3760 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3762 def ElemNbEdges(self, id):
3764 Return the number of edges for the given element
3767 return self.mesh.ElemNbEdges(id)
3769 def ElemNbFaces(self, id):
3771 Return the number of faces for the given element
3774 return self.mesh.ElemNbFaces(id)
3776 def GetElemFaceNodes(self,elemId, faceIndex):
3778 Return nodes of given face (counted from zero) for given volumic element.
3781 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3783 def GetFaceNormal(self, faceId, normalized=False):
3785 Return three components of normal of given mesh face
3786 (or an empty array in KO case)
3789 return self.mesh.GetFaceNormal(faceId,normalized)
3791 def FindElementByNodes(self, nodes):
3793 Return an element based on all given nodes.
3796 return self.mesh.FindElementByNodes(nodes)
3798 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3800 Return elements including all given nodes.
3803 return self.mesh.GetElementsByNodes( nodes, elemType )
3805 def IsPoly(self, id):
3807 Return true if the given element is a polygon
3810 return self.mesh.IsPoly(id)
3812 def IsQuadratic(self, id):
3814 Return true if the given element is quadratic
3817 return self.mesh.IsQuadratic(id)
3819 def GetBallDiameter(self, id):
3821 Return diameter of a ball discrete element or zero in case of an invalid *id*
3824 return self.mesh.GetBallDiameter(id)
3826 def BaryCenter(self, id):
3828 Return XYZ coordinates of the barycenter of the given element.
3829 If there is no element for the given ID - return an empty list
3832 a list of three double values
3835 :meth:`smeshBuilder.GetGravityCenter`
3838 return self.mesh.BaryCenter(id)
3840 def GetIdsFromFilter(self, filter, meshParts=[] ):
3842 Pass mesh elements through the given filter and return IDs of fitting elements
3845 filter: :class:`SMESH.Filter`
3846 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3852 :meth:`SMESH.Filter.GetIDs`
3853 :meth:`SMESH.Filter.GetElementsIdFromParts`
3856 filter.SetMesh( self.mesh )
3859 if isinstance( meshParts, Mesh ):
3860 filter.SetMesh( meshParts.GetMesh() )
3861 return theFilter.GetIDs()
3862 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3863 meshParts = [ meshParts ]
3864 return filter.GetElementsIdFromParts( meshParts )
3866 return filter.GetIDs()
3868 # Get mesh measurements information:
3869 # ------------------------------------
3871 def GetFreeBorders(self):
3873 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3874 Return a list of special structures (borders).
3877 a list of :class:`SMESH.FreeEdges.Border`
3880 aFilterMgr = self.smeshpyD.CreateFilterManager()
3881 aPredicate = aFilterMgr.CreateFreeEdges()
3882 aPredicate.SetMesh(self.mesh)
3883 aBorders = aPredicate.GetBorders()
3884 aFilterMgr.UnRegister()
3887 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3889 Get minimum distance between two nodes, elements or distance to the origin
3892 id1: first node/element id
3893 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3894 isElem1: *True* if *id1* is element id, *False* if it is node id
3895 isElem2: *True* if *id2* is element id, *False* if it is node id
3898 minimum distance value
3900 :meth:`GetMinDistance`
3903 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3904 return aMeasure.value
3906 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3908 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3911 id1: first node/element id
3912 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3913 isElem1: *True* if *id1* is element id, *False* if it is node id
3914 isElem2: *True* if *id2* is element id, *False* if it is node id
3917 :class:`SMESH.Measure` structure
3923 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3925 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3928 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3930 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3935 aMeasurements = self.smeshpyD.CreateMeasurements()
3936 aMeasure = aMeasurements.MinDistance(id1, id2)
3937 genObjUnRegister([aMeasurements,id1, id2])
3940 def BoundingBox(self, objects=None, isElem=False):
3942 Get bounding box of the specified object(s)
3945 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3946 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3947 *False* specifies that *objects* are nodes
3950 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3953 :meth:`GetBoundingBox()`
3956 result = self.GetBoundingBox(objects, isElem)
3960 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3963 def GetBoundingBox(self, objects=None, isElem=False):
3965 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3968 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3969 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3970 False means that *objects* are nodes
3973 :class:`SMESH.Measure` structure
3976 :meth:`BoundingBox()`
3980 objects = [self.mesh]
3981 elif isinstance(objects, tuple):
3982 objects = list(objects)
3983 if not isinstance(objects, list):
3985 if len(objects) > 0 and isinstance(objects[0], int):
3988 unRegister = genObjUnRegister()
3990 if isinstance(o, Mesh):
3991 srclist.append(o.mesh)
3992 elif hasattr(o, "_narrow"):
3993 src = o._narrow(SMESH.SMESH_IDSource)
3994 if src: srclist.append(src)
3996 elif isinstance(o, list):
3998 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4000 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4001 unRegister.set( srclist[-1] )
4004 aMeasurements = self.smeshpyD.CreateMeasurements()
4005 unRegister.set( aMeasurements )
4006 aMeasure = aMeasurements.BoundingBox(srclist)
4009 # Mesh edition (SMESH_MeshEditor functionality):
4010 # ---------------------------------------------
4012 def RemoveElements(self, IDsOfElements):
4014 Remove the elements from the mesh by ids
4017 IDsOfElements: is a list of ids of elements to remove
4023 This operation can create gaps in numeration of elements.
4024 Call :meth:`RenumberElements` to remove the gaps.
4027 return self.editor.RemoveElements(IDsOfElements)
4029 def RemoveNodes(self, IDsOfNodes):
4031 Remove nodes from mesh by ids
4034 IDsOfNodes: is a list of ids of nodes to remove
4040 This operation can create gaps in numeration of nodes.
4041 Call :meth:`RenumberElements` to remove the gaps.
4044 return self.editor.RemoveNodes(IDsOfNodes)
4046 def RemoveOrphanNodes(self):
4048 Remove all orphan (free) nodes from mesh
4051 number of the removed nodes
4054 This operation can create gaps in numeration of nodes.
4055 Call :meth:`RenumberElements` to remove the gaps.
4058 return self.editor.RemoveOrphanNodes()
4060 def AddNode(self, x, y, z):
4062 Add a node to the mesh by coordinates
4068 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4069 if hasVars: self.mesh.SetParameters(Parameters)
4070 return self.editor.AddNode( x, y, z)
4072 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4074 Create a 0D element on a node with given number.
4077 IDOfNode: the ID of node for creation of the element.
4078 DuplicateElements: to add one more 0D element to a node or not
4081 ID of the new 0D element
4084 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4086 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4088 Create 0D elements on all nodes of the given elements except those
4089 nodes on which a 0D element already exists.
4092 theObject: an object on whose nodes 0D elements will be created.
4093 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4094 theGroupName: optional name of a group to add 0D elements created
4095 and/or found on nodes of *theObject*.
4096 DuplicateElements: to add one more 0D element to a node or not
4099 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4100 IDs of new and/or found 0D elements. IDs of 0D elements
4101 can be retrieved from the returned object by
4102 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4105 unRegister = genObjUnRegister()
4106 if isinstance( theObject, Mesh ):
4107 theObject = theObject.GetMesh()
4108 elif isinstance( theObject, list ):
4109 theObject = self.GetIDSource( theObject, SMESH.ALL )
4110 unRegister.set( theObject )
4111 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4113 def AddBall(self, IDOfNode, diameter):
4115 Create a ball element on a node with given ID.
4118 IDOfNode: the ID of node for creation of the element.
4119 diameter: the bal diameter.
4122 ID of the new ball element
4125 return self.editor.AddBall( IDOfNode, diameter )
4127 def AddEdge(self, IDsOfNodes):
4129 Create a linear or quadratic edge (this is determined
4130 by the number of given nodes).
4133 IDsOfNodes: list of node IDs for creation of the element.
4134 The order of nodes in this list should correspond to
4135 the :ref:`connectivity convention <connectivity_page>`.
4141 return self.editor.AddEdge(IDsOfNodes)
4143 def AddFace(self, IDsOfNodes):
4145 Create a linear or quadratic face (this is determined
4146 by the number of given nodes).
4149 IDsOfNodes: list of node IDs for creation of the element.
4150 The order of nodes in this list should correspond to
4151 the :ref:`connectivity convention <connectivity_page>`.
4157 return self.editor.AddFace(IDsOfNodes)
4159 def AddPolygonalFace(self, IdsOfNodes):
4161 Add a polygonal face defined by a list of node IDs
4164 IdsOfNodes: the list of node IDs for creation of the element.
4170 return self.editor.AddPolygonalFace(IdsOfNodes)
4172 def AddQuadPolygonalFace(self, IdsOfNodes):
4174 Add a quadratic polygonal face defined by a list of node IDs
4177 IdsOfNodes: the list of node IDs for creation of the element;
4178 corner nodes follow first.
4184 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4186 def AddVolume(self, IDsOfNodes):
4188 Create both simple and quadratic volume (this is determined
4189 by the number of given nodes).
4192 IDsOfNodes: list of node IDs for creation of the element.
4193 The order of nodes in this list should correspond to
4194 the :ref:`connectivity convention <connectivity_page>`.
4197 ID of the new volumic element
4200 return self.editor.AddVolume(IDsOfNodes)
4202 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4204 Create a volume of many faces, giving nodes for each face.
4207 IdsOfNodes: list of node IDs for volume creation, face by face.
4208 Quantities: list of integer values, Quantities[i]
4209 gives the quantity of nodes in face number i.
4212 ID of the new volumic element
4215 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4217 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4219 Create a volume of many faces, giving the IDs of the existing faces.
4222 The created volume will refer only to the nodes
4223 of the given faces, not to the faces themselves.
4226 IdsOfFaces: the list of face IDs for volume creation.
4229 ID of the new volumic element
4232 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4235 def SetNodeOnVertex(self, NodeID, Vertex):
4237 Bind a node to a vertex
4241 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4244 True if succeed else raises an exception
4247 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4248 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4252 self.editor.SetNodeOnVertex(NodeID, VertexID)
4253 except SALOME.SALOME_Exception as inst:
4254 raise ValueError(inst.details.text)
4258 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4260 Store the node position on an edge
4264 Edge: an edge (GEOM.GEOM_Object) or edge ID
4265 paramOnEdge: a parameter on the edge where the node is located
4268 True if succeed else raises an exception
4271 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4272 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4276 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4277 except SALOME.SALOME_Exception as inst:
4278 raise ValueError(inst.details.text)
4281 def SetNodeOnFace(self, NodeID, Face, u, v):
4283 Store node position on a face
4287 Face: a face (GEOM.GEOM_Object) or face ID
4288 u: U parameter on the face where the node is located
4289 v: V parameter on the face where the node is located
4292 True if succeed else raises an exception
4295 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4296 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4300 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4301 except SALOME.SALOME_Exception as inst:
4302 raise ValueError(inst.details.text)
4305 def SetNodeInVolume(self, NodeID, Solid):
4307 Bind a node to a solid
4311 Solid: a solid (GEOM.GEOM_Object) or solid ID
4314 True if succeed else raises an exception
4317 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4318 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4322 self.editor.SetNodeInVolume(NodeID, SolidID)
4323 except SALOME.SALOME_Exception as inst:
4324 raise ValueError(inst.details.text)
4327 def SetMeshElementOnShape(self, ElementID, Shape):
4329 Bind an element to a shape
4332 ElementID: an element ID
4333 Shape: a shape (GEOM.GEOM_Object) or shape ID
4336 True if succeed else raises an exception
4339 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4340 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4344 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4345 except SALOME.SALOME_Exception as inst:
4346 raise ValueError(inst.details.text)
4350 def MoveNode(self, NodeID, x, y, z):
4352 Move the node with the given id
4355 NodeID: the id of the node
4356 x: a new X coordinate
4357 y: a new Y coordinate
4358 z: a new Z coordinate
4361 True if succeed else False
4364 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4365 if hasVars: self.mesh.SetParameters(Parameters)
4366 return self.editor.MoveNode(NodeID, x, y, z)
4368 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4370 Find the node closest to a point and moves it to a point location
4373 x: the X coordinate of a point
4374 y: the Y coordinate of a point
4375 z: the Z coordinate of a point
4376 NodeID: if specified (>0), the node with this ID is moved,
4377 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4380 the ID of a moved node
4383 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4384 if hasVars: self.mesh.SetParameters(Parameters)
4385 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4387 def FindNodeClosestTo(self, x, y, z):
4389 Find the node closest to a point
4392 x: the X coordinate of a point
4393 y: the Y coordinate of a point
4394 z: the Z coordinate of a point
4400 return self.editor.FindNodeClosestTo(x, y, z)
4402 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4404 Find the elements where a point lays IN or ON
4407 x,y,z (float): coordinates of the point
4408 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4409 means elements of any type excluding nodes, discrete and 0D elements.
4410 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4413 list of IDs of found elements
4416 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4418 return self.editor.FindElementsByPoint(x, y, z, elementType)
4420 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4422 Project a point to a mesh object.
4423 Return ID of an element of given type where the given point is projected
4424 and coordinates of the projection point.
4425 In the case if nothing found, return -1 and []
4427 if isinstance( meshObject, Mesh ):
4428 meshObject = meshObject.GetMesh()
4430 meshObject = self.GetMesh()
4431 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4433 def GetPointState(self, x, y, z):
4435 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4436 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4437 UNKNOWN state means that either mesh is wrong or the analysis fails.
4440 return self.editor.GetPointState(x, y, z)
4442 def IsManifold(self):
4444 Check if a 2D mesh is manifold
4447 return self.editor.IsManifold()
4449 def IsCoherentOrientation2D(self):
4451 Check if orientation of 2D elements is coherent
4454 return self.editor.IsCoherentOrientation2D()
4456 def Get1DBranches( self, edges, startNode = 0 ):
4458 Partition given 1D elements into groups of contiguous edges.
4459 A node where number of meeting edges != 2 is a group end.
4460 An optional startNode is used to orient groups it belongs to.
4463 A list of edge groups and a list of corresponding node groups,
4464 where the group is a list of IDs of edges or nodes, like follows
4465 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4466 If a group is closed, the first and last nodes of the group are same.
4468 if isinstance( edges, Mesh ):
4469 edges = edges.GetMesh()
4470 unRegister = genObjUnRegister()
4471 if isinstance( edges, list ):
4472 edges = self.GetIDSource( edges, SMESH.EDGE )
4473 unRegister.set( edges )
4474 return self.editor.Get1DBranches( edges, startNode )
4476 def FindSharpEdges( self, angle, addExisting=False ):
4478 Return sharp edges of faces and non-manifold ones.
4479 Optionally add existing edges.
4482 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4483 addExisting: to return existing edges (1D elements) as well
4486 list of FaceEdge structures
4488 angle = ParseParameters( angle )[0]
4489 return self.editor.FindSharpEdges( angle, addExisting )
4491 def MeshToPassThroughAPoint(self, x, y, z):
4493 Find the node closest to a point and moves it to a point location
4496 x: the X coordinate of a point
4497 y: the Y coordinate of a point
4498 z: the Z coordinate of a point
4501 the ID of a moved node
4504 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4506 def InverseDiag(self, NodeID1, NodeID2):
4508 Replace two neighbour triangles sharing Node1-Node2 link
4509 with the triangles built on the same 4 nodes but having other common link.
4512 NodeID1: the ID of the first node
4513 NodeID2: the ID of the second node
4516 False if proper faces were not found
4518 return self.editor.InverseDiag(NodeID1, NodeID2)
4520 def DeleteDiag(self, NodeID1, NodeID2):
4522 Replace two neighbour triangles sharing *Node1-Node2* link
4523 with a quadrangle built on the same 4 nodes.
4526 NodeID1: ID of the first node
4527 NodeID2: ID of the second node
4530 False if proper faces were not found
4533 This operation can create gaps in numeration of elements.
4534 Call :meth:`RenumberElements` to remove the gaps.
4537 return self.editor.DeleteDiag(NodeID1, NodeID2)
4539 def Reorient(self, IDsOfElements=None):
4541 Reorient elements by ids
4544 IDsOfElements: if undefined reorients all mesh elements
4547 True if succeed else False
4550 if IDsOfElements == None:
4551 IDsOfElements = self.GetElementsId()
4552 return self.editor.Reorient(IDsOfElements)
4554 def ReorientObject(self, theObject):
4556 Reorient all elements of the object
4559 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4562 True if succeed else False
4565 if ( isinstance( theObject, Mesh )):
4566 theObject = theObject.GetMesh()
4567 return self.editor.ReorientObject(theObject)
4569 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4571 Reorient faces contained in *the2DObject*.
4574 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4575 theDirection: a desired direction of normal of *theFace*.
4576 It can be either a GEOM vector or a list of coordinates [x,y,z].
4577 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4578 compared with theDirection. It can be either ID of face or a point
4579 by which the face will be found. The point can be given as either
4580 a GEOM vertex or a list of point coordinates.
4583 number of reoriented faces
4586 unRegister = genObjUnRegister()
4588 if isinstance( the2DObject, Mesh ):
4589 the2DObject = the2DObject.GetMesh()
4590 if isinstance( the2DObject, list ):
4591 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4592 unRegister.set( the2DObject )
4593 # check theDirection
4594 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4595 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4596 if isinstance( theDirection, list ):
4597 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4598 # prepare theFace and thePoint
4599 theFace = theFaceOrPoint
4600 thePoint = PointStruct(0,0,0)
4601 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4602 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4604 if isinstance( theFaceOrPoint, list ):
4605 thePoint = PointStruct( *theFaceOrPoint )
4607 if isinstance( theFaceOrPoint, PointStruct ):
4608 thePoint = theFaceOrPoint
4610 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4612 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4614 Reorient faces according to adjacent volumes.
4617 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4618 either IDs of faces or face groups.
4619 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4620 theOutsideNormal: to orient faces to have their normals
4621 pointing either *outside* or *inside* the adjacent volumes.
4624 number of reoriented faces.
4627 unRegister = genObjUnRegister()
4629 if not isinstance( the2DObject, list ):
4630 the2DObject = [ the2DObject ]
4631 elif the2DObject and isinstance( the2DObject[0], int ):
4632 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4633 unRegister.set( the2DObject )
4634 the2DObject = [ the2DObject ]
4635 for i,obj2D in enumerate( the2DObject ):
4636 if isinstance( obj2D, Mesh ):
4637 the2DObject[i] = obj2D.GetMesh()
4638 if isinstance( obj2D, list ):
4639 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4640 unRegister.set( the2DObject[i] )
4642 if isinstance( the3DObject, Mesh ):
4643 the3DObject = the3DObject.GetMesh()
4644 if isinstance( the3DObject, list ):
4645 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4646 unRegister.set( the3DObject )
4647 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4649 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4651 Fuse the neighbouring triangles into quadrangles.
4654 IDsOfElements: The triangles to be fused.
4655 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4656 applied to possible quadrangles to choose a neighbour to fuse with.
4657 Note that not all items of :class:`SMESH.FunctorType` corresponds
4658 to numerical functors.
4659 MaxAngle: is the maximum angle between element normals at which the fusion
4660 is still performed; theMaxAngle is measured in radians.
4661 Also it could be a name of variable which defines angle in degrees.
4664 True in case of success, False otherwise.
4667 This operation can create gaps in numeration of elements.
4668 Call :meth:`RenumberElements` to remove the gaps.
4671 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4672 self.mesh.SetParameters(Parameters)
4673 if not IDsOfElements:
4674 IDsOfElements = self.GetElementsId()
4675 Functor = self.smeshpyD.GetFunctor(theCriterion)
4676 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4678 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4680 Fuse the neighbouring triangles of the object into quadrangles
4683 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4684 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4685 applied to possible quadrangles to choose a neighbour to fuse with.
4686 Note that not all items of :class:`SMESH.FunctorType` corresponds
4687 to numerical functors.
4688 MaxAngle: a max angle between element normals at which the fusion
4689 is still performed; theMaxAngle is measured in radians.
4692 True in case of success, False otherwise.
4695 This operation can create gaps in numeration of elements.
4696 Call :meth:`RenumberElements` to remove the gaps.
4699 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4700 self.mesh.SetParameters(Parameters)
4701 if isinstance( theObject, Mesh ):
4702 theObject = theObject.GetMesh()
4703 Functor = self.smeshpyD.GetFunctor(theCriterion)
4704 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4706 def QuadToTri (self, IDsOfElements, theCriterion = None):
4708 Split quadrangles into triangles.
4711 IDsOfElements: the faces to be splitted.
4712 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4713 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4714 value, then quadrangles will be split by the smallest diagonal.
4715 Note that not all items of :class:`SMESH.FunctorType` corresponds
4716 to numerical functors.
4719 True in case of success, False otherwise.
4722 This operation can create gaps in numeration of elements.
4723 Call :meth:`RenumberElements` to remove the gaps.
4725 if IDsOfElements == []:
4726 IDsOfElements = self.GetElementsId()
4727 if theCriterion is None:
4728 theCriterion = FT_MaxElementLength2D
4729 Functor = self.smeshpyD.GetFunctor(theCriterion)
4730 return self.editor.QuadToTri(IDsOfElements, Functor)
4732 def QuadToTriObject (self, theObject, theCriterion = None):
4734 Split quadrangles into triangles.
4737 theObject: the object from which the list of elements is taken,
4738 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4739 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4740 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4741 value, then quadrangles will be split by the smallest diagonal.
4742 Note that not all items of :class:`SMESH.FunctorType` corresponds
4743 to numerical functors.
4746 True in case of success, False otherwise.
4749 This operation can create gaps in numeration of elements.
4750 Call :meth:`RenumberElements` to remove the gaps.
4752 if ( isinstance( theObject, Mesh )):
4753 theObject = theObject.GetMesh()
4754 if theCriterion is None:
4755 theCriterion = FT_MaxElementLength2D
4756 Functor = self.smeshpyD.GetFunctor(theCriterion)
4757 return self.editor.QuadToTriObject(theObject, Functor)
4759 def QuadTo4Tri (self, theElements=[]):
4761 Split each of given quadrangles into 4 triangles. A node is added at the center of
4765 theElements: the faces to be splitted. This can be either
4766 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4767 or a list of face IDs. By default all quadrangles are split
4770 This operation can create gaps in numeration of elements.
4771 Call :meth:`RenumberElements` to remove the gaps.
4773 unRegister = genObjUnRegister()
4774 if isinstance( theElements, Mesh ):
4775 theElements = theElements.mesh
4776 elif not theElements:
4777 theElements = self.mesh
4778 elif isinstance( theElements, list ):
4779 theElements = self.GetIDSource( theElements, SMESH.FACE )
4780 unRegister.set( theElements )
4781 return self.editor.QuadTo4Tri( theElements )
4783 def SplitQuad (self, IDsOfElements, Diag13):
4785 Split quadrangles into triangles.
4788 IDsOfElements: the faces to be splitted
4789 Diag13 (boolean): is used to choose a diagonal for splitting.
4792 True in case of success, False otherwise.
4795 This operation can create gaps in numeration of elements.
4796 Call :meth:`RenumberElements` to remove the gaps.
4798 if IDsOfElements == []:
4799 IDsOfElements = self.GetElementsId()
4800 return self.editor.SplitQuad(IDsOfElements, Diag13)
4802 def SplitQuadObject (self, theObject, Diag13):
4804 Split quadrangles into triangles.
4807 theObject: the object from which the list of elements is taken,
4808 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4809 Diag13 (boolean): is used to choose a diagonal for splitting.
4812 True in case of success, False otherwise.
4815 This operation can create gaps in numeration of elements.
4816 Call :meth:`RenumberElements` to remove the gaps.
4818 if ( isinstance( theObject, Mesh )):
4819 theObject = theObject.GetMesh()
4820 return self.editor.SplitQuadObject(theObject, Diag13)
4822 def BestSplit (self, IDOfQuad, theCriterion):
4824 Find a better splitting of the given quadrangle.
4827 IDOfQuad: the ID of the quadrangle to be splitted.
4828 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4829 choose a diagonal for splitting.
4830 Note that not all items of :class:`SMESH.FunctorType` corresponds
4831 to numerical functors.
4834 * 1 if 1-3 diagonal is better,
4835 * 2 if 2-4 diagonal is better,
4836 * 0 if error occurs.
4839 This operation can create gaps in numeration of elements.
4840 Call :meth:`RenumberElements` to remove the gaps.
4842 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4844 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4846 Split volumic elements into tetrahedrons
4849 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4850 method: flags passing splitting method:
4851 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4852 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4855 This operation can create gaps in numeration of elements.
4856 Call :meth:`RenumberElements` to remove the gaps.
4858 unRegister = genObjUnRegister()
4859 if isinstance( elems, Mesh ):
4860 elems = elems.GetMesh()
4861 if ( isinstance( elems, list )):
4862 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4863 unRegister.set( elems )
4864 self.editor.SplitVolumesIntoTetra(elems, method)
4867 def SplitBiQuadraticIntoLinear(self, elems=None):
4869 Split bi-quadratic elements into linear ones without creation of additional nodes:
4871 - bi-quadratic triangle will be split into 3 linear quadrangles;
4872 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4873 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4875 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4876 will be split in order to keep the mesh conformal.
4879 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4880 if None (default), all bi-quadratic elements will be split
4883 This operation can create gaps in numeration of elements.
4884 Call :meth:`RenumberElements` to remove the gaps.
4886 unRegister = genObjUnRegister()
4887 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4888 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4889 unRegister.set( elems )
4891 elems = [ self.GetMesh() ]
4892 if isinstance( elems, Mesh ):
4893 elems = [ elems.GetMesh() ]
4894 if not isinstance( elems, list ):
4896 self.editor.SplitBiQuadraticIntoLinear( elems )
4898 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4899 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4901 Split hexahedra into prisms
4904 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4905 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4906 gives a normal vector defining facets to split into triangles.
4907 *startHexPoint* can be either a triple of coordinates or a vertex.
4908 facetNormal: a normal to a facet to split into triangles of a
4909 hexahedron found by *startHexPoint*.
4910 *facetNormal* can be either a triple of coordinates or an edge.
4911 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4912 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4913 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4914 to *startHexPoint* are split, else *startHexPoint*
4915 is used to find the facet to split in all domains present in *elems*.
4918 This operation can create gaps in numeration of elements.
4919 Call :meth:`RenumberElements` to remove the gaps.
4922 unRegister = genObjUnRegister()
4923 if isinstance( elems, Mesh ):
4924 elems = elems.GetMesh()
4925 if ( isinstance( elems, list )):
4926 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4927 unRegister.set( elems )
4930 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4931 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4932 elif isinstance( startHexPoint, list ):
4933 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4936 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4937 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4938 elif isinstance( facetNormal, list ):
4939 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4942 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4944 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4946 def SplitQuadsNearTriangularFacets(self):
4948 Split quadrangle faces near triangular facets of volumes
4951 This operation can create gaps in numeration of elements.
4952 Call :meth:`RenumberElements` to remove the gaps.
4954 faces_array = self.GetElementsByType(SMESH.FACE)
4955 for face_id in faces_array:
4956 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4957 quad_nodes = self.mesh.GetElemNodes(face_id)
4958 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4959 isVolumeFound = False
4960 for node1_elem in node1_elems:
4961 if not isVolumeFound:
4962 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4963 nb_nodes = self.GetElemNbNodes(node1_elem)
4964 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4965 volume_elem = node1_elem
4966 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4967 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4968 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4969 isVolumeFound = True
4970 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4971 self.SplitQuad([face_id], False) # diagonal 2-4
4972 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4973 isVolumeFound = True
4974 self.SplitQuad([face_id], True) # diagonal 1-3
4975 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4976 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4977 isVolumeFound = True
4978 self.SplitQuad([face_id], True) # diagonal 1-3
4980 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4982 Split hexahedrons into tetrahedrons.
4984 This operation uses :doc:`pattern_mapping` functionality for splitting.
4987 theObject: the object from which the list of hexahedrons is taken;
4988 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4989 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4990 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4991 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4992 key-point will be mapped into *theNode001*-th node of each volume.
4993 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4996 True in case of success, False otherwise.
4999 This operation can create gaps in numeration of elements.
5000 Call :meth:`RenumberElements` to remove the gaps.
5008 # (0,0,1) 4.---------.7 * |
5015 # (0,0,0) 0.---------.3
5016 pattern_tetra = "!!! Nb of points: \n 8 \n\
5026 !!! Indices of points of 6 tetras: \n\
5034 pattern = self.smeshpyD.GetPattern()
5035 isDone = pattern.LoadFromFile(pattern_tetra)
5037 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5040 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5041 isDone = pattern.MakeMesh(self.mesh, False, False)
5042 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5044 # split quafrangle faces near triangular facets of volumes
5045 self.SplitQuadsNearTriangularFacets()
5049 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5051 Split hexahedrons into prisms.
5053 Uses the :doc:`pattern_mapping` functionality for splitting.
5056 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5057 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5058 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5059 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5060 will be mapped into the *theNode001* -th node of each volume.
5061 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5064 True in case of success, False otherwise.
5067 This operation can create gaps in numeration of elements.
5068 Call :meth:`RenumberElements` to remove the gaps.
5070 # Pattern: 5.---------.6
5075 # (0,0,1) 4.---------.7 |
5082 # (0,0,0) 0.---------.3
5083 pattern_prism = "!!! Nb of points: \n 8 \n\
5093 !!! Indices of points of 2 prisms: \n\
5097 pattern = self.smeshpyD.GetPattern()
5098 isDone = pattern.LoadFromFile(pattern_prism)
5100 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5103 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5104 isDone = pattern.MakeMesh(self.mesh, False, False)
5105 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5107 # Split quafrangle faces near triangular facets of volumes
5108 self.SplitQuadsNearTriangularFacets()
5112 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5113 MaxNbOfIterations, MaxAspectRatio, Method):
5118 IDsOfElements: the list if ids of elements to smooth
5119 IDsOfFixedNodes: the list of ids of fixed nodes.
5120 Note that nodes built on edges and boundary nodes are always fixed.
5121 MaxNbOfIterations: the maximum number of iterations
5122 MaxAspectRatio: varies in range [1.0, inf]
5123 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5124 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5127 True in case of success, False otherwise.
5130 if IDsOfElements == []:
5131 IDsOfElements = self.GetElementsId()
5132 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5133 self.mesh.SetParameters(Parameters)
5134 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5135 MaxNbOfIterations, MaxAspectRatio, Method)
5137 def SmoothObject(self, theObject, IDsOfFixedNodes,
5138 MaxNbOfIterations, MaxAspectRatio, Method):
5140 Smooth elements which belong to the given object
5143 theObject: the object to smooth
5144 IDsOfFixedNodes: the list of ids of fixed nodes.
5145 Note that nodes built on edges and boundary nodes are always fixed.
5146 MaxNbOfIterations: the maximum number of iterations
5147 MaxAspectRatio: varies in range [1.0, inf]
5148 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5149 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5152 True in case of success, False otherwise.
5155 if ( isinstance( theObject, Mesh )):
5156 theObject = theObject.GetMesh()
5157 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5158 MaxNbOfIterations, MaxAspectRatio, Method)
5160 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5161 MaxNbOfIterations, MaxAspectRatio, Method):
5163 Parametrically smooth the given elements
5166 IDsOfElements: the list if ids of elements to smooth
5167 IDsOfFixedNodes: the list of ids of fixed nodes.
5168 Note that nodes built on edges and boundary nodes are always fixed.
5169 MaxNbOfIterations: the maximum number of iterations
5170 MaxAspectRatio: varies in range [1.0, inf]
5171 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5172 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5175 True in case of success, False otherwise.
5178 if IDsOfElements == []:
5179 IDsOfElements = self.GetElementsId()
5180 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5181 self.mesh.SetParameters(Parameters)
5182 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5183 MaxNbOfIterations, MaxAspectRatio, Method)
5185 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5186 MaxNbOfIterations, MaxAspectRatio, Method):
5188 Parametrically smooth the elements which belong to the given object
5191 theObject: the object to smooth
5192 IDsOfFixedNodes: the list of ids of fixed nodes.
5193 Note that nodes built on edges and boundary nodes are always fixed.
5194 MaxNbOfIterations: the maximum number of iterations
5195 MaxAspectRatio: varies in range [1.0, inf]
5196 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5197 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5200 True in case of success, False otherwise.
5203 if ( isinstance( theObject, Mesh )):
5204 theObject = theObject.GetMesh()
5205 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5206 MaxNbOfIterations, MaxAspectRatio, Method)
5208 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5210 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5211 them with quadratic with the same id.
5214 theForce3d: method of new node creation:
5216 * False - the medium node lies at the geometrical entity from which the mesh element is built
5217 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5218 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5219 theToBiQuad: If True, converts the mesh to bi-quadratic
5222 :class:`SMESH.ComputeError` which can hold a warning
5225 If *theSubMesh* is provided, the mesh can become non-conformal
5228 This operation can create gaps in numeration of nodes or elements.
5229 Call :meth:`RenumberElements` to remove the gaps.
5232 if isinstance( theSubMesh, Mesh ):
5233 theSubMesh = theSubMesh.mesh
5235 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5238 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5240 self.editor.ConvertToQuadratic(theForce3d)
5241 error = self.editor.GetLastError()
5242 if error and error.comment:
5243 print(error.comment)
5246 def ConvertFromQuadratic(self, theSubMesh=None):
5248 Convert the mesh from quadratic to ordinary,
5249 deletes old quadratic elements,
5250 replacing them with ordinary mesh elements with the same id.
5253 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5256 If *theSubMesh* is provided, the mesh can become non-conformal
5259 This operation can create gaps in numeration of nodes or elements.
5260 Call :meth:`RenumberElements` to remove the gaps.
5264 self.editor.ConvertFromQuadraticObject(theSubMesh)
5266 return self.editor.ConvertFromQuadratic()
5268 def Make2DMeshFrom3D(self):
5270 Create 2D mesh as skin on boundary faces of a 3D mesh
5273 True if operation has been completed successfully, False otherwise
5276 return self.editor.Make2DMeshFrom3D()
5278 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5279 toCopyElements=False, toCopyExistingBondary=False):
5281 Create missing boundary elements
5284 elements: elements whose boundary is to be checked:
5285 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5286 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5287 dimension: defines type of boundary elements to create, either of
5288 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5289 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5290 groupName: a name of group to store created boundary elements in,
5291 "" means not to create the group
5292 meshName: a name of new mesh to store created boundary elements in,
5293 "" means not to create the new mesh
5294 toCopyElements: if True, the checked elements will be copied into
5295 the new mesh else only boundary elements will be copied into the new mesh
5296 toCopyExistingBondary: if True, not only new but also pre-existing
5297 boundary elements will be copied into the new mesh
5300 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5303 unRegister = genObjUnRegister()
5304 if isinstance( elements, Mesh ):
5305 elements = elements.GetMesh()
5306 if ( isinstance( elements, list )):
5307 elemType = SMESH.ALL
5308 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5309 elements = self.editor.MakeIDSource(elements, elemType)
5310 unRegister.set( elements )
5311 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5312 toCopyElements,toCopyExistingBondary)
5313 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5316 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5317 toCopyAll=False, groups=[]):
5319 Create missing boundary elements around either the whole mesh or
5323 dimension: defines type of boundary elements to create, either of
5324 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5325 groupName: a name of group to store all boundary elements in,
5326 "" means not to create the group
5327 meshName: a name of a new mesh, which is a copy of the initial
5328 mesh + created boundary elements; "" means not to create the new mesh
5329 toCopyAll: if True, the whole initial mesh will be copied into
5330 the new mesh else only boundary elements will be copied into the new mesh
5331 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5334 tuple( long, mesh, group )
5335 - long - number of added boundary elements
5336 - mesh - the :class:`Mesh` where elements were added to
5337 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5340 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5342 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5343 return nb, mesh, group
5345 def RenumberNodes(self):
5347 Renumber mesh nodes to remove unused node IDs
5349 self.editor.RenumberNodes()
5351 def RenumberElements(self):
5353 Renumber mesh elements to remove unused element IDs
5355 self.editor.RenumberElements()
5357 def _getIdSourceList(self, arg, idType, unRegister):
5359 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5361 if arg and isinstance( arg, list ):
5362 if isinstance( arg[0], int ):
5363 arg = self.GetIDSource( arg, idType )
5364 unRegister.set( arg )
5365 elif isinstance( arg[0], Mesh ):
5366 arg[0] = arg[0].GetMesh()
5367 elif isinstance( arg, Mesh ):
5369 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5373 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5374 MakeGroups=False, TotalAngle=False):
5376 Generate new elements by rotation of the given elements and nodes around the axis
5379 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5380 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5381 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5382 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5383 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5384 which defines angle in degrees
5385 NbOfSteps: the number of steps
5386 Tolerance: tolerance
5387 MakeGroups: forces the generation of new groups from existing ones
5388 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5389 of all steps, else - size of each step
5392 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5395 unRegister = genObjUnRegister()
5396 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5397 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5398 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5400 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5401 Axis = self.smeshpyD.GetAxisStruct( Axis )
5402 if isinstance( Axis, list ):
5403 Axis = SMESH.AxisStruct( *Axis )
5405 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5406 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5407 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5408 self.mesh.SetParameters(Parameters)
5409 if TotalAngle and NbOfSteps:
5410 AngleInRadians /= NbOfSteps
5411 return self.editor.RotationSweepObjects( nodes, edges, faces,
5412 Axis, AngleInRadians,
5413 NbOfSteps, Tolerance, MakeGroups)
5415 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5416 MakeGroups=False, TotalAngle=False):
5418 Generate new elements by rotation of the elements around the axis
5421 IDsOfElements: the list of ids of elements to sweep
5422 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5423 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5424 NbOfSteps: the number of steps
5425 Tolerance: tolerance
5426 MakeGroups: forces the generation of new groups from existing ones
5427 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5428 of all steps, else - size of each step
5431 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5434 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5435 AngleInRadians, NbOfSteps, Tolerance,
5436 MakeGroups, TotalAngle)
5438 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5439 MakeGroups=False, TotalAngle=False):
5441 Generate new elements by rotation of the elements of object around the axis
5442 theObject object which elements should be sweeped.
5443 It can be a mesh, a sub mesh or a group.
5446 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5447 AngleInRadians: the angle of Rotation
5448 NbOfSteps: number of steps
5449 Tolerance: tolerance
5450 MakeGroups: forces the generation of new groups from existing ones
5451 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5452 of all steps, else - size of each step
5455 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5458 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5459 AngleInRadians, NbOfSteps, Tolerance,
5460 MakeGroups, TotalAngle )
5462 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5463 MakeGroups=False, TotalAngle=False):
5465 Generate new elements by rotation of the elements of object around the axis
5466 theObject object which elements should be sweeped.
5467 It can be a mesh, a sub mesh or a group.
5470 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5471 AngleInRadians: the angle of Rotation
5472 NbOfSteps: number of steps
5473 Tolerance: tolerance
5474 MakeGroups: forces the generation of new groups from existing ones
5475 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5476 of all steps, else - size of each step
5479 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5480 empty list otherwise
5483 return self.RotationSweepObjects([],theObject,[], Axis,
5484 AngleInRadians, NbOfSteps, Tolerance,
5485 MakeGroups, TotalAngle)
5487 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5488 MakeGroups=False, TotalAngle=False):
5490 Generate new elements by rotation of the elements of object around the axis
5491 theObject object which elements should be sweeped.
5492 It can be a mesh, a sub mesh or a group.
5495 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5496 AngleInRadians: the angle of Rotation
5497 NbOfSteps: number of steps
5498 Tolerance: tolerance
5499 MakeGroups: forces the generation of new groups from existing ones
5500 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5501 of all steps, else - size of each step
5504 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5507 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5508 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5510 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5511 scaleFactors=[], linearVariation=False, basePoint=[],
5512 angles=[], anglesVariation=False):
5514 Generate new elements by extrusion of the given elements and nodes
5517 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5518 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5519 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5520 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5521 the direction and value of extrusion for one step (the total extrusion
5522 length will be NbOfSteps * ||StepVector||)
5523 NbOfSteps: the number of steps
5524 MakeGroups: forces the generation of new groups from existing ones
5525 scaleFactors: optional scale factors to apply during extrusion
5526 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5527 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5528 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5529 nodes and elements being extruded is used as the scaling center.
5532 - a list of tree components of the point or
5535 angles: list of angles in radians. Nodes at each extrusion step are rotated
5536 around *basePoint*, additionally to previous steps.
5537 anglesVariation: forces the computation of rotation angles as linear
5538 variation of the given *angles* along path steps
5540 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5542 Example: :ref:`tui_extrusion`
5544 unRegister = genObjUnRegister()
5545 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5546 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5547 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5549 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5550 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5551 if isinstance( StepVector, list ):
5552 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5554 if isinstance( basePoint, int):
5555 xyz = self.GetNodeXYZ( basePoint )
5557 raise RuntimeError("Invalid node ID: %s" % basePoint)
5559 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5560 basePoint = self.geompyD.PointCoordinates( basePoint )
5562 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5563 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5564 angles,angleParameters,hasVars = ParseAngles(angles)
5565 Parameters = StepVector.PS.parameters + var_separator + \
5566 Parameters + var_separator + \
5567 scaleParameters + var_separator + angleParameters
5568 self.mesh.SetParameters(Parameters)
5570 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5571 StepVector, NbOfSteps, MakeGroups,
5572 scaleFactors, linearVariation, basePoint,
5573 angles, anglesVariation )
5576 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5578 Generate new elements by extrusion of the elements with given ids
5581 IDsOfElements: the list of ids of elements or nodes for extrusion
5582 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5583 the direction and value of extrusion for one step (the total extrusion
5584 length will be NbOfSteps * ||StepVector||)
5585 NbOfSteps: the number of steps
5586 MakeGroups: forces the generation of new groups from existing ones
5587 IsNodes: is True if elements with given ids are nodes
5590 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5592 Example: :ref:`tui_extrusion`
5595 if IsNodes: n = IDsOfElements
5596 else : e,f, = IDsOfElements,IDsOfElements
5597 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5599 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5600 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5602 Generate new elements by extrusion along the normal to a discretized surface or wire
5605 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5606 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5607 StepSize: length of one extrusion step (the total extrusion
5608 length will be *NbOfSteps* *StepSize*).
5609 NbOfSteps: number of extrusion steps.
5610 ByAverageNormal: if True each node is translated by *StepSize*
5611 along the average of the normal vectors to the faces sharing the node;
5612 else each node is translated along the same average normal till
5613 intersection with the plane got by translation of the face sharing
5614 the node along its own normal by *StepSize*.
5615 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5616 for every node of *Elements*.
5617 MakeGroups: forces generation of new groups from existing ones.
5618 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5619 is not yet implemented. This parameter is used if *Elements* contains
5620 both faces and edges, i.e. *Elements* is a Mesh.
5623 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5624 empty list otherwise.
5625 Example: :ref:`tui_extrusion`
5628 unRegister = genObjUnRegister()
5629 if isinstance( Elements, Mesh ):
5630 Elements = [ Elements.GetMesh() ]
5631 if isinstance( Elements, list ):
5633 raise RuntimeError("Elements empty!")
5634 if isinstance( Elements[0], Mesh ):
5635 Elements = [ Elements[0].GetMesh() ]
5636 if isinstance( Elements[0], int ):
5637 Elements = self.GetIDSource( Elements, SMESH.ALL )
5638 unRegister.set( Elements )
5639 if not isinstance( Elements, list ):
5640 Elements = [ Elements ]
5641 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5642 self.mesh.SetParameters(Parameters)
5643 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5644 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5646 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5648 Generate new elements by extrusion of the elements or nodes which belong to the object
5651 theObject: the object whose elements or nodes should be processed.
5652 It can be a :class:`mesh, sub-mesh, group or filter <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 IsNodes: is True if elements to extrude are nodes
5661 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5662 Example: :ref:`tui_extrusion`
5666 if IsNodes: n = theObject
5667 else : e,f, = theObject,theObject
5668 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5670 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5672 Generate new elements by extrusion of edges which belong to the object
5675 theObject: object whose 1D elements should be processed.
5676 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5677 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5678 the direction and value of extrusion for one step (the total extrusion
5679 length will be NbOfSteps * ||StepVector||)
5680 NbOfSteps: the number of steps
5681 MakeGroups: to generate new groups from existing ones
5684 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5685 Example: :ref:`tui_extrusion`
5688 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5690 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5692 Generate new elements by extrusion of faces which belong to the object
5695 theObject: object whose 2D elements should be processed.
5696 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5697 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5698 the direction and value of extrusion for one step (the total extrusion
5699 length will be NbOfSteps * ||StepVector||)
5700 NbOfSteps: the number of steps
5701 MakeGroups: forces the generation of new groups from existing ones
5704 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5705 Example: :ref:`tui_extrusion`
5708 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5710 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5711 ExtrFlags, SewTolerance, MakeGroups=False):
5713 Generate new elements by extrusion of the elements with given ids
5716 IDsOfElements: is ids of elements
5717 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5718 the direction and value of extrusion for one step (the total extrusion
5719 length will be NbOfSteps * ||StepVector||)
5720 NbOfSteps: the number of steps
5721 ExtrFlags: sets flags for extrusion
5722 SewTolerance: uses for comparing locations of nodes if flag
5723 EXTRUSION_FLAG_SEW is set
5724 MakeGroups: forces the generation of new groups from existing ones
5727 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5730 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5731 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5732 if isinstance( StepVector, list ):
5733 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5734 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5735 ExtrFlags, SewTolerance, MakeGroups)
5737 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5738 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5739 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5740 ScaleFactors=[], ScalesVariation=False):
5742 Generate new elements by extrusion of the given elements and nodes along the path.
5743 The path of extrusion must be a meshed edge.
5746 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5747 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5748 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5749 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5750 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
5751 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5752 HasAngles: not used obsolete
5753 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5754 around *basePoint*, additionally to previous steps.
5755 LinearVariation: forces the computation of rotation angles as linear
5756 variation of the given Angles along path steps
5757 HasRefPoint: allows using the reference point
5758 RefPoint: optional scaling and rotation center (mass center of the extruded
5759 elements by default). The User can specify any point as the Reference Point.
5760 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5761 MakeGroups: forces the generation of new groups from existing ones
5762 ScaleFactors: optional scale factors to apply during extrusion
5763 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5764 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5767 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5768 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5769 Example: :ref:`tui_extrusion_along_path`
5772 unRegister = genObjUnRegister()
5773 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5774 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5775 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5777 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5778 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5779 if isinstance( RefPoint, list ):
5780 if not RefPoint: RefPoint = [0,0,0]
5781 RefPoint = SMESH.PointStruct( *RefPoint )
5782 if isinstance( PathObject, Mesh ):
5783 PathObject = PathObject.GetMesh()
5784 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5785 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5786 Parameters = AnglesParameters + var_separator + \
5787 RefPoint.parameters + var_separator + ScalesParameters
5788 self.mesh.SetParameters(Parameters)
5789 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5790 PathObject, PathShape, NodeStart,
5791 HasAngles, Angles, LinearVariation,
5792 HasRefPoint, RefPoint, MakeGroups,
5793 ScaleFactors, ScalesVariation)
5795 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5796 HasAngles=False, Angles=[], LinearVariation=False,
5797 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5798 ElemType=SMESH.FACE):
5800 Generate new elements by extrusion of the given elements.
5801 The path of extrusion must be a meshed edge.
5804 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5805 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5806 NodeStart: the start node from Path. Defines the direction of extrusion
5807 HasAngles: not used obsolete
5808 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5809 around *basePoint*, additionally to previous steps.
5810 LinearVariation: forces the computation of rotation angles as linear
5811 variation of the given Angles along path steps
5812 HasRefPoint: allows using the reference point
5813 RefPoint: the reference point around which the elements are rotated (the mass
5814 center of the elements by default).
5815 The User can specify any point as the Reference Point.
5816 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5817 MakeGroups: forces the generation of new groups from existing ones
5818 ElemType: type of elements for extrusion (if param Base is a mesh)
5821 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5822 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5823 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5825 Example: :ref:`tui_extrusion_along_path`
5829 if ElemType == SMESH.NODE: n = Base
5830 if ElemType == SMESH.EDGE: e = Base
5831 if ElemType == SMESH.FACE: f = Base
5832 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5833 HasAngles, Angles, LinearVariation,
5834 HasRefPoint, RefPoint, MakeGroups)
5835 if MakeGroups: return gr,er
5838 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5839 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5840 MakeGroups=False, LinearVariation=False):
5842 Generate new elements by extrusion of the given elements.
5843 The path of extrusion must be a meshed edge.
5846 IDsOfElements: ids of elements
5847 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5848 PathShape: shape (edge) defines the sub-mesh for the path
5849 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5850 HasAngles: not used obsolete
5851 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5852 around *basePoint*, additionally to previous steps.
5853 HasRefPoint: allows using the reference point
5854 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5855 The User can specify any point as the Reference Point.
5856 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5857 MakeGroups: forces the generation of new groups from existing ones
5858 LinearVariation: forces the computation of rotation angles as linear
5859 variation of the given Angles along path steps
5862 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5863 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5864 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5865 Example: :ref:`tui_extrusion_along_path`
5868 if not IDsOfElements:
5869 IDsOfElements = [ self.GetMesh() ]
5870 n,e,f = [],IDsOfElements,IDsOfElements
5871 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5872 NodeStart, HasAngles, Angles,
5874 HasRefPoint, RefPoint, MakeGroups)
5875 if MakeGroups: return gr,er
5878 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5879 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5880 MakeGroups=False, LinearVariation=False):
5882 Generate new elements by extrusion of the elements which belong to the object.
5883 The path of extrusion must be a meshed edge.
5886 theObject: the object whose elements should be processed.
5887 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5888 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5889 PathShape: shape (edge) defines the sub-mesh for the path
5890 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5891 HasAngles: not used obsolete
5892 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5893 around *basePoint*, additionally to previous steps.
5894 HasRefPoint: allows using the reference point
5895 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5896 The User can specify any point as the Reference Point.
5897 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5898 MakeGroups: forces the generation of new groups from existing ones
5899 LinearVariation: forces the computation of rotation angles as linear
5900 variation of the given Angles along path steps
5903 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5904 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5905 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5906 Example: :ref:`tui_extrusion_along_path`
5909 n,e,f = [],theObject,theObject
5910 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5911 HasAngles, Angles, LinearVariation,
5912 HasRefPoint, RefPoint, MakeGroups)
5913 if MakeGroups: return gr,er
5916 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5917 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5918 MakeGroups=False, LinearVariation=False):
5920 Generate new elements by extrusion of mesh segments which belong to the object.
5921 The path of extrusion must be a meshed edge.
5924 theObject: the object whose 1D elements should be processed.
5925 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5926 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5927 PathShape: shape (edge) defines the sub-mesh for the path
5928 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5929 HasAngles: not used obsolete
5930 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5931 around *basePoint*, additionally to previous steps.
5932 HasRefPoint: allows using the reference point
5933 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5934 The User can specify any point as the Reference Point.
5935 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5936 MakeGroups: forces the generation of new groups from existing ones
5937 LinearVariation: forces the computation of rotation angles as linear
5938 variation of the given Angles along path steps
5941 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5942 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5943 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5944 Example: :ref:`tui_extrusion_along_path`
5947 n,e,f = [],theObject,[]
5948 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5949 HasAngles, Angles, LinearVariation,
5950 HasRefPoint, RefPoint, MakeGroups)
5951 if MakeGroups: return gr,er
5954 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5955 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5956 MakeGroups=False, LinearVariation=False):
5958 Generate new elements by extrusion of faces which belong to the object.
5959 The path of extrusion must be a meshed edge.
5962 theObject: the object whose 2D elements should be processed.
5963 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5964 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5965 PathShape: shape (edge) defines the sub-mesh for the path
5966 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5967 HasAngles: not used obsolete
5968 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5969 around *basePoint*, additionally to previous steps.
5970 HasRefPoint: allows using the reference point
5971 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5972 The User can specify any point as the Reference Point.
5973 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5974 MakeGroups: forces the generation of new groups from existing ones
5975 LinearVariation: forces the computation of rotation angles as linear
5976 variation of the given Angles along path steps
5979 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5980 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5981 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5982 Example: :ref:`tui_extrusion_along_path`
5985 n,e,f = [],[],theObject
5986 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5987 HasAngles, Angles, LinearVariation,
5988 HasRefPoint, RefPoint, MakeGroups)
5989 if MakeGroups: return gr,er
5992 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5994 Create a symmetrical copy of mesh elements
5997 IDsOfElements: list of elements ids
5998 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5999 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6000 If the *Mirror* is a geom object this parameter is unnecessary
6001 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6002 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6005 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6008 if IDsOfElements == []:
6009 IDsOfElements = self.GetElementsId()
6010 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6011 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6012 theMirrorType = Mirror._mirrorType
6014 self.mesh.SetParameters(Mirror.parameters)
6015 if Copy and MakeGroups:
6016 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6017 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6020 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6022 Create a new mesh by a symmetrical copy of mesh elements
6025 IDsOfElements: the list of elements ids
6026 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6027 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6028 If the *Mirror* is a geom object this parameter is unnecessary
6029 MakeGroups: to generate new groups from existing ones
6030 NewMeshName: a name of the new mesh to create
6033 instance of class :class:`Mesh`
6036 if IDsOfElements == []:
6037 IDsOfElements = self.GetElementsId()
6038 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6039 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6040 theMirrorType = Mirror._mirrorType
6042 self.mesh.SetParameters(Mirror.parameters)
6043 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6044 MakeGroups, NewMeshName)
6045 return Mesh(self.smeshpyD,self.geompyD,mesh)
6047 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6049 Create a symmetrical copy of the object
6052 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6053 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6054 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6055 If the *Mirror* is a geom object this parameter is unnecessary
6056 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6057 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6060 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6063 if ( isinstance( theObject, Mesh )):
6064 theObject = theObject.GetMesh()
6065 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6066 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6067 theMirrorType = Mirror._mirrorType
6069 self.mesh.SetParameters(Mirror.parameters)
6070 if Copy and MakeGroups:
6071 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6072 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6075 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6077 Create a new mesh by a symmetrical copy of the object
6080 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6081 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6082 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6083 If the *Mirror* is a geom object this parameter is unnecessary
6084 MakeGroups: forces the generation of new groups from existing ones
6085 NewMeshName: the name of the new mesh to create
6088 instance of class :class:`Mesh`
6091 if ( isinstance( theObject, Mesh )):
6092 theObject = theObject.GetMesh()
6093 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6094 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6095 theMirrorType = Mirror._mirrorType
6097 self.mesh.SetParameters(Mirror.parameters)
6098 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6099 MakeGroups, NewMeshName)
6100 return Mesh( self.smeshpyD,self.geompyD,mesh )
6102 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6104 Translate the elements
6107 IDsOfElements: list of elements ids
6108 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6109 Copy: allows copying the translated elements
6110 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6113 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6116 if IDsOfElements == []:
6117 IDsOfElements = self.GetElementsId()
6118 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6119 Vector = self.smeshpyD.GetDirStruct(Vector)
6120 if isinstance( Vector, list ):
6121 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6122 self.mesh.SetParameters(Vector.PS.parameters)
6123 if Copy and MakeGroups:
6124 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6125 self.editor.Translate(IDsOfElements, Vector, Copy)
6128 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6130 Create a new mesh of translated elements
6133 IDsOfElements: list of elements ids
6134 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6135 MakeGroups: forces the generation of new groups from existing ones
6136 NewMeshName: the name of the newly created mesh
6139 instance of class :class:`Mesh`
6142 if IDsOfElements == []:
6143 IDsOfElements = self.GetElementsId()
6144 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6145 Vector = self.smeshpyD.GetDirStruct(Vector)
6146 if isinstance( Vector, list ):
6147 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6148 self.mesh.SetParameters(Vector.PS.parameters)
6149 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6150 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6152 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6154 Translate the object
6157 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6158 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6159 Copy: allows copying the translated elements
6160 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6163 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6166 if ( isinstance( theObject, Mesh )):
6167 theObject = theObject.GetMesh()
6168 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6169 Vector = self.smeshpyD.GetDirStruct(Vector)
6170 if isinstance( Vector, list ):
6171 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6172 self.mesh.SetParameters(Vector.PS.parameters)
6173 if Copy and MakeGroups:
6174 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6175 self.editor.TranslateObject(theObject, Vector, Copy)
6178 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6180 Create a new mesh from the translated object
6183 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6184 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6185 MakeGroups: forces the generation of new groups from existing ones
6186 NewMeshName: the name of the newly created mesh
6189 instance of class :class:`Mesh`
6192 if isinstance( theObject, Mesh ):
6193 theObject = theObject.GetMesh()
6194 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6195 Vector = self.smeshpyD.GetDirStruct(Vector)
6196 if isinstance( Vector, list ):
6197 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6198 self.mesh.SetParameters(Vector.PS.parameters)
6199 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6200 return Mesh( self.smeshpyD, self.geompyD, mesh )
6204 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6209 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6210 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6211 theScaleFact: list of 1-3 scale factors for axises
6212 Copy: allows copying the translated elements
6213 MakeGroups: forces the generation of new groups from existing
6217 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6218 empty list otherwise
6220 unRegister = genObjUnRegister()
6221 if ( isinstance( theObject, Mesh )):
6222 theObject = theObject.GetMesh()
6223 if ( isinstance( theObject, list )):
6224 theObject = self.GetIDSource(theObject, SMESH.ALL)
6225 unRegister.set( theObject )
6226 if ( isinstance( thePoint, list )):
6227 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6228 if ( isinstance( theScaleFact, float )):
6229 theScaleFact = [theScaleFact]
6230 if ( isinstance( theScaleFact, int )):
6231 theScaleFact = [ float(theScaleFact)]
6233 self.mesh.SetParameters(thePoint.parameters)
6235 if Copy and MakeGroups:
6236 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6237 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6240 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6242 Create a new mesh from the translated object
6245 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6246 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6247 theScaleFact: list of 1-3 scale factors for axises
6248 MakeGroups: forces the generation of new groups from existing ones
6249 NewMeshName: the name of the newly created mesh
6252 instance of class :class:`Mesh`
6254 unRegister = genObjUnRegister()
6255 if (isinstance(theObject, Mesh)):
6256 theObject = theObject.GetMesh()
6257 if ( isinstance( theObject, list )):
6258 theObject = self.GetIDSource(theObject,SMESH.ALL)
6259 unRegister.set( theObject )
6260 if ( isinstance( thePoint, list )):
6261 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6262 if ( isinstance( theScaleFact, float )):
6263 theScaleFact = [theScaleFact]
6264 if ( isinstance( theScaleFact, int )):
6265 theScaleFact = [ float(theScaleFact)]
6267 self.mesh.SetParameters(thePoint.parameters)
6268 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6269 MakeGroups, NewMeshName)
6270 return Mesh( self.smeshpyD, self.geompyD, mesh )
6274 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6279 IDsOfElements: list of elements ids
6280 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6281 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6282 Copy: allows copying the rotated elements
6283 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6286 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6290 if IDsOfElements == []:
6291 IDsOfElements = self.GetElementsId()
6292 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6293 Axis = self.smeshpyD.GetAxisStruct(Axis)
6294 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6295 Parameters = Axis.parameters + var_separator + Parameters
6296 self.mesh.SetParameters(Parameters)
6297 if Copy and MakeGroups:
6298 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6299 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6302 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6304 Create a new mesh of rotated elements
6307 IDsOfElements: list of element ids
6308 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6309 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6310 MakeGroups: forces the generation of new groups from existing ones
6311 NewMeshName: the name of the newly created mesh
6314 instance of class :class:`Mesh`
6317 if IDsOfElements == []:
6318 IDsOfElements = self.GetElementsId()
6319 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6320 Axis = self.smeshpyD.GetAxisStruct(Axis)
6321 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6322 Parameters = Axis.parameters + var_separator + Parameters
6323 self.mesh.SetParameters(Parameters)
6324 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6325 MakeGroups, NewMeshName)
6326 return Mesh( self.smeshpyD, self.geompyD, mesh )
6328 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6333 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6334 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6335 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6336 Copy: allows copying the rotated elements
6337 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6340 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6343 if (isinstance(theObject, Mesh)):
6344 theObject = theObject.GetMesh()
6345 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6346 Axis = self.smeshpyD.GetAxisStruct(Axis)
6347 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6348 Parameters = Axis.parameters + ":" + Parameters
6349 self.mesh.SetParameters(Parameters)
6350 if Copy and MakeGroups:
6351 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6352 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6355 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6357 Create a new mesh from the rotated object
6360 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6361 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6362 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6363 MakeGroups: forces the generation of new groups from existing ones
6364 NewMeshName: the name of the newly created mesh
6367 instance of class :class:`Mesh`
6370 if (isinstance( theObject, Mesh )):
6371 theObject = theObject.GetMesh()
6372 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6373 Axis = self.smeshpyD.GetAxisStruct(Axis)
6374 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6375 Parameters = Axis.parameters + ":" + Parameters
6376 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6377 MakeGroups, NewMeshName)
6378 self.mesh.SetParameters(Parameters)
6379 return Mesh( self.smeshpyD, self.geompyD, mesh )
6381 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6383 Create an offset mesh from the given 2D object
6386 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6387 theValue (float): signed offset size
6388 MakeGroups (boolean): forces the generation of new groups from existing ones
6389 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6390 False means to remove original elements.
6391 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6394 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6397 if isinstance( theObject, Mesh ):
6398 theObject = theObject.GetMesh()
6399 theValue,Parameters,hasVars = ParseParameters(Value)
6400 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6401 self.mesh.SetParameters(Parameters)
6403 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6406 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6408 Find groups of adjacent nodes within Tolerance.
6411 Tolerance (float): the value of tolerance
6412 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6413 corner and medium nodes in separate groups thus preventing
6414 their further merge.
6417 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6420 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6422 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6423 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6425 Find groups of adjacent nodes within Tolerance.
6428 Tolerance: the value of tolerance
6429 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6430 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6431 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6432 corner and medium nodes in separate groups thus preventing
6433 their further merge.
6436 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6439 unRegister = genObjUnRegister()
6440 if not isinstance( SubMeshOrGroup, list ):
6441 SubMeshOrGroup = [ SubMeshOrGroup ]
6442 for i,obj in enumerate( SubMeshOrGroup ):
6443 if isinstance( obj, Mesh ):
6444 SubMeshOrGroup = [ obj.GetMesh() ]
6446 if isinstance( obj, int ):
6447 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6448 unRegister.set( SubMeshOrGroup )
6451 if not isinstance( exceptNodes, list ):
6452 exceptNodes = [ exceptNodes ]
6453 if exceptNodes and isinstance( exceptNodes[0], int ):
6454 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6455 unRegister.set( exceptNodes )
6457 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6458 exceptNodes, SeparateCornerAndMediumNodes)
6460 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6465 GroupsOfNodes: a list of groups of nodes IDs for merging.
6466 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6467 in all elements and mesh groups by nodes 1 and 25 correspondingly
6468 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6469 If *NodesToKeep* does not include a node to keep for some group to merge,
6470 then the first node in the group is kept.
6471 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6475 This operation can create gaps in numeration of nodes or elements.
6476 Call :meth:`RenumberElements` to remove the gaps.
6478 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6480 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6482 Find the elements built on the same nodes.
6485 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6486 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6490 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6493 unRegister = genObjUnRegister()
6494 if MeshOrSubMeshOrGroup is None:
6495 MeshOrSubMeshOrGroup = [ self.mesh ]
6496 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6497 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6498 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6499 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6500 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6501 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6502 unRegister.set( MeshOrSubMeshOrGroup )
6503 for item in MeshOrSubMeshOrGroup:
6504 if isinstance( item, Mesh ):
6505 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6507 if not isinstance( exceptElements, list ):
6508 exceptElements = [ exceptElements ]
6509 if exceptElements and isinstance( exceptElements[0], int ):
6510 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6511 unRegister.set( exceptElements )
6513 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6515 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6517 Merge elements in each given group.
6520 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6521 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6522 replaced in all mesh groups by elements 1 and 25)
6523 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6524 If *ElementsToKeep* does not include an element to keep for some group to merge,
6525 then the first element in the group is kept.
6528 This operation can create gaps in numeration of elements.
6529 Call :meth:`RenumberElements` to remove the gaps.
6532 unRegister = genObjUnRegister()
6534 if not isinstance( ElementsToKeep, list ):
6535 ElementsToKeep = [ ElementsToKeep ]
6536 if isinstance( ElementsToKeep[0], int ):
6537 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6538 unRegister.set( ElementsToKeep )
6540 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6542 def MergeEqualElements(self):
6544 Leave one element and remove all other elements built on the same nodes.
6547 This operation can create gaps in numeration of elements.
6548 Call :meth:`RenumberElements` to remove the gaps.
6551 self.editor.MergeEqualElements()
6553 def FindFreeBorders(self, ClosedOnly=True):
6555 Returns all or only closed free borders
6558 list of SMESH.FreeBorder's
6561 return self.editor.FindFreeBorders( ClosedOnly )
6563 def FillHole(self, holeNodes, groupName=""):
6565 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6568 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6569 must describe all sequential nodes of the hole border. The first and the last
6570 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6571 groupName (string): name of a group to add new faces
6573 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6577 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6578 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6579 if not isinstance( holeNodes, SMESH.FreeBorder ):
6580 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6581 return self.editor.FillHole( holeNodes, groupName )
6583 def FindCoincidentFreeBorders (self, tolerance=0.):
6585 Return groups of FreeBorder's coincident within the given tolerance.
6588 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6589 size of elements adjacent to free borders being compared is used.
6592 SMESH.CoincidentFreeBorders structure
6595 return self.editor.FindCoincidentFreeBorders( tolerance )
6597 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6599 Sew FreeBorder's of each group
6602 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6603 where each enclosed list contains node IDs of a group of coincident free
6604 borders such that each consequent triple of IDs within a group describes
6605 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6606 last node of a border.
6607 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6608 groups of coincident free borders, each group including two borders.
6609 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6610 polygons if a node of opposite border falls on a face edge, else such
6611 faces are split into several ones.
6612 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6613 polyhedra if a node of opposite border falls on a volume edge, else such
6614 volumes, if any, remain intact and the mesh becomes non-conformal.
6617 a number of successfully sewed groups
6620 This operation can create gaps in numeration of nodes or elements.
6621 Call :meth:`RenumberElements` to remove the gaps.
6624 if freeBorders and isinstance( freeBorders, list ):
6625 # construct SMESH.CoincidentFreeBorders
6626 if isinstance( freeBorders[0], int ):
6627 freeBorders = [freeBorders]
6629 coincidentGroups = []
6630 for nodeList in freeBorders:
6631 if not nodeList or len( nodeList ) % 3:
6632 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6635 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6636 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6637 nodeList = nodeList[3:]
6639 coincidentGroups.append( group )
6641 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6643 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6645 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6646 FirstNodeID2, SecondNodeID2, LastNodeID2,
6647 CreatePolygons, CreatePolyedrs):
6652 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6655 This operation can create gaps in numeration of nodes or elements.
6656 Call :meth:`RenumberElements` to remove the gaps.
6659 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6660 FirstNodeID2, SecondNodeID2, LastNodeID2,
6661 CreatePolygons, CreatePolyedrs)
6663 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6664 FirstNodeID2, SecondNodeID2):
6666 Sew conform free borders
6669 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6672 This operation can create gaps in numeration of elements.
6673 Call :meth:`RenumberElements` to remove the gaps.
6676 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6677 FirstNodeID2, SecondNodeID2)
6679 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6680 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6685 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6688 This operation can create gaps in numeration of elements.
6689 Call :meth:`RenumberElements` to remove the gaps.
6692 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6693 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6695 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6696 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6697 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6699 Sew two sides of a mesh. The nodes belonging to Side1 are
6700 merged with the nodes of elements of Side2.
6701 The number of elements in theSide1 and in theSide2 must be
6702 equal and they should have similar nodal connectivity.
6703 The nodes to merge should belong to side borders and
6704 the first node should be linked to the second.
6707 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6710 This operation can create gaps in numeration of nodes.
6711 Call :meth:`RenumberElements` to remove the gaps.
6714 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6715 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6716 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6718 def ChangeElemNodes(self, ide, newIDs):
6720 Set new nodes for the given element. Number of nodes should be kept.
6727 False if the number of nodes does not correspond to the type of element
6730 return self.editor.ChangeElemNodes(ide, newIDs)
6732 def GetLastCreatedNodes(self):
6734 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6735 created, this method return the list of their IDs.
6736 If new nodes were not created - return empty list
6739 the list of integer values (can be empty)
6742 return self.editor.GetLastCreatedNodes()
6744 def GetLastCreatedElems(self):
6746 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6747 created this method return the list of their IDs.
6748 If new elements were not created - return empty list
6751 the list of integer values (can be empty)
6754 return self.editor.GetLastCreatedElems()
6756 def ClearLastCreated(self):
6758 Forget what nodes and elements were created by the last mesh edition operation
6761 self.editor.ClearLastCreated()
6763 def DoubleElements(self, theElements, theGroupName=""):
6765 Create duplicates of given elements, i.e. create new elements based on the
6766 same nodes as the given ones.
6769 theElements: container of elements to duplicate. It can be a
6770 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6771 or a list of element IDs. If *theElements* is
6772 a :class:`Mesh`, elements of highest dimension are duplicated
6773 theGroupName: a name of group to contain the generated elements.
6774 If a group with such a name already exists, the new elements
6775 are added to the existing group, else a new group is created.
6776 If *theGroupName* is empty, new elements are not added
6780 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6781 None if *theGroupName* == "".
6784 unRegister = genObjUnRegister()
6785 if isinstance( theElements, Mesh ):
6786 theElements = theElements.mesh
6787 elif isinstance( theElements, list ):
6788 theElements = self.GetIDSource( theElements, SMESH.ALL )
6789 unRegister.set( theElements )
6790 return self.editor.DoubleElements(theElements, theGroupName)
6792 def DoubleNodes(self, theNodes, theModifiedElems):
6794 Create a hole in a mesh by doubling the nodes of some particular elements
6797 theNodes: IDs of nodes to be doubled
6798 theModifiedElems: IDs of elements to be updated by the new (doubled)
6799 nodes. If list of element identifiers is empty then nodes are doubled but
6800 they not assigned to elements
6803 True if operation has been completed successfully, False otherwise
6806 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6808 def DoubleNode(self, theNodeId, theModifiedElems):
6810 Create a hole in a mesh by doubling the nodes of some particular elements.
6811 This method provided for convenience works as :meth:`DoubleNodes`.
6814 theNodeId: IDs of node to double
6815 theModifiedElems: IDs of elements to update
6818 True if operation has been completed successfully, False otherwise
6821 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6823 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6825 Create a hole in a mesh by doubling the nodes of some particular elements.
6826 This method provided for convenience works as :meth:`DoubleNodes`.
6829 theNodes: group of nodes to double.
6830 theModifiedElems: group of elements to update.
6831 theMakeGroup: forces the generation of a group containing new nodes.
6834 True or a created group if operation has been completed successfully,
6835 False or None otherwise
6839 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6840 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6842 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6844 Create a hole in a mesh by doubling the nodes of some particular elements.
6845 This method provided for convenience works as :meth:`DoubleNodes`.
6848 theNodes: list of groups of nodes to double.
6849 theModifiedElems: list of groups of elements to update.
6850 theMakeGroup: forces the generation of a group containing new nodes.
6853 True if operation has been completed successfully, False otherwise
6857 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6858 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6860 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6862 Create a hole in a mesh by doubling the nodes of some particular elements
6865 theElems: the list of elements (edges or faces) to replicate.
6866 The nodes for duplication could be found from these elements
6867 theNodesNot: list of nodes NOT to replicate
6868 theAffectedElems: the list of elements (cells and edges) to which the
6869 replicated nodes should be associated to
6872 True if operation has been completed successfully, False otherwise
6875 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6877 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6879 Create a hole in a mesh by doubling the nodes of some particular elements
6882 theElems: the list of elements (edges or faces) to replicate.
6883 The nodes for duplication could be found from these elements
6884 theNodesNot: list of nodes NOT to replicate
6885 theShape: shape to detect affected elements (element which geometric center
6886 located on or inside shape).
6887 The replicated nodes should be associated to affected elements.
6890 True if operation has been completed successfully, False otherwise
6893 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6895 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6896 theMakeGroup=False, theMakeNodeGroup=False):
6898 Create a hole in a mesh by doubling the nodes of some particular elements.
6899 This method provided for convenience works as :meth:`DoubleNodes`.
6902 theElems: group of of elements (edges or faces) to replicate.
6903 theNodesNot: group of nodes NOT to replicate.
6904 theAffectedElems: group of elements to which the replicated nodes
6905 should be associated to.
6906 theMakeGroup: forces the generation of a group containing new elements.
6907 theMakeNodeGroup: forces the generation of a group containing new nodes.
6910 True or created groups (one or two) if operation has been completed successfully,
6911 False or None otherwise
6914 if theMakeGroup or theMakeNodeGroup:
6915 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6917 theMakeGroup, theMakeNodeGroup)
6918 if theMakeGroup and theMakeNodeGroup:
6921 return twoGroups[ int(theMakeNodeGroup) ]
6922 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6924 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6926 Create a hole in a mesh by doubling the nodes of some particular elements.
6927 This method provided for convenience works as :meth:`DoubleNodes`.
6930 theElems: group of of elements (edges or faces) to replicate
6931 theNodesNot: group of nodes not to replicate
6932 theShape: shape to detect affected elements (element which geometric center
6933 located on or inside shape).
6934 The replicated nodes should be associated to affected elements
6937 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6939 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6940 theMakeGroup=False, theMakeNodeGroup=False):
6942 Create a hole in a mesh by doubling the nodes of some particular elements.
6943 This method provided for convenience works as :meth:`DoubleNodes`.
6946 theElems: list of groups of elements (edges or faces) to replicate
6947 theNodesNot: list of groups of nodes NOT to replicate
6948 theAffectedElems: group of elements to which the replicated nodes
6949 should be associated to
6950 theMakeGroup: forces generation of a group containing new elements.
6951 theMakeNodeGroup: forces generation of a group containing new nodes
6954 True or created groups (one or two) if operation has been completed successfully,
6955 False or None otherwise
6958 if theMakeGroup or theMakeNodeGroup:
6959 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6961 theMakeGroup, theMakeNodeGroup)
6962 if theMakeGroup and theMakeNodeGroup:
6965 return twoGroups[ int(theMakeNodeGroup) ]
6966 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6968 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6970 Create a hole in a mesh by doubling the nodes of some particular elements.
6971 This method provided for convenience works as :meth:`DoubleNodes`.
6974 theElems: list of groups of elements (edges or faces) to replicate
6975 theNodesNot: list of groups of nodes NOT to replicate
6976 theShape: shape to detect affected elements (element which geometric center
6977 located on or inside shape).
6978 The replicated nodes should be associated to affected elements
6981 True if operation has been completed successfully, False otherwise
6984 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6986 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6988 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6989 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6992 theElems: list of groups of nodes or elements (edges or faces) to replicate
6993 theNodesNot: list of groups of nodes NOT to replicate
6994 theShape: shape to detect affected elements (element which geometric center
6995 located on or inside shape).
6996 The replicated nodes should be associated to affected elements
6999 groups of affected elements in order: volumes, faces, edges
7002 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7004 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7007 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7008 The list of groups must describe a partition of the mesh volumes.
7009 The nodes of the internal faces at the boundaries of the groups are doubled.
7010 In option, the internal faces are replaced by flat elements.
7011 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7014 theDomains: list of groups of volumes
7015 createJointElems: if True, create the elements
7016 onAllBoundaries: if True, the nodes and elements are also created on
7017 the boundary between *theDomains* and the rest mesh
7020 True if operation has been completed successfully, False otherwise
7023 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7025 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7027 Double nodes on some external faces and create flat elements.
7028 Flat elements are mainly used by some types of mechanic calculations.
7030 Each group of the list must be constituted of faces.
7031 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7034 theGroupsOfFaces: list of groups of faces
7037 True if operation has been completed successfully, False otherwise
7040 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7042 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7044 Identify all the elements around a geom shape, get the faces delimiting the hole
7046 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7048 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7050 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7051 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7052 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7053 If there are several paths connecting a pair of points, the shortest path is
7054 selected by the module. Position of the cutting plane is defined by the two
7055 points and an optional vector lying on the plane specified by a PolySegment.
7056 By default the vector is defined by Mesh module as following. A middle point
7057 of the two given points is computed. The middle point is projected to the mesh.
7058 The vector goes from the middle point to the projection point. In case of planar
7059 mesh, the vector is normal to the mesh.
7061 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7064 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7065 groupName: optional name of a group where created mesh segments will be added.
7068 editor = self.editor
7070 editor = self.mesh.GetMeshEditPreviewer()
7071 segmentsRes = editor.MakePolyLine( segments, groupName )
7072 for i, seg in enumerate( segmentsRes ):
7073 segments[i].vector = seg.vector
7075 return editor.GetPreviewData()
7078 def MakeSlot(self, segmentGroup, width ):
7080 Create a slot of given width around given 1D elements lying on a triangle mesh.
7081 The slot is constructed by cutting faces by cylindrical surfaces made
7082 around each segment. Segments are expected to be created by MakePolyLine().
7085 FaceEdge's located at the slot boundary
7087 return self.editor.MakeSlot( segmentGroup, width )
7089 def GetFunctor(self, funcType ):
7091 Return a cached numerical functor by its type.
7094 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7095 Note that not all items correspond to numerical functors.
7098 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7101 fn = self.functors[ funcType._v ]
7103 fn = self.smeshpyD.GetFunctor(funcType)
7104 fn.SetMesh(self.mesh)
7105 self.functors[ funcType._v ] = fn
7108 def FunctorValue(self, funcType, elemId, isElem=True):
7110 Return value of a functor for a given element
7113 funcType: an item of :class:`SMESH.FunctorType` enum.
7114 elemId: element or node ID
7115 isElem: *elemId* is ID of element or node
7118 the functor value or zero in case of invalid arguments
7121 fn = self.GetFunctor( funcType )
7122 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7123 val = fn.GetValue(elemId)
7128 def GetLength(self, elemId=None):
7130 Get length of given 1D elements or of all 1D mesh elements
7133 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.
7136 Sum of lengths of given elements
7141 length = self.smeshpyD.GetLength(self)
7142 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7143 length = self.smeshpyD.GetLength(elemId)
7146 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7148 length += self.smeshpyD.GetLength(obj)
7149 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7150 unRegister = genObjUnRegister()
7151 obj = self.GetIDSource( elemId )
7152 unRegister.set( obj )
7153 length = self.smeshpyD.GetLength( obj )
7155 length = self.FunctorValue(SMESH.FT_Length, elemId)
7158 def GetArea(self, elemId=None):
7160 Get area of given 2D elements or of all 2D mesh elements
7163 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.
7166 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7171 area = self.smeshpyD.GetArea(self)
7172 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7173 area = self.smeshpyD.GetArea(elemId)
7176 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7178 area += self.smeshpyD.GetArea(obj)
7179 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7180 unRegister = genObjUnRegister()
7181 obj = self.GetIDSource( elemId )
7182 unRegister.set( obj )
7183 area = self.smeshpyD.GetArea( obj )
7185 area = self.FunctorValue(SMESH.FT_Area, elemId)
7188 def GetVolume(self, elemId=None):
7190 Get volume of given 3D elements or of all 3D mesh elements
7193 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.
7196 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7201 volume= self.smeshpyD.GetVolume(self)
7202 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7203 volume= self.smeshpyD.GetVolume(elemId)
7206 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7208 volume+= self.smeshpyD.GetVolume(obj)
7209 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7210 unRegister = genObjUnRegister()
7211 obj = self.GetIDSource( elemId )
7212 unRegister.set( obj )
7213 volume= self.smeshpyD.GetVolume( obj )
7215 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7218 def GetAngle(self, node1, node2, node3 ):
7220 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7223 node1,node2,node3: IDs of the three nodes
7226 Angle in radians [0,PI]. -1 if failure case.
7228 p1 = self.GetNodeXYZ( node1 )
7229 p2 = self.GetNodeXYZ( node2 )
7230 p3 = self.GetNodeXYZ( node3 )
7231 if p1 and p2 and p3:
7232 return self.smeshpyD.GetAngle( p1,p2,p3 )
7236 def GetMaxElementLength(self, elemId):
7238 Get maximum element length.
7241 elemId: mesh element ID
7244 element's maximum length value
7247 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7248 ftype = SMESH.FT_MaxElementLength3D
7250 ftype = SMESH.FT_MaxElementLength2D
7251 return self.FunctorValue(ftype, elemId)
7253 def GetAspectRatio(self, elemId):
7255 Get aspect ratio of 2D or 3D element.
7258 elemId: mesh element ID
7261 element's aspect ratio value
7264 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7265 ftype = SMESH.FT_AspectRatio3D
7267 ftype = SMESH.FT_AspectRatio
7268 return self.FunctorValue(ftype, elemId)
7270 def GetWarping(self, elemId):
7272 Get warping angle of 2D element.
7275 elemId: mesh element ID
7278 element's warping angle value
7281 return self.FunctorValue(SMESH.FT_Warping, elemId)
7283 def GetMinimumAngle(self, elemId):
7285 Get minimum angle of 2D element.
7288 elemId: mesh element ID
7291 element's minimum angle value
7294 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7296 def GetTaper(self, elemId):
7298 Get taper of 2D element.
7301 elemId: mesh element ID
7304 element's taper value
7307 return self.FunctorValue(SMESH.FT_Taper, elemId)
7309 def GetSkew(self, elemId):
7311 Get skew of 2D element.
7314 elemId: mesh element ID
7317 element's skew value
7320 return self.FunctorValue(SMESH.FT_Skew, elemId)
7322 def GetMinMax(self, funType, meshPart=None):
7324 Return minimal and maximal value of a given functor.
7327 funType (SMESH.FunctorType): a functor type.
7328 Note that not all items of :class:`SMESH.FunctorType` corresponds
7329 to numerical functors.
7330 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7336 unRegister = genObjUnRegister()
7337 if isinstance( meshPart, list ):
7338 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7339 unRegister.set( meshPart )
7340 if isinstance( meshPart, Mesh ):
7341 meshPart = meshPart.mesh
7342 fun = self.GetFunctor( funType )
7345 if hasattr( meshPart, "SetMesh" ):
7346 meshPart.SetMesh( self.mesh ) # set mesh to filter
7347 hist = fun.GetLocalHistogram( 1, False, meshPart )
7349 hist = fun.GetHistogram( 1, False )
7351 return hist[0].min, hist[0].max
7354 pass # end of Mesh class
7357 class meshProxy(SMESH._objref_SMESH_Mesh):
7359 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7360 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7362 def __init__(self,*args):
7363 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7364 def __deepcopy__(self, memo=None):
7365 new = self.__class__(self)
7367 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7368 if len( args ) == 3:
7369 args += SMESH.ALL_NODES, True
7370 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7371 def ExportToMEDX(self, *args): # function removed
7372 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7373 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7374 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7375 def ExportToMED(self, *args): # function removed
7376 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7377 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7379 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7381 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7382 def ExportPartToMED(self, *args): # 'version' parameter removed
7383 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7384 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7385 def ExportMED(self, *args): # signature of method changed
7386 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7388 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7390 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7392 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7395 class submeshProxy(SMESH._objref_SMESH_subMesh):
7398 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7400 def __init__(self,*args):
7401 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7403 def __deepcopy__(self, memo=None):
7404 new = self.__class__(self)
7407 def Compute(self,refresh=False):
7409 Compute the sub-mesh and return the status of the computation
7412 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7417 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7418 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7422 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7424 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7426 if salome.sg.hasDesktop():
7427 if refresh: salome.sg.updateObjBrowser()
7432 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7435 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7437 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7438 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7441 def __init__(self,*args):
7442 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7444 def __getattr__(self, name ): # method called if an attribute not found
7445 if not self.mesh: # look for name() method in Mesh class
7446 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7447 if hasattr( self.mesh, name ):
7448 return getattr( self.mesh, name )
7449 if name == "ExtrusionAlongPathObjX":
7450 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7451 print("meshEditor: attribute '%s' NOT FOUND" % name)
7453 def __deepcopy__(self, memo=None):
7454 new = self.__class__(self)
7456 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7457 if len( args ) == 1: args += False,
7458 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7459 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7460 if len( args ) == 2: args += False,
7461 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7462 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7463 if len( args ) == 1:
7464 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7465 NodesToKeep = args[1]
7466 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7467 unRegister = genObjUnRegister()
7469 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7470 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7471 if not isinstance( NodesToKeep, list ):
7472 NodesToKeep = [ NodesToKeep ]
7473 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7475 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7477 class Pattern(SMESH._objref_SMESH_Pattern):
7479 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7480 variables in some methods
7483 def LoadFromFile(self, patternTextOrFile ):
7484 text = patternTextOrFile
7485 if os.path.exists( text ):
7486 text = open( patternTextOrFile ).read()
7488 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7490 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7491 decrFun = lambda i: i-1
7492 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7493 theMesh.SetParameters(Parameters)
7494 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7496 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7497 decrFun = lambda i: i-1
7498 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7499 theMesh.SetParameters(Parameters)
7500 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7502 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7503 if isinstance( mesh, Mesh ):
7504 mesh = mesh.GetMesh()
7505 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7507 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7509 Registering the new proxy for Pattern
7514 Private class used to bind methods creating algorithms to the class Mesh
7517 def __init__(self, method):
7519 self.defaultAlgoType = ""
7520 self.algoTypeToClass = {}
7521 self.method = method
7523 def add(self, algoClass):
7525 Store a python class of algorithm
7527 if inspect.isclass(algoClass) and \
7528 hasattr( algoClass, "algoType"):
7529 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7530 if not self.defaultAlgoType and \
7531 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7532 self.defaultAlgoType = algoClass.algoType
7533 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7535 def copy(self, mesh):
7537 Create a copy of self and assign mesh to the copy
7540 other = algoCreator( self.method )
7541 other.defaultAlgoType = self.defaultAlgoType
7542 other.algoTypeToClass = self.algoTypeToClass
7546 def __call__(self,algo="",geom=0,*args):
7548 Create an instance of algorithm
7552 if isinstance( algo, str ):
7554 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7555 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7560 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7562 elif not algoType and isinstance( geom, str ):
7567 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7569 elif isinstance( arg, str ) and not algoType:
7572 import traceback, sys
7573 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7574 sys.stderr.write( msg + '\n' )
7575 tb = traceback.extract_stack(None,2)
7576 traceback.print_list( [tb[0]] )
7578 algoType = self.defaultAlgoType
7579 if not algoType and self.algoTypeToClass:
7580 algoType = sorted( self.algoTypeToClass.keys() )[0]
7581 if algoType in self.algoTypeToClass:
7582 #print("Create algo",algoType)
7583 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7584 raise RuntimeError( "No class found for algo type %s" % algoType)
7587 class hypMethodWrapper:
7589 Private class used to substitute and store variable parameters of hypotheses.
7592 def __init__(self, hyp, method):
7594 self.method = method
7595 #print("REBIND:", method.__name__)
7598 def __call__(self,*args):
7600 call a method of hypothesis with calling SetVarParameter() before
7604 return self.method( self.hyp, *args ) # hypothesis method with no args
7606 #print("MethWrapper.__call__", self.method.__name__, args)
7608 parsed = ParseParameters(*args) # replace variables with their values
7609 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7610 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7611 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7612 # maybe there is a replaced string arg which is not variable
7613 result = self.method( self.hyp, *args )
7614 except ValueError as detail: # raised by ParseParameters()
7616 result = self.method( self.hyp, *args )
7617 except omniORB.CORBA.BAD_PARAM:
7618 raise ValueError(detail) # wrong variable name
7623 class genObjUnRegister:
7625 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7628 def __init__(self, genObj=None):
7629 self.genObjList = []
7633 def set(self, genObj):
7634 "Store one or a list of of SALOME.GenericObj'es"
7635 if isinstance( genObj, list ):
7636 self.genObjList.extend( genObj )
7638 self.genObjList.append( genObj )
7642 for genObj in self.genObjList:
7643 if genObj and hasattr( genObj, "UnRegister" ):
7646 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7648 Bind methods creating mesher plug-ins to the Mesh class
7651 # print("pluginName: ", pluginName)
7652 pluginBuilderName = pluginName + "Builder"
7654 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7655 except Exception as e:
7656 from salome_utils import verbose
7657 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7659 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7660 plugin = eval( pluginBuilderName )
7661 # print(" plugin:" , str(plugin))
7663 # add methods creating algorithms to Mesh
7664 for k in dir( plugin ):
7665 if k[0] == '_': continue
7666 algo = getattr( plugin, k )
7667 #print(" algo:", str(algo))
7668 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7669 #print(" meshMethod:" , str(algo.meshMethod))
7670 if not hasattr( Mesh, algo.meshMethod ):
7671 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7673 _mmethod = getattr( Mesh, algo.meshMethod )
7674 if hasattr( _mmethod, "add" ):