1 # Copyright (C) 2007-2020 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()
1654 self.geompyD = self.geom.GetGen()
1660 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1663 a :class:`SMESH.SMESH_Mesh` object
1668 def GetEngine(self):
1670 Return a smeshBuilder instance created this mesh
1672 return self.smeshpyD
1674 def GetGeomEngine(self):
1676 Return a geomBuilder instance
1682 Get the name of the mesh
1685 the name of the mesh as a string
1688 name = GetName(self.GetMesh())
1691 def SetName(self, name):
1693 Set a name to the mesh
1696 name: a new name of the mesh
1699 self.smeshpyD.SetName(self.GetMesh(), name)
1701 def GetSubMesh(self, geom, name):
1703 Get a sub-mesh object associated to a *geom* geometrical object.
1706 geom: a geometrical object (shape)
1707 name: a name for the sub-mesh in the Object Browser
1710 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1711 which lies on the given shape
1714 A sub-mesh is implicitly created when a sub-shape is specified at
1715 creating an algorithm, for example::
1717 algo1D = mesh.Segment(geom=Edge_1)
1719 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1720 The created sub-mesh can be retrieved from the algorithm::
1722 submesh = algo1D.GetSubMesh()
1725 AssureGeomPublished( self, geom, name )
1726 submesh = self.mesh.GetSubMesh( geom, name )
1731 Return the shape associated to the mesh
1739 def SetShape(self, geom):
1741 Associate the given shape to the mesh (entails the recreation of the mesh)
1744 geom: the shape to be meshed (GEOM_Object)
1747 self.mesh = self.smeshpyD.CreateMesh(geom)
1749 def HasShapeToMesh(self):
1751 Return ``True`` if this mesh is based on geometry
1753 return self.mesh.HasShapeToMesh()
1757 Load mesh from the study after opening the study
1761 def IsReadyToCompute(self, theSubObject):
1763 Return true if the hypotheses are defined well
1766 theSubObject: a sub-shape of a mesh shape
1772 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1774 def GetAlgoState(self, theSubObject):
1776 Return errors of hypotheses definition.
1777 The list of errors is empty if everything is OK.
1780 theSubObject: a sub-shape of a mesh shape
1786 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1788 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1790 Return a geometrical object on which the given element was built.
1791 The returned geometrical object, if not nil, is either found in the
1792 study or published by this method with the given name
1795 theElementID: the id of the mesh element
1796 theGeomName: the user-defined name of the geometrical object
1799 GEOM.GEOM_Object instance
1802 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1804 def MeshDimension(self):
1806 Return the mesh dimension depending on the dimension of the underlying shape
1807 or, if the mesh is not based on any shape, basing on deimension of elements
1810 mesh dimension as an integer value [0,3]
1813 if self.mesh.HasShapeToMesh():
1814 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1815 if len( shells ) > 0 :
1817 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1819 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1824 if self.NbVolumes() > 0: return 3
1825 if self.NbFaces() > 0: return 2
1826 if self.NbEdges() > 0: return 1
1829 def Evaluate(self, geom=0):
1831 Evaluate size of prospective mesh on a shape
1834 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1835 To know predicted number of e.g. edges, inquire it this way::
1837 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1840 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1842 geom = self.mesh.GetShapeToMesh()
1845 return self.smeshpyD.Evaluate(self.mesh, geom)
1848 def Compute(self, geom=0, discardModifs=False, refresh=False):
1850 Compute the mesh and return the status of the computation
1853 geom: geomtrical shape on which mesh data should be computed
1854 discardModifs: if True and the mesh has been edited since
1855 a last total re-compute and that may prevent successful partial re-compute,
1856 then the mesh is cleaned before Compute()
1857 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1863 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1864 geom = self.mesh.GetShapeToMesh()
1867 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1869 ok = self.smeshpyD.Compute(self.mesh, geom)
1870 except SALOME.SALOME_Exception as ex:
1871 print("Mesh computation failed, exception caught:")
1872 print(" ", ex.details.text)
1875 print("Mesh computation failed, exception caught:")
1876 traceback.print_exc()
1880 # Treat compute errors
1881 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1883 for err in computeErrors:
1884 if self.mesh.HasShapeToMesh():
1885 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1887 stdErrors = ["OK", #COMPERR_OK
1888 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1889 "std::exception", #COMPERR_STD_EXCEPTION
1890 "OCC exception", #COMPERR_OCC_EXCEPTION
1891 "..", #COMPERR_SLM_EXCEPTION
1892 "Unknown exception", #COMPERR_EXCEPTION
1893 "Memory allocation problem", #COMPERR_MEMORY_PB
1894 "Algorithm failed", #COMPERR_ALGO_FAILED
1895 "Unexpected geometry", #COMPERR_BAD_SHAPE
1896 "Warning", #COMPERR_WARNING
1897 "Computation cancelled",#COMPERR_CANCELED
1898 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1900 if err.code < len(stdErrors): errText = stdErrors[err.code]
1902 errText = "code %s" % -err.code
1903 if errText: errText += ". "
1904 errText += err.comment
1905 if allReasons: allReasons += "\n"
1907 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1909 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1913 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1915 if err.isGlobalAlgo:
1923 reason = '%s %sD algorithm is missing' % (glob, dim)
1924 elif err.state == HYP_MISSING:
1925 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1926 % (glob, dim, name, dim))
1927 elif err.state == HYP_NOTCONFORM:
1928 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1929 elif err.state == HYP_BAD_PARAMETER:
1930 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1931 % ( glob, dim, name ))
1932 elif err.state == HYP_BAD_GEOMETRY:
1933 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1934 'geometry' % ( glob, dim, name ))
1935 elif err.state == HYP_HIDDEN_ALGO:
1936 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1937 'algorithm of upper dimension generating %sD mesh'
1938 % ( glob, dim, name, glob, dim ))
1940 reason = ("For unknown reason. "
1941 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1943 if allReasons: allReasons += "\n"
1944 allReasons += "- " + reason
1946 if not ok or allReasons != "":
1947 msg = '"' + GetName(self.mesh) + '"'
1948 if ok: msg += " has been computed with warnings"
1949 else: msg += " has not been computed"
1950 if allReasons != "": msg += ":"
1955 if salome.sg.hasDesktop():
1956 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1957 if refresh: salome.sg.updateObjBrowser()
1961 def GetComputeErrors(self, shape=0 ):
1963 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1967 shape = self.mesh.GetShapeToMesh()
1968 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1970 def GetSubShapeName(self, subShapeID ):
1972 Return a name of a sub-shape by its ID.
1973 Possible variants (for *subShapeID* == 3):
1975 - **"Face_12"** - published sub-shape
1976 - **FACE #3** - not published sub-shape
1977 - **sub-shape #3** - invalid sub-shape ID
1978 - **#3** - error in this function
1981 subShapeID: a unique ID of a sub-shape
1984 a string describing the sub-shape
1988 if not self.mesh.HasShapeToMesh():
1992 mainIOR = salome.orb.object_to_string( self.GetShape() )
1994 mainSO = s.FindObjectIOR(mainIOR)
1997 shapeText = '"%s"' % mainSO.GetName()
1998 subIt = s.NewChildIterator(mainSO)
2000 subSO = subIt.Value()
2002 obj = subSO.GetObject()
2003 if not obj: continue
2004 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2007 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2010 if ids == subShapeID:
2011 shapeText = '"%s"' % subSO.GetName()
2014 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2016 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2018 shapeText = 'sub-shape #%s' % (subShapeID)
2020 shapeText = "#%s" % (subShapeID)
2023 def GetFailedShapes(self, publish=False):
2025 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2026 error of an algorithm
2029 publish: if *True*, the returned groups will be published in the study
2032 a list of GEOM groups each named after a failed algorithm
2037 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2038 for err in computeErrors:
2039 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2040 if not shape: continue
2041 if err.algoName in algo2shapes:
2042 algo2shapes[ err.algoName ].append( shape )
2044 algo2shapes[ err.algoName ] = [ shape ]
2048 for algoName, shapes in list(algo2shapes.items()):
2050 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2051 otherTypeShapes = []
2053 group = self.geompyD.CreateGroup( self.geom, groupType )
2054 for shape in shapes:
2055 if shape.GetShapeType() == shapes[0].GetShapeType():
2056 sameTypeShapes.append( shape )
2058 otherTypeShapes.append( shape )
2059 self.geompyD.UnionList( group, sameTypeShapes )
2061 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2063 group.SetName( algoName )
2064 groups.append( group )
2065 shapes = otherTypeShapes
2068 for group in groups:
2069 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2072 def GetMeshOrder(self):
2074 Return sub-mesh objects list in meshing order
2077 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2080 return self.mesh.GetMeshOrder()
2082 def SetMeshOrder(self, submeshes):
2084 Set priority of sub-meshes. It works in two ways:
2086 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2087 *several dimensions*, it sets the order in which the sub-meshes are computed.
2088 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2089 when looking for meshing parameters to apply to a sub-shape. To impose the
2090 order in which sub-meshes with uni-dimensional algorithms are computed,
2091 call **submesh.Compute()** in a desired order.
2094 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2096 Warning: the method is for setting the order for all sub-meshes at once:
2097 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2100 return self.mesh.SetMeshOrder(submeshes)
2102 def Clear(self, refresh=False):
2104 Remove all nodes and elements generated on geometry. Imported elements remain.
2107 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2111 if ( salome.sg.hasDesktop() ):
2112 if refresh: salome.sg.updateObjBrowser()
2114 def ClearSubMesh(self, geomId, refresh=False):
2116 Remove all nodes and elements of indicated shape
2119 geomId: the ID of a sub-shape to remove elements on
2120 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2123 self.mesh.ClearSubMesh(geomId)
2124 if salome.sg.hasDesktop():
2125 if refresh: salome.sg.updateObjBrowser()
2127 def AutomaticTetrahedralization(self, fineness=0):
2129 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2132 fineness: [0.0,1.0] defines mesh fineness
2138 dim = self.MeshDimension()
2140 self.RemoveGlobalHypotheses()
2141 self.Segment().AutomaticLength(fineness)
2143 self.Triangle().LengthFromEdges()
2148 return self.Compute()
2150 def AutomaticHexahedralization(self, fineness=0):
2152 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2155 fineness: [0.0, 1.0] defines mesh fineness
2161 dim = self.MeshDimension()
2162 # assign the hypotheses
2163 self.RemoveGlobalHypotheses()
2164 self.Segment().AutomaticLength(fineness)
2171 return self.Compute()
2173 def AddHypothesis(self, hyp, geom=0):
2178 hyp: a hypothesis to assign
2179 geom: a subhape of mesh geometry
2182 :class:`SMESH.Hypothesis_Status`
2185 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2186 hyp, geom = geom, hyp
2187 if isinstance( hyp, Mesh_Algorithm ):
2188 hyp = hyp.GetAlgorithm()
2193 geom = self.mesh.GetShapeToMesh()
2196 if self.mesh.HasShapeToMesh():
2197 hyp_type = hyp.GetName()
2198 lib_name = hyp.GetLibName()
2199 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2200 # if checkAll and geom:
2201 # checkAll = geom.GetType() == 37
2203 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2205 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2206 status = self.mesh.AddHypothesis(geom, hyp)
2208 status = HYP_BAD_GEOMETRY, ""
2209 hyp_name = GetName( hyp )
2212 geom_name = geom.GetName()
2213 isAlgo = hyp._narrow( SMESH_Algo )
2214 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2217 def IsUsedHypothesis(self, hyp, geom):
2219 Return True if an algorithm or hypothesis is assigned to a given shape
2222 hyp: an algorithm or hypothesis to check
2223 geom: a subhape of mesh geometry
2229 if not hyp: # or not geom
2231 if isinstance( hyp, Mesh_Algorithm ):
2232 hyp = hyp.GetAlgorithm()
2234 hyps = self.GetHypothesisList(geom)
2236 if h.GetId() == hyp.GetId():
2240 def RemoveHypothesis(self, hyp, geom=0):
2242 Unassign a hypothesis
2245 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2246 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2249 :class:`SMESH.Hypothesis_Status`
2254 if isinstance( hyp, Mesh_Algorithm ):
2255 hyp = hyp.GetAlgorithm()
2261 if self.IsUsedHypothesis( hyp, shape ):
2262 return self.mesh.RemoveHypothesis( shape, hyp )
2263 hypName = GetName( hyp )
2264 geoName = GetName( shape )
2265 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2268 def GetHypothesisList(self, geom):
2270 Get the list of hypotheses added on a geometry
2273 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2276 the sequence of :class:`SMESH.SMESH_Hypothesis`
2279 return self.mesh.GetHypothesisList( geom )
2281 def RemoveGlobalHypotheses(self):
2283 Remove all global hypotheses
2286 current_hyps = self.mesh.GetHypothesisList( self.geom )
2287 for hyp in current_hyps:
2288 self.mesh.RemoveHypothesis( self.geom, hyp )
2291 def ExportMED(self, *args, **kwargs):
2293 Export the mesh in a file in MED format
2294 allowing to overwrite the file if it exists or add the exported data to its contents
2297 fileName: is the file name
2298 auto_groups (boolean): parameter for creating/not creating
2299 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2300 the typical use is auto_groups=False.
2301 version (int): define the version (xy, where version is x.y.z) of MED file format.
2302 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2303 The rules of compatibility to write a mesh in an older version than
2304 the current version depend on the current version. For instance,
2305 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2306 or 3.2.1 or 3.3.1 formats.
2307 If the version is equal to -1, the version is not changed (default).
2308 overwrite (boolean): parameter for overwriting/not overwriting the file
2309 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2310 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2312 - 1D if all mesh nodes lie on OX coordinate axis, or
2313 - 2D if all mesh nodes lie on XOY coordinate plane, or
2314 - 3D in the rest cases.
2316 If *autoDimension* is *False*, the space dimension is always 3.
2317 fields: list of GEOM fields defined on the shape to mesh.
2318 geomAssocFields: each character of this string means a need to export a
2319 corresponding field; correspondence between fields and characters
2322 - 'v' stands for "_vertices_" field;
2323 - 'e' stands for "_edges_" field;
2324 - 'f' stands for "_faces_" field;
2325 - 's' stands for "_solids_" field.
2327 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2328 close to zero within a given tolerance, the coordinate is set to zero.
2329 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2331 # process positional arguments
2332 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2334 auto_groups = args[1] if len(args) > 1 else False
2335 version = args[2] if len(args) > 2 else -1
2336 overwrite = args[3] if len(args) > 3 else True
2337 meshPart = args[4] if len(args) > 4 else None
2338 autoDimension = args[5] if len(args) > 5 else True
2339 fields = args[6] if len(args) > 6 else []
2340 geomAssocFields = args[7] if len(args) > 7 else ''
2341 z_tolerance = args[8] if len(args) > 8 else -1.
2342 # process keywords arguments
2343 auto_groups = kwargs.get("auto_groups", auto_groups)
2344 version = kwargs.get("version", version)
2345 version = kwargs.get("minor", version)
2346 overwrite = kwargs.get("overwrite", overwrite)
2347 meshPart = kwargs.get("meshPart", meshPart)
2348 autoDimension = kwargs.get("autoDimension", autoDimension)
2349 fields = kwargs.get("fields", fields)
2350 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2351 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2353 # invoke engine's function
2354 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2355 unRegister = genObjUnRegister()
2356 if isinstance( meshPart, list ):
2357 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2358 unRegister.set( meshPart )
2360 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2361 self.mesh.SetParameters(Parameters)
2363 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2364 version, overwrite, autoDimension,
2365 fields, geomAssocFields, z_tolerance)
2367 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2369 def ExportSAUV(self, f, auto_groups=0):
2371 Export the mesh in a file in SAUV format
2376 auto_groups: boolean parameter for creating/not creating
2377 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2378 the typical use is auto_groups=False.
2381 self.mesh.ExportSAUV(f, auto_groups)
2383 def ExportDAT(self, f, meshPart=None):
2385 Export the mesh in a file in DAT format
2389 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2393 unRegister = genObjUnRegister()
2394 if isinstance( meshPart, list ):
2395 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2396 unRegister.set( meshPart )
2397 self.mesh.ExportPartToDAT( meshPart, f )
2399 self.mesh.ExportDAT(f)
2401 def ExportUNV(self, f, meshPart=None):
2403 Export the mesh in a file in UNV format
2407 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2411 unRegister = genObjUnRegister()
2412 if isinstance( meshPart, list ):
2413 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2414 unRegister.set( meshPart )
2415 self.mesh.ExportPartToUNV( meshPart, f )
2417 self.mesh.ExportUNV(f)
2419 def ExportSTL(self, f, ascii=1, meshPart=None):
2421 Export the mesh in a file in STL format
2425 ascii: defines the file encoding
2426 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2430 unRegister = genObjUnRegister()
2431 if isinstance( meshPart, list ):
2432 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2433 unRegister.set( meshPart )
2434 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2436 self.mesh.ExportSTL(f, ascii)
2438 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2440 Export the mesh in a file in CGNS format
2444 overwrite: boolean parameter for overwriting/not overwriting the file
2445 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2446 groupElemsByType: if True all elements of same entity type are exported at ones,
2447 else elements are exported in order of their IDs which can cause creation
2448 of multiple cgns sections
2451 unRegister = genObjUnRegister()
2452 if isinstance( meshPart, list ):
2453 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2454 unRegister.set( meshPart )
2455 if isinstance( meshPart, Mesh ):
2456 meshPart = meshPart.mesh
2458 meshPart = self.mesh
2459 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2461 def ExportGMF(self, f, meshPart=None):
2463 Export the mesh in a file in GMF format.
2464 GMF files must have .mesh extension for the ASCII format and .meshb for
2465 the bynary format. Other extensions are not allowed.
2469 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2472 unRegister = genObjUnRegister()
2473 if isinstance( meshPart, list ):
2474 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2475 unRegister.set( meshPart )
2476 if isinstance( meshPart, Mesh ):
2477 meshPart = meshPart.mesh
2479 meshPart = self.mesh
2480 self.mesh.ExportGMF(meshPart, f, True)
2482 def ExportToMED(self, *args, **kwargs):
2484 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2485 Export the mesh in a file in MED format
2486 allowing to overwrite the file if it exists or add the exported data to its contents
2489 fileName: the file name
2490 opt (boolean): parameter for creating/not creating
2491 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2492 overwrite: boolean parameter for overwriting/not overwriting the file
2493 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2495 - 1D if all mesh nodes lie on OX coordinate axis, or
2496 - 2D if all mesh nodes lie on XOY coordinate plane, or
2497 - 3D in the rest cases.
2499 If **autoDimension** is *False*, the space dimension is always 3.
2502 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2503 # process positional arguments
2504 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2506 auto_groups = args[1] if len(args) > 1 else False
2507 overwrite = args[2] if len(args) > 2 else True
2508 autoDimension = args[3] if len(args) > 3 else True
2509 # process keywords arguments
2510 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2511 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2512 overwrite = kwargs.get("overwrite", overwrite)
2513 autoDimension = kwargs.get("autoDimension", autoDimension)
2515 # invoke engine's function
2516 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2518 def ExportToMEDX(self, *args, **kwargs):
2520 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2521 Export the mesh in a file in MED format
2524 fileName: the file name
2525 opt (boolean): parameter for creating/not creating
2526 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2527 overwrite: boolean parameter for overwriting/not overwriting the file
2528 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2530 - 1D if all mesh nodes lie on OX coordinate axis, or
2531 - 2D if all mesh nodes lie on XOY coordinate plane, or
2532 - 3D in the rest cases.
2534 If **autoDimension** is *False*, the space dimension is always 3.
2537 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2538 # process positional arguments
2539 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2541 auto_groups = args[1] if len(args) > 1 else False
2542 overwrite = args[2] if len(args) > 2 else True
2543 autoDimension = args[3] if len(args) > 3 else True
2544 # process keywords arguments
2545 auto_groups = kwargs.get("auto_groups", auto_groups)
2546 overwrite = kwargs.get("overwrite", overwrite)
2547 autoDimension = kwargs.get("autoDimension", autoDimension)
2549 # invoke engine's function
2550 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2554 def Append(self, meshes, uniteIdenticalGroups = True,
2555 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2557 Append given meshes into this mesh.
2558 All groups of input meshes will be created in this mesh.
2561 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2562 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2563 mergeNodesAndElements: if True, equal nodes and elements are merged
2564 mergeTolerance: tolerance for merging nodes
2565 allGroups: forces creation of groups corresponding to every input mesh
2567 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2568 mergeNodesAndElements, mergeTolerance, allGroups,
2569 meshToAppendTo = self.GetMesh() )
2571 # Operations with groups:
2572 # ----------------------
2573 def CreateEmptyGroup(self, elementType, name):
2575 Create an empty standalone mesh group
2578 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2579 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2580 name: the name of the mesh group
2583 :class:`SMESH.SMESH_Group`
2586 return self.mesh.CreateGroup(elementType, name)
2588 def Group(self, grp, name=""):
2590 Create a mesh group based on the geometric object *grp*
2591 and give it a *name*.
2592 If *name* is not defined the name of the geometric group is used
2595 Works like :meth:`GroupOnGeom`.
2598 grp: a geometric group, a vertex, an edge, a face or a solid
2599 name: the name of the mesh group
2602 :class:`SMESH.SMESH_GroupOnGeom`
2605 return self.GroupOnGeom(grp, name)
2607 def GroupOnGeom(self, grp, name="", typ=None):
2609 Create a mesh group based on the geometrical object *grp*
2610 and give it a *name*.
2611 if *name* is not defined the name of the geometric group is used
2614 grp: a geometrical group, a vertex, an edge, a face or a solid
2615 name: the name of the mesh group
2616 typ: the type of elements in the group; either of
2617 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2618 automatically detected by the type of the geometry
2621 :class:`SMESH.SMESH_GroupOnGeom`
2624 AssureGeomPublished( self, grp, name )
2626 name = grp.GetName()
2628 typ = self._groupTypeFromShape( grp )
2629 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2631 def _groupTypeFromShape( self, shape ):
2633 Pivate method to get a type of group on geometry
2635 tgeo = str(shape.GetShapeType())
2636 if tgeo == "VERTEX":
2638 elif tgeo == "EDGE" or tgeo == "WIRE":
2640 elif tgeo == "FACE" or tgeo == "SHELL":
2642 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2644 elif tgeo == "COMPOUND":
2646 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2648 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2649 # simplification of access in geomBuilder: omniORB.registerObjref
2650 from SHAPERSTUDY_utils import getEngine
2653 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2655 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2656 return self._groupTypeFromShape( sub[0] )
2658 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2661 def GroupOnFilter(self, typ, name, filter):
2663 Create a mesh group with given *name* based on the *filter*.
2664 It is a special type of group dynamically updating it's contents during
2668 typ: the type of elements in the group; either of
2669 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2670 name: the name of the mesh group
2671 filter (SMESH.Filter): the filter defining group contents
2674 :class:`SMESH.SMESH_GroupOnFilter`
2677 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2679 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2681 Create a mesh group by the given ids of elements
2684 groupName: the name of the mesh group
2685 elementType: the type of elements in the group; either of
2686 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2687 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2690 :class:`SMESH.SMESH_Group`
2693 group = self.mesh.CreateGroup(elementType, groupName)
2694 if isinstance( elemIDs, Mesh ):
2695 elemIDs = elemIDs.GetMesh()
2696 if hasattr( elemIDs, "GetIDs" ):
2697 if hasattr( elemIDs, "SetMesh" ):
2698 elemIDs.SetMesh( self.GetMesh() )
2699 group.AddFrom( elemIDs )
2707 CritType=FT_Undefined,
2710 UnaryOp=FT_Undefined,
2713 Create a mesh group by the given conditions
2716 groupName: the name of the mesh group
2717 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2718 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2719 Note that the items starting from FT_LessThan are not suitable for CritType.
2720 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2721 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2722 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2723 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2724 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2727 :class:`SMESH.SMESH_GroupOnFilter`
2730 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2731 group = self.MakeGroupByCriterion(groupName, aCriterion)
2734 def MakeGroupByCriterion(self, groupName, Criterion):
2736 Create a mesh group by the given criterion
2739 groupName: the name of the mesh group
2740 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2743 :class:`SMESH.SMESH_GroupOnFilter`
2746 :meth:`smeshBuilder.GetCriterion`
2749 return self.MakeGroupByCriteria( groupName, [Criterion] )
2751 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2753 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2756 groupName: the name of the mesh group
2757 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2758 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2761 :class:`SMESH.SMESH_GroupOnFilter`
2764 :meth:`smeshBuilder.GetCriterion`
2767 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2768 group = self.MakeGroupByFilter(groupName, aFilter)
2771 def MakeGroupByFilter(self, groupName, theFilter):
2773 Create a mesh group by the given filter
2776 groupName (string): the name of the mesh group
2777 theFilter (SMESH.Filter): the filter
2780 :class:`SMESH.SMESH_GroupOnFilter`
2783 :meth:`smeshBuilder.GetFilter`
2786 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2787 #theFilter.SetMesh( self.mesh )
2788 #group.AddFrom( theFilter )
2789 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2792 def RemoveGroup(self, group):
2797 group (SMESH.SMESH_GroupBase): group to remove
2800 self.mesh.RemoveGroup(group)
2802 def RemoveGroupWithContents(self, group):
2804 Remove a group with its contents
2807 group (SMESH.SMESH_GroupBase): group to remove
2810 This operation can create gaps in numeration of nodes or elements.
2811 Call :meth:`RenumberElements` to remove the gaps.
2814 self.mesh.RemoveGroupWithContents(group)
2816 def GetGroups(self, elemType = SMESH.ALL):
2818 Get the list of groups existing in the mesh in the order of creation
2819 (starting from the oldest one)
2822 elemType (SMESH.ElementType): type of elements the groups contain;
2823 by default groups of elements of all types are returned
2826 a list of :class:`SMESH.SMESH_GroupBase`
2829 groups = self.mesh.GetGroups()
2830 if elemType == SMESH.ALL:
2834 if g.GetType() == elemType:
2835 typedGroups.append( g )
2842 Get the number of groups existing in the mesh
2845 the quantity of groups as an integer value
2848 return self.mesh.NbGroups()
2850 def GetGroupNames(self):
2852 Get the list of names of groups existing in the mesh
2858 groups = self.GetGroups()
2860 for group in groups:
2861 names.append(group.GetName())
2864 def GetGroupByName(self, name, elemType = None):
2866 Find groups by name and type
2869 name (string): name of the group of interest
2870 elemType (SMESH.ElementType): type of elements the groups contain;
2871 by default one group of any type is returned;
2872 if elemType == SMESH.ALL then all groups of any type are returned
2875 a list of :class:`SMESH.SMESH_GroupBase`
2879 for group in self.GetGroups():
2880 if group.GetName() == name:
2881 if elemType is None:
2883 if ( elemType == SMESH.ALL or
2884 group.GetType() == elemType ):
2885 groups.append( group )
2888 def UnionGroups(self, group1, group2, name):
2890 Produce a union of two groups.
2891 A new group is created. All mesh elements that are
2892 present in the initial groups are added to the new one
2895 group1 (SMESH.SMESH_GroupBase): a group
2896 group2 (SMESH.SMESH_GroupBase): another group
2899 instance of :class:`SMESH.SMESH_Group`
2902 return self.mesh.UnionGroups(group1, group2, name)
2904 def UnionListOfGroups(self, groups, name):
2906 Produce a union list of groups.
2907 New group is created. All mesh elements that are present in
2908 initial groups are added to the new one
2911 groups: list of :class:`SMESH.SMESH_GroupBase`
2914 instance of :class:`SMESH.SMESH_Group`
2916 return self.mesh.UnionListOfGroups(groups, name)
2918 def IntersectGroups(self, group1, group2, name):
2920 Prodice an intersection of two groups.
2921 A new group is created. All mesh elements that are common
2922 for the two initial groups are added to the new one.
2925 group1 (SMESH.SMESH_GroupBase): a group
2926 group2 (SMESH.SMESH_GroupBase): another group
2929 instance of :class:`SMESH.SMESH_Group`
2932 return self.mesh.IntersectGroups(group1, group2, name)
2934 def IntersectListOfGroups(self, groups, name):
2936 Produce an intersection of groups.
2937 New group is created. All mesh elements that are present in all
2938 initial groups simultaneously are added to the new one
2941 groups: a list of :class:`SMESH.SMESH_GroupBase`
2944 instance of :class:`SMESH.SMESH_Group`
2946 return self.mesh.IntersectListOfGroups(groups, name)
2948 def CutGroups(self, main_group, tool_group, name):
2950 Produce a cut of two groups.
2951 A new group is created. All mesh elements that are present in
2952 the main group but are not present in the tool group are added to the new one
2955 main_group (SMESH.SMESH_GroupBase): a group to cut from
2956 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2959 an instance of :class:`SMESH.SMESH_Group`
2962 return self.mesh.CutGroups(main_group, tool_group, name)
2964 def CutListOfGroups(self, main_groups, tool_groups, name):
2966 Produce a cut of groups.
2967 A new group is created. All mesh elements that are present in main groups
2968 but do not present in tool groups are added to the new one
2971 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2972 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2975 an instance of :class:`SMESH.SMESH_Group`
2978 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2980 def CreateDimGroup(self, groups, elemType, name,
2981 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2983 Create a standalone group of entities basing on nodes of other groups.
2986 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2987 elemType: a type of elements to include to the new group; either of
2988 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2989 name: a name of the new group.
2990 nbCommonNodes: a criterion of inclusion of an element to the new group
2991 basing on number of element nodes common with reference *groups*.
2992 Meaning of possible values are:
2994 - SMESH.ALL_NODES - include if all nodes are common,
2995 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2996 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2997 - SMEHS.MAJORITY - include if half of nodes or more are common.
2998 underlyingOnly: if *True* (default), an element is included to the
2999 new group provided that it is based on nodes of an element of *groups*;
3000 in this case the reference *groups* are supposed to be of higher dimension
3001 than *elemType*, which can be useful for example to get all faces lying on
3002 volumes of the reference *groups*.
3005 an instance of :class:`SMESH.SMESH_Group`
3008 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3010 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3012 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3014 Distribute all faces of the mesh among groups using sharp edges and optionally
3015 existing 1D elements as group boundaries.
3018 sharpAngle: edge is considered sharp if an angle between normals of
3019 adjacent faces is more than \a sharpAngle in degrees.
3020 createEdges (boolean): to create 1D elements for detected sharp edges.
3021 useExistingEdges (boolean): to use existing edges as group boundaries
3023 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3025 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3026 self.mesh.SetParameters(Parameters)
3027 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3029 def ConvertToStandalone(self, group):
3031 Convert group on geom into standalone group
3034 return self.mesh.ConvertToStandalone(group)
3036 # Get some info about mesh:
3037 # ------------------------
3039 def GetLog(self, clearAfterGet):
3041 Return the log of nodes and elements added or removed
3042 since the previous clear of the log.
3045 clearAfterGet: log is emptied after Get (safe if concurrents access)
3048 list of SMESH.log_block structures { commandType, number, coords, indexes }
3051 return self.mesh.GetLog(clearAfterGet)
3055 Clear the log of nodes and elements added or removed since the previous
3056 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3059 self.mesh.ClearLog()
3061 def SetAutoColor(self, theAutoColor):
3063 Toggle auto color mode on the object.
3064 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3067 theAutoColor (boolean): the flag which toggles auto color mode.
3070 self.mesh.SetAutoColor(theAutoColor)
3072 def GetAutoColor(self):
3074 Get flag of object auto color mode.
3080 return self.mesh.GetAutoColor()
3087 integer value, which is the internal Id of the mesh
3090 return self.mesh.GetId()
3092 def HasDuplicatedGroupNamesMED(self):
3094 Check the group names for duplications.
3095 Consider the maximum group name length stored in MED file.
3101 return self.mesh.HasDuplicatedGroupNamesMED()
3103 def GetMeshEditor(self):
3105 Obtain the mesh editor tool
3108 an instance of :class:`SMESH.SMESH_MeshEditor`
3113 def GetIDSource(self, ids, elemType = SMESH.ALL):
3115 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3116 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3120 elemType: type of elements; this parameter is used to distinguish
3121 IDs of nodes from IDs of elements; by default ids are treated as
3122 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3125 an instance of :class:`SMESH.SMESH_IDSource`
3128 call UnRegister() for the returned object as soon as it is no more useful::
3130 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3131 mesh.DoSomething( idSrc )
3135 if isinstance( ids, int ):
3137 return self.editor.MakeIDSource(ids, elemType)
3140 # Get information about mesh contents:
3141 # ------------------------------------
3143 def GetMeshInfo(self, obj = None):
3145 Get the mesh statistic.
3148 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3151 if not obj: obj = self.mesh
3152 return self.smeshpyD.GetMeshInfo(obj)
3156 Return the number of nodes in the mesh
3162 return self.mesh.NbNodes()
3164 def NbElements(self):
3166 Return the number of elements in the mesh
3172 return self.mesh.NbElements()
3174 def Nb0DElements(self):
3176 Return the number of 0d elements in the mesh
3182 return self.mesh.Nb0DElements()
3186 Return the number of ball discrete elements in the mesh
3192 return self.mesh.NbBalls()
3196 Return the number of edges in the mesh
3202 return self.mesh.NbEdges()
3204 def NbEdgesOfOrder(self, elementOrder):
3206 Return the number of edges with the given order in the mesh
3209 elementOrder: the order of elements
3210 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3216 return self.mesh.NbEdgesOfOrder(elementOrder)
3220 Return the number of faces in the mesh
3226 return self.mesh.NbFaces()
3228 def NbFacesOfOrder(self, elementOrder):
3230 Return the number of faces with the given order in the mesh
3233 elementOrder: the order of elements
3234 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3240 return self.mesh.NbFacesOfOrder(elementOrder)
3242 def NbTriangles(self):
3244 Return the number of triangles in the mesh
3250 return self.mesh.NbTriangles()
3252 def NbTrianglesOfOrder(self, elementOrder):
3254 Return the number of triangles with the given order in the mesh
3257 elementOrder: is the order of elements
3258 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3264 return self.mesh.NbTrianglesOfOrder(elementOrder)
3266 def NbBiQuadTriangles(self):
3268 Return the number of biquadratic triangles in the mesh
3274 return self.mesh.NbBiQuadTriangles()
3276 def NbQuadrangles(self):
3278 Return the number of quadrangles in the mesh
3284 return self.mesh.NbQuadrangles()
3286 def NbQuadranglesOfOrder(self, elementOrder):
3288 Return the number of quadrangles with the given order in the mesh
3291 elementOrder: the order of elements
3292 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3298 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3300 def NbBiQuadQuadrangles(self):
3302 Return the number of biquadratic quadrangles in the mesh
3308 return self.mesh.NbBiQuadQuadrangles()
3310 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3312 Return the number of polygons of given order in the mesh
3315 elementOrder: the order of elements
3316 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3322 return self.mesh.NbPolygonsOfOrder(elementOrder)
3324 def NbVolumes(self):
3326 Return the number of volumes in the mesh
3332 return self.mesh.NbVolumes()
3335 def NbVolumesOfOrder(self, elementOrder):
3337 Return the number of volumes with the given order in the mesh
3340 elementOrder: the order of elements
3341 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3347 return self.mesh.NbVolumesOfOrder(elementOrder)
3351 Return the number of tetrahedrons in the mesh
3357 return self.mesh.NbTetras()
3359 def NbTetrasOfOrder(self, elementOrder):
3361 Return the number of tetrahedrons with the given order in the mesh
3364 elementOrder: the order of elements
3365 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3371 return self.mesh.NbTetrasOfOrder(elementOrder)
3375 Return the number of hexahedrons in the mesh
3381 return self.mesh.NbHexas()
3383 def NbHexasOfOrder(self, elementOrder):
3385 Return the number of hexahedrons with the given order in the mesh
3388 elementOrder: the order of elements
3389 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3395 return self.mesh.NbHexasOfOrder(elementOrder)
3397 def NbTriQuadraticHexas(self):
3399 Return the number of triquadratic hexahedrons in the mesh
3405 return self.mesh.NbTriQuadraticHexas()
3407 def NbPyramids(self):
3409 Return the number of pyramids in the mesh
3415 return self.mesh.NbPyramids()
3417 def NbPyramidsOfOrder(self, elementOrder):
3419 Return the number of pyramids with the given order in the mesh
3422 elementOrder: the order of elements
3423 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3429 return self.mesh.NbPyramidsOfOrder(elementOrder)
3433 Return the number of prisms in the mesh
3439 return self.mesh.NbPrisms()
3441 def NbPrismsOfOrder(self, elementOrder):
3443 Return the number of prisms with the given order in the mesh
3446 elementOrder: the order of elements
3447 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3453 return self.mesh.NbPrismsOfOrder(elementOrder)
3455 def NbHexagonalPrisms(self):
3457 Return the number of hexagonal prisms in the mesh
3463 return self.mesh.NbHexagonalPrisms()
3465 def NbPolyhedrons(self):
3467 Return the number of polyhedrons in the mesh
3473 return self.mesh.NbPolyhedrons()
3475 def NbSubMesh(self):
3477 Return the number of submeshes in the mesh
3483 return self.mesh.NbSubMesh()
3485 def GetElementsId(self):
3487 Return the list of all mesh elements IDs
3490 the list of integer values
3493 :meth:`GetElementsByType`
3496 return self.mesh.GetElementsId()
3498 def GetElementsByType(self, elementType):
3500 Return the list of IDs of mesh elements with the given type
3503 elementType (SMESH.ElementType): the required type of elements
3506 list of integer values
3509 return self.mesh.GetElementsByType(elementType)
3511 def GetNodesId(self):
3513 Return the list of mesh nodes IDs
3516 the list of integer values
3519 return self.mesh.GetNodesId()
3521 # Get the information about mesh elements:
3522 # ------------------------------------
3524 def GetElementType(self, id, iselem=True):
3526 Return the type of mesh element or node
3529 the value from :class:`SMESH.ElementType` enumeration.
3530 Return SMESH.ALL if element or node with the given ID does not exist
3533 return self.mesh.GetElementType(id, iselem)
3535 def GetElementGeomType(self, id):
3537 Return the geometric type of mesh element
3540 the value from :class:`SMESH.EntityType` enumeration.
3543 return self.mesh.GetElementGeomType(id)
3545 def GetElementShape(self, id):
3547 Return the shape type of mesh element
3550 the value from :class:`SMESH.GeometryType` enumeration.
3553 return self.mesh.GetElementShape(id)
3555 def GetSubMeshElementsId(self, Shape):
3557 Return the list of sub-mesh elements IDs
3560 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3561 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3564 list of integer values
3567 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3568 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3571 return self.mesh.GetSubMeshElementsId(ShapeID)
3573 def GetSubMeshNodesId(self, Shape, all):
3575 Return the list of sub-mesh nodes IDs
3578 Shape: a geom object (sub-shape).
3579 *Shape* must be the sub-shape of a :meth:`GetShape`
3580 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3583 list of integer values
3586 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3587 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3590 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3592 def GetSubMeshElementType(self, Shape):
3594 Return type of elements on given shape
3597 Shape: a geom object (sub-shape).
3598 *Shape* must be a sub-shape of a ShapeToMesh()
3601 :class:`SMESH.ElementType`
3604 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3605 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3608 return self.mesh.GetSubMeshElementType(ShapeID)
3612 Get the mesh description
3618 return self.mesh.Dump()
3621 # Get the information about nodes and elements of a mesh by its IDs:
3622 # -----------------------------------------------------------
3624 def GetNodeXYZ(self, id):
3626 Get XYZ coordinates of a node.
3627 If there is no node for the given ID - return an empty list
3630 list of float values
3633 return self.mesh.GetNodeXYZ(id)
3635 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3637 Return list of IDs of inverse elements for the given node.
3638 If there is no node for the given ID - return an empty list
3642 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3645 list of integer values
3648 return self.mesh.GetNodeInverseElements(id,elemType)
3650 def GetNodePosition(self,NodeID):
3652 Return the position of a node on the shape
3655 :class:`SMESH.NodePosition`
3658 return self.mesh.GetNodePosition(NodeID)
3660 def GetElementPosition(self,ElemID):
3662 Return the position of an element on the shape
3665 :class:`SMESH.ElementPosition`
3668 return self.mesh.GetElementPosition(ElemID)
3670 def GetShapeID(self, id):
3672 Return the ID of the shape, on which the given node was generated.
3675 an integer value > 0 or -1 if there is no node for the given
3676 ID or the node is not assigned to any geometry
3679 return self.mesh.GetShapeID(id)
3681 def GetShapeIDForElem(self,id):
3683 Return the ID of the shape, on which the given element was generated.
3686 an integer value > 0 or -1 if there is no element for the given
3687 ID or the element is not assigned to any geometry
3690 return self.mesh.GetShapeIDForElem(id)
3692 def GetElemNbNodes(self, id):
3694 Return the number of nodes of the given element
3697 an integer value > 0 or -1 if there is no element for the given ID
3700 return self.mesh.GetElemNbNodes(id)
3702 def GetElemNode(self, id, index):
3704 Return the node ID the given (zero based) index for the given element.
3706 * If there is no element for the given ID - return -1.
3707 * If there is no node for the given index - return -2.
3710 id (int): element ID
3711 index (int): node index within the element
3714 an integer value (ID)
3717 :meth:`GetElemNodes`
3720 return self.mesh.GetElemNode(id, index)
3722 def GetElemNodes(self, id):
3724 Return the IDs of nodes of the given element
3727 a list of integer values
3730 return self.mesh.GetElemNodes(id)
3732 def IsMediumNode(self, elementID, nodeID):
3734 Return true if the given node is the medium node in the given quadratic element
3737 return self.mesh.IsMediumNode(elementID, nodeID)
3739 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3741 Return true if the given node is the medium node in one of quadratic elements
3744 nodeID: ID of the node
3745 elementType: the type of elements to check a state of the node, either of
3746 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3749 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3751 def ElemNbEdges(self, id):
3753 Return the number of edges for the given element
3756 return self.mesh.ElemNbEdges(id)
3758 def ElemNbFaces(self, id):
3760 Return the number of faces for the given element
3763 return self.mesh.ElemNbFaces(id)
3765 def GetElemFaceNodes(self,elemId, faceIndex):
3767 Return nodes of given face (counted from zero) for given volumic element.
3770 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3772 def GetFaceNormal(self, faceId, normalized=False):
3774 Return three components of normal of given mesh face
3775 (or an empty array in KO case)
3778 return self.mesh.GetFaceNormal(faceId,normalized)
3780 def FindElementByNodes(self, nodes):
3782 Return an element based on all given nodes.
3785 return self.mesh.FindElementByNodes(nodes)
3787 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3789 Return elements including all given nodes.
3792 return self.mesh.GetElementsByNodes( nodes, elemType )
3794 def IsPoly(self, id):
3796 Return true if the given element is a polygon
3799 return self.mesh.IsPoly(id)
3801 def IsQuadratic(self, id):
3803 Return true if the given element is quadratic
3806 return self.mesh.IsQuadratic(id)
3808 def GetBallDiameter(self, id):
3810 Return diameter of a ball discrete element or zero in case of an invalid *id*
3813 return self.mesh.GetBallDiameter(id)
3815 def BaryCenter(self, id):
3817 Return XYZ coordinates of the barycenter of the given element.
3818 If there is no element for the given ID - return an empty list
3821 a list of three double values
3824 :meth:`smeshBuilder.GetGravityCenter`
3827 return self.mesh.BaryCenter(id)
3829 def GetIdsFromFilter(self, filter, meshParts=[] ):
3831 Pass mesh elements through the given filter and return IDs of fitting elements
3834 filter: :class:`SMESH.Filter`
3835 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3841 :meth:`SMESH.Filter.GetIDs`
3842 :meth:`SMESH.Filter.GetElementsIdFromParts`
3845 filter.SetMesh( self.mesh )
3848 if isinstance( meshParts, Mesh ):
3849 filter.SetMesh( meshParts.GetMesh() )
3850 return theFilter.GetIDs()
3851 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3852 meshParts = [ meshParts ]
3853 return filter.GetElementsIdFromParts( meshParts )
3855 return filter.GetIDs()
3857 # Get mesh measurements information:
3858 # ------------------------------------
3860 def GetFreeBorders(self):
3862 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3863 Return a list of special structures (borders).
3866 a list of :class:`SMESH.FreeEdges.Border`
3869 aFilterMgr = self.smeshpyD.CreateFilterManager()
3870 aPredicate = aFilterMgr.CreateFreeEdges()
3871 aPredicate.SetMesh(self.mesh)
3872 aBorders = aPredicate.GetBorders()
3873 aFilterMgr.UnRegister()
3876 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3878 Get minimum distance between two nodes, elements or distance to the origin
3881 id1: first node/element id
3882 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3883 isElem1: *True* if *id1* is element id, *False* if it is node id
3884 isElem2: *True* if *id2* is element id, *False* if it is node id
3887 minimum distance value
3889 :meth:`GetMinDistance`
3892 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3893 return aMeasure.value
3895 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3897 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3900 id1: first node/element id
3901 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3902 isElem1: *True* if *id1* is element id, *False* if it is node id
3903 isElem2: *True* if *id2* is element id, *False* if it is node id
3906 :class:`SMESH.Measure` structure
3912 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3914 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3917 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3919 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3924 aMeasurements = self.smeshpyD.CreateMeasurements()
3925 aMeasure = aMeasurements.MinDistance(id1, id2)
3926 genObjUnRegister([aMeasurements,id1, id2])
3929 def BoundingBox(self, objects=None, isElem=False):
3931 Get bounding box of the specified object(s)
3934 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3935 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3936 *False* specifies that *objects* are nodes
3939 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3942 :meth:`GetBoundingBox()`
3945 result = self.GetBoundingBox(objects, isElem)
3949 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3952 def GetBoundingBox(self, objects=None, isElem=False):
3954 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3957 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3958 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3959 False means that *objects* are nodes
3962 :class:`SMESH.Measure` structure
3965 :meth:`BoundingBox()`
3969 objects = [self.mesh]
3970 elif isinstance(objects, tuple):
3971 objects = list(objects)
3972 if not isinstance(objects, list):
3974 if len(objects) > 0 and isinstance(objects[0], int):
3977 unRegister = genObjUnRegister()
3979 if isinstance(o, Mesh):
3980 srclist.append(o.mesh)
3981 elif hasattr(o, "_narrow"):
3982 src = o._narrow(SMESH.SMESH_IDSource)
3983 if src: srclist.append(src)
3985 elif isinstance(o, list):
3987 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3989 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3990 unRegister.set( srclist[-1] )
3993 aMeasurements = self.smeshpyD.CreateMeasurements()
3994 unRegister.set( aMeasurements )
3995 aMeasure = aMeasurements.BoundingBox(srclist)
3998 # Mesh edition (SMESH_MeshEditor functionality):
3999 # ---------------------------------------------
4001 def RemoveElements(self, IDsOfElements):
4003 Remove the elements from the mesh by ids
4006 IDsOfElements: is a list of ids of elements to remove
4012 This operation can create gaps in numeration of elements.
4013 Call :meth:`RenumberElements` to remove the gaps.
4016 return self.editor.RemoveElements(IDsOfElements)
4018 def RemoveNodes(self, IDsOfNodes):
4020 Remove nodes from mesh by ids
4023 IDsOfNodes: is a list of ids of nodes to remove
4029 This operation can create gaps in numeration of nodes.
4030 Call :meth:`RenumberElements` to remove the gaps.
4033 return self.editor.RemoveNodes(IDsOfNodes)
4035 def RemoveOrphanNodes(self):
4037 Remove all orphan (free) nodes from mesh
4040 number of the removed nodes
4043 This operation can create gaps in numeration of nodes.
4044 Call :meth:`RenumberElements` to remove the gaps.
4047 return self.editor.RemoveOrphanNodes()
4049 def AddNode(self, x, y, z):
4051 Add a node to the mesh by coordinates
4057 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4058 if hasVars: self.mesh.SetParameters(Parameters)
4059 return self.editor.AddNode( x, y, z)
4061 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4063 Create a 0D element on a node with given number.
4066 IDOfNode: the ID of node for creation of the element.
4067 DuplicateElements: to add one more 0D element to a node or not
4070 ID of the new 0D element
4073 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4075 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4077 Create 0D elements on all nodes of the given elements except those
4078 nodes on which a 0D element already exists.
4081 theObject: an object on whose nodes 0D elements will be created.
4082 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4083 theGroupName: optional name of a group to add 0D elements created
4084 and/or found on nodes of *theObject*.
4085 DuplicateElements: to add one more 0D element to a node or not
4088 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4089 IDs of new and/or found 0D elements. IDs of 0D elements
4090 can be retrieved from the returned object by
4091 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4094 unRegister = genObjUnRegister()
4095 if isinstance( theObject, Mesh ):
4096 theObject = theObject.GetMesh()
4097 elif isinstance( theObject, list ):
4098 theObject = self.GetIDSource( theObject, SMESH.ALL )
4099 unRegister.set( theObject )
4100 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4102 def AddBall(self, IDOfNode, diameter):
4104 Create a ball element on a node with given ID.
4107 IDOfNode: the ID of node for creation of the element.
4108 diameter: the bal diameter.
4111 ID of the new ball element
4114 return self.editor.AddBall( IDOfNode, diameter )
4116 def AddEdge(self, IDsOfNodes):
4118 Create a linear or quadratic edge (this is determined
4119 by the number of given nodes).
4122 IDsOfNodes: list of node IDs for creation of the element.
4123 The order of nodes in this list should correspond to
4124 the :ref:`connectivity convention <connectivity_page>`.
4130 return self.editor.AddEdge(IDsOfNodes)
4132 def AddFace(self, IDsOfNodes):
4134 Create a linear or quadratic face (this is determined
4135 by the number of given nodes).
4138 IDsOfNodes: list of node IDs for creation of the element.
4139 The order of nodes in this list should correspond to
4140 the :ref:`connectivity convention <connectivity_page>`.
4146 return self.editor.AddFace(IDsOfNodes)
4148 def AddPolygonalFace(self, IdsOfNodes):
4150 Add a polygonal face defined by a list of node IDs
4153 IdsOfNodes: the list of node IDs for creation of the element.
4159 return self.editor.AddPolygonalFace(IdsOfNodes)
4161 def AddQuadPolygonalFace(self, IdsOfNodes):
4163 Add a quadratic polygonal face defined by a list of node IDs
4166 IdsOfNodes: the list of node IDs for creation of the element;
4167 corner nodes follow first.
4173 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4175 def AddVolume(self, IDsOfNodes):
4177 Create both simple and quadratic volume (this is determined
4178 by the number of given nodes).
4181 IDsOfNodes: list of node IDs for creation of the element.
4182 The order of nodes in this list should correspond to
4183 the :ref:`connectivity convention <connectivity_page>`.
4186 ID of the new volumic element
4189 return self.editor.AddVolume(IDsOfNodes)
4191 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4193 Create a volume of many faces, giving nodes for each face.
4196 IdsOfNodes: list of node IDs for volume creation, face by face.
4197 Quantities: list of integer values, Quantities[i]
4198 gives the quantity of nodes in face number i.
4201 ID of the new volumic element
4204 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4206 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4208 Create a volume of many faces, giving the IDs of the existing faces.
4211 The created volume will refer only to the nodes
4212 of the given faces, not to the faces themselves.
4215 IdsOfFaces: the list of face IDs for volume creation.
4218 ID of the new volumic element
4221 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4224 def SetNodeOnVertex(self, NodeID, Vertex):
4226 Bind a node to a vertex
4230 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4233 True if succeed else raises an exception
4236 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4237 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4241 self.editor.SetNodeOnVertex(NodeID, VertexID)
4242 except SALOME.SALOME_Exception as inst:
4243 raise ValueError(inst.details.text)
4247 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4249 Store the node position on an edge
4253 Edge: an edge (GEOM.GEOM_Object) or edge ID
4254 paramOnEdge: a parameter on the edge where the node is located
4257 True if succeed else raises an exception
4260 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4261 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4265 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4266 except SALOME.SALOME_Exception as inst:
4267 raise ValueError(inst.details.text)
4270 def SetNodeOnFace(self, NodeID, Face, u, v):
4272 Store node position on a face
4276 Face: a face (GEOM.GEOM_Object) or face ID
4277 u: U parameter on the face where the node is located
4278 v: V parameter on the face where the node is located
4281 True if succeed else raises an exception
4284 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4285 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4289 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4290 except SALOME.SALOME_Exception as inst:
4291 raise ValueError(inst.details.text)
4294 def SetNodeInVolume(self, NodeID, Solid):
4296 Bind a node to a solid
4300 Solid: a solid (GEOM.GEOM_Object) or solid ID
4303 True if succeed else raises an exception
4306 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4307 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4311 self.editor.SetNodeInVolume(NodeID, SolidID)
4312 except SALOME.SALOME_Exception as inst:
4313 raise ValueError(inst.details.text)
4316 def SetMeshElementOnShape(self, ElementID, Shape):
4318 Bind an element to a shape
4321 ElementID: an element ID
4322 Shape: a shape (GEOM.GEOM_Object) or shape ID
4325 True if succeed else raises an exception
4328 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4329 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4333 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4334 except SALOME.SALOME_Exception as inst:
4335 raise ValueError(inst.details.text)
4339 def MoveNode(self, NodeID, x, y, z):
4341 Move the node with the given id
4344 NodeID: the id of the node
4345 x: a new X coordinate
4346 y: a new Y coordinate
4347 z: a new Z coordinate
4350 True if succeed else False
4353 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4354 if hasVars: self.mesh.SetParameters(Parameters)
4355 return self.editor.MoveNode(NodeID, x, y, z)
4357 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4359 Find the node closest to a point and moves it to a point location
4362 x: the X coordinate of a point
4363 y: the Y coordinate of a point
4364 z: the Z coordinate of a point
4365 NodeID: if specified (>0), the node with this ID is moved,
4366 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4369 the ID of a moved node
4372 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4373 if hasVars: self.mesh.SetParameters(Parameters)
4374 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4376 def FindNodeClosestTo(self, x, y, z):
4378 Find the node closest to a point
4381 x: the X coordinate of a point
4382 y: the Y coordinate of a point
4383 z: the Z coordinate of a point
4389 return self.editor.FindNodeClosestTo(x, y, z)
4391 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4393 Find the elements where a point lays IN or ON
4396 x,y,z (float): coordinates of the point
4397 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4398 means elements of any type excluding nodes, discrete and 0D elements.
4399 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4402 list of IDs of found elements
4405 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4407 return self.editor.FindElementsByPoint(x, y, z, elementType)
4409 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4411 Project a point to a mesh object.
4412 Return ID of an element of given type where the given point is projected
4413 and coordinates of the projection point.
4414 In the case if nothing found, return -1 and []
4416 if isinstance( meshObject, Mesh ):
4417 meshObject = meshObject.GetMesh()
4419 meshObject = self.GetMesh()
4420 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4422 def GetPointState(self, x, y, z):
4424 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4425 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4426 UNKNOWN state means that either mesh is wrong or the analysis fails.
4429 return self.editor.GetPointState(x, y, z)
4431 def IsManifold(self):
4433 Check if a 2D mesh is manifold
4436 return self.editor.IsManifold()
4438 def IsCoherentOrientation2D(self):
4440 Check if orientation of 2D elements is coherent
4443 return self.editor.IsCoherentOrientation2D()
4445 def Get1DBranches( self, edges, startNode = 0 ):
4447 Partition given 1D elements into groups of contiguous edges.
4448 A node where number of meeting edges != 2 is a group end.
4449 An optional startNode is used to orient groups it belongs to.
4452 A list of edge groups and a list of corresponding node groups,
4453 where the group is a list of IDs of edges or nodes, like follows
4454 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4455 If a group is closed, the first and last nodes of the group are same.
4457 if isinstance( edges, Mesh ):
4458 edges = edges.GetMesh()
4459 unRegister = genObjUnRegister()
4460 if isinstance( edges, list ):
4461 edges = self.GetIDSource( edges, SMESH.EDGE )
4462 unRegister.set( edges )
4463 return self.editor.Get1DBranches( edges, startNode )
4465 def FindSharpEdges( self, angle, addExisting=False ):
4467 Return sharp edges of faces and non-manifold ones.
4468 Optionally add existing edges.
4471 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4472 addExisting: to return existing edges (1D elements) as well
4475 list of FaceEdge structures
4477 angle = ParseParameters( angle )[0]
4478 return self.editor.FindSharpEdges( angle, addExisting )
4480 def MeshToPassThroughAPoint(self, x, y, z):
4482 Find the node closest to a point and moves it to a point location
4485 x: the X coordinate of a point
4486 y: the Y coordinate of a point
4487 z: the Z coordinate of a point
4490 the ID of a moved node
4493 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4495 def InverseDiag(self, NodeID1, NodeID2):
4497 Replace two neighbour triangles sharing Node1-Node2 link
4498 with the triangles built on the same 4 nodes but having other common link.
4501 NodeID1: the ID of the first node
4502 NodeID2: the ID of the second node
4505 False if proper faces were not found
4507 return self.editor.InverseDiag(NodeID1, NodeID2)
4509 def DeleteDiag(self, NodeID1, NodeID2):
4511 Replace two neighbour triangles sharing *Node1-Node2* link
4512 with a quadrangle built on the same 4 nodes.
4515 NodeID1: ID of the first node
4516 NodeID2: ID of the second node
4519 False if proper faces were not found
4522 This operation can create gaps in numeration of elements.
4523 Call :meth:`RenumberElements` to remove the gaps.
4526 return self.editor.DeleteDiag(NodeID1, NodeID2)
4528 def Reorient(self, IDsOfElements=None):
4530 Reorient elements by ids
4533 IDsOfElements: if undefined reorients all mesh elements
4536 True if succeed else False
4539 if IDsOfElements == None:
4540 IDsOfElements = self.GetElementsId()
4541 return self.editor.Reorient(IDsOfElements)
4543 def ReorientObject(self, theObject):
4545 Reorient all elements of the object
4548 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4551 True if succeed else False
4554 if ( isinstance( theObject, Mesh )):
4555 theObject = theObject.GetMesh()
4556 return self.editor.ReorientObject(theObject)
4558 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4560 Reorient faces contained in *the2DObject*.
4563 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4564 theDirection: a desired direction of normal of *theFace*.
4565 It can be either a GEOM vector or a list of coordinates [x,y,z].
4566 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4567 compared with theDirection. It can be either ID of face or a point
4568 by which the face will be found. The point can be given as either
4569 a GEOM vertex or a list of point coordinates.
4572 number of reoriented faces
4575 unRegister = genObjUnRegister()
4577 if isinstance( the2DObject, Mesh ):
4578 the2DObject = the2DObject.GetMesh()
4579 if isinstance( the2DObject, list ):
4580 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4581 unRegister.set( the2DObject )
4582 # check theDirection
4583 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4584 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4585 if isinstance( theDirection, list ):
4586 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4587 # prepare theFace and thePoint
4588 theFace = theFaceOrPoint
4589 thePoint = PointStruct(0,0,0)
4590 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4591 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4593 if isinstance( theFaceOrPoint, list ):
4594 thePoint = PointStruct( *theFaceOrPoint )
4596 if isinstance( theFaceOrPoint, PointStruct ):
4597 thePoint = theFaceOrPoint
4599 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4601 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4603 Reorient faces according to adjacent volumes.
4606 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4607 either IDs of faces or face groups.
4608 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4609 theOutsideNormal: to orient faces to have their normals
4610 pointing either *outside* or *inside* the adjacent volumes.
4613 number of reoriented faces.
4616 unRegister = genObjUnRegister()
4618 if not isinstance( the2DObject, list ):
4619 the2DObject = [ the2DObject ]
4620 elif the2DObject and isinstance( the2DObject[0], int ):
4621 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4622 unRegister.set( the2DObject )
4623 the2DObject = [ the2DObject ]
4624 for i,obj2D in enumerate( the2DObject ):
4625 if isinstance( obj2D, Mesh ):
4626 the2DObject[i] = obj2D.GetMesh()
4627 if isinstance( obj2D, list ):
4628 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4629 unRegister.set( the2DObject[i] )
4631 if isinstance( the3DObject, Mesh ):
4632 the3DObject = the3DObject.GetMesh()
4633 if isinstance( the3DObject, list ):
4634 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4635 unRegister.set( the3DObject )
4636 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4638 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4640 Fuse the neighbouring triangles into quadrangles.
4643 IDsOfElements: The triangles to be fused.
4644 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4645 applied to possible quadrangles to choose a neighbour to fuse with.
4646 Note that not all items of :class:`SMESH.FunctorType` corresponds
4647 to numerical functors.
4648 MaxAngle: is the maximum angle between element normals at which the fusion
4649 is still performed; theMaxAngle is measured in radians.
4650 Also it could be a name of variable which defines angle in degrees.
4653 True in case of success, False otherwise.
4656 This operation can create gaps in numeration of elements.
4657 Call :meth:`RenumberElements` to remove the gaps.
4660 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4661 self.mesh.SetParameters(Parameters)
4662 if not IDsOfElements:
4663 IDsOfElements = self.GetElementsId()
4664 Functor = self.smeshpyD.GetFunctor(theCriterion)
4665 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4667 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4669 Fuse the neighbouring triangles of the object into quadrangles
4672 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4673 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4674 applied to possible quadrangles to choose a neighbour to fuse with.
4675 Note that not all items of :class:`SMESH.FunctorType` corresponds
4676 to numerical functors.
4677 MaxAngle: a max angle between element normals at which the fusion
4678 is still performed; theMaxAngle is measured in radians.
4681 True in case of success, False otherwise.
4684 This operation can create gaps in numeration of elements.
4685 Call :meth:`RenumberElements` to remove the gaps.
4688 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4689 self.mesh.SetParameters(Parameters)
4690 if isinstance( theObject, Mesh ):
4691 theObject = theObject.GetMesh()
4692 Functor = self.smeshpyD.GetFunctor(theCriterion)
4693 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4695 def QuadToTri (self, IDsOfElements, theCriterion = None):
4697 Split quadrangles into triangles.
4700 IDsOfElements: the faces to be splitted.
4701 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4702 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4703 value, then quadrangles will be split by the smallest diagonal.
4704 Note that not all items of :class:`SMESH.FunctorType` corresponds
4705 to numerical functors.
4708 True in case of success, False otherwise.
4711 This operation can create gaps in numeration of elements.
4712 Call :meth:`RenumberElements` to remove the gaps.
4714 if IDsOfElements == []:
4715 IDsOfElements = self.GetElementsId()
4716 if theCriterion is None:
4717 theCriterion = FT_MaxElementLength2D
4718 Functor = self.smeshpyD.GetFunctor(theCriterion)
4719 return self.editor.QuadToTri(IDsOfElements, Functor)
4721 def QuadToTriObject (self, theObject, theCriterion = None):
4723 Split quadrangles into triangles.
4726 theObject: the object from which the list of elements is taken,
4727 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4728 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4729 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4730 value, then quadrangles will be split by the smallest diagonal.
4731 Note that not all items of :class:`SMESH.FunctorType` corresponds
4732 to numerical functors.
4735 True in case of success, False otherwise.
4738 This operation can create gaps in numeration of elements.
4739 Call :meth:`RenumberElements` to remove the gaps.
4741 if ( isinstance( theObject, Mesh )):
4742 theObject = theObject.GetMesh()
4743 if theCriterion is None:
4744 theCriterion = FT_MaxElementLength2D
4745 Functor = self.smeshpyD.GetFunctor(theCriterion)
4746 return self.editor.QuadToTriObject(theObject, Functor)
4748 def QuadTo4Tri (self, theElements=[]):
4750 Split each of given quadrangles into 4 triangles. A node is added at the center of
4754 theElements: the faces to be splitted. This can be either
4755 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4756 or a list of face IDs. By default all quadrangles are split
4759 This operation can create gaps in numeration of elements.
4760 Call :meth:`RenumberElements` to remove the gaps.
4762 unRegister = genObjUnRegister()
4763 if isinstance( theElements, Mesh ):
4764 theElements = theElements.mesh
4765 elif not theElements:
4766 theElements = self.mesh
4767 elif isinstance( theElements, list ):
4768 theElements = self.GetIDSource( theElements, SMESH.FACE )
4769 unRegister.set( theElements )
4770 return self.editor.QuadTo4Tri( theElements )
4772 def SplitQuad (self, IDsOfElements, Diag13):
4774 Split quadrangles into triangles.
4777 IDsOfElements: the faces to be splitted
4778 Diag13 (boolean): is used to choose a diagonal for splitting.
4781 True in case of success, False otherwise.
4784 This operation can create gaps in numeration of elements.
4785 Call :meth:`RenumberElements` to remove the gaps.
4787 if IDsOfElements == []:
4788 IDsOfElements = self.GetElementsId()
4789 return self.editor.SplitQuad(IDsOfElements, Diag13)
4791 def SplitQuadObject (self, theObject, Diag13):
4793 Split quadrangles into triangles.
4796 theObject: the object from which the list of elements is taken,
4797 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4798 Diag13 (boolean): is used to choose a diagonal for splitting.
4801 True in case of success, False otherwise.
4804 This operation can create gaps in numeration of elements.
4805 Call :meth:`RenumberElements` to remove the gaps.
4807 if ( isinstance( theObject, Mesh )):
4808 theObject = theObject.GetMesh()
4809 return self.editor.SplitQuadObject(theObject, Diag13)
4811 def BestSplit (self, IDOfQuad, theCriterion):
4813 Find a better splitting of the given quadrangle.
4816 IDOfQuad: the ID of the quadrangle to be splitted.
4817 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4818 choose a diagonal for splitting.
4819 Note that not all items of :class:`SMESH.FunctorType` corresponds
4820 to numerical functors.
4823 * 1 if 1-3 diagonal is better,
4824 * 2 if 2-4 diagonal is better,
4825 * 0 if error occurs.
4828 This operation can create gaps in numeration of elements.
4829 Call :meth:`RenumberElements` to remove the gaps.
4831 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4833 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4835 Split volumic elements into tetrahedrons
4838 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4839 method: flags passing splitting method:
4840 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4841 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4844 This operation can create gaps in numeration of elements.
4845 Call :meth:`RenumberElements` to remove the gaps.
4847 unRegister = genObjUnRegister()
4848 if isinstance( elems, Mesh ):
4849 elems = elems.GetMesh()
4850 if ( isinstance( elems, list )):
4851 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4852 unRegister.set( elems )
4853 self.editor.SplitVolumesIntoTetra(elems, method)
4856 def SplitBiQuadraticIntoLinear(self, elems=None):
4858 Split bi-quadratic elements into linear ones without creation of additional nodes:
4860 - bi-quadratic triangle will be split into 3 linear quadrangles;
4861 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4862 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4864 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4865 will be split in order to keep the mesh conformal.
4868 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4869 if None (default), all bi-quadratic elements will be split
4872 This operation can create gaps in numeration of elements.
4873 Call :meth:`RenumberElements` to remove the gaps.
4875 unRegister = genObjUnRegister()
4876 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4877 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4878 unRegister.set( elems )
4880 elems = [ self.GetMesh() ]
4881 if isinstance( elems, Mesh ):
4882 elems = [ elems.GetMesh() ]
4883 if not isinstance( elems, list ):
4885 self.editor.SplitBiQuadraticIntoLinear( elems )
4887 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4888 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4890 Split hexahedra into prisms
4893 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4894 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4895 gives a normal vector defining facets to split into triangles.
4896 *startHexPoint* can be either a triple of coordinates or a vertex.
4897 facetNormal: a normal to a facet to split into triangles of a
4898 hexahedron found by *startHexPoint*.
4899 *facetNormal* can be either a triple of coordinates or an edge.
4900 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4901 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4902 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4903 to *startHexPoint* are split, else *startHexPoint*
4904 is used to find the facet to split in all domains present in *elems*.
4907 This operation can create gaps in numeration of elements.
4908 Call :meth:`RenumberElements` to remove the gaps.
4911 unRegister = genObjUnRegister()
4912 if isinstance( elems, Mesh ):
4913 elems = elems.GetMesh()
4914 if ( isinstance( elems, list )):
4915 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4916 unRegister.set( elems )
4919 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4920 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4921 elif isinstance( startHexPoint, list ):
4922 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4925 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4926 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4927 elif isinstance( facetNormal, list ):
4928 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4931 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4933 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4935 def SplitQuadsNearTriangularFacets(self):
4937 Split quadrangle faces near triangular facets of volumes
4940 This operation can create gaps in numeration of elements.
4941 Call :meth:`RenumberElements` to remove the gaps.
4943 faces_array = self.GetElementsByType(SMESH.FACE)
4944 for face_id in faces_array:
4945 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4946 quad_nodes = self.mesh.GetElemNodes(face_id)
4947 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4948 isVolumeFound = False
4949 for node1_elem in node1_elems:
4950 if not isVolumeFound:
4951 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4952 nb_nodes = self.GetElemNbNodes(node1_elem)
4953 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4954 volume_elem = node1_elem
4955 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4956 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4957 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4958 isVolumeFound = True
4959 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4960 self.SplitQuad([face_id], False) # diagonal 2-4
4961 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4962 isVolumeFound = True
4963 self.SplitQuad([face_id], True) # diagonal 1-3
4964 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4965 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4966 isVolumeFound = True
4967 self.SplitQuad([face_id], True) # diagonal 1-3
4969 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4971 Split hexahedrons into tetrahedrons.
4973 This operation uses :doc:`pattern_mapping` functionality for splitting.
4976 theObject: the object from which the list of hexahedrons is taken;
4977 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4978 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4979 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4980 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4981 key-point will be mapped into *theNode001*-th node of each volume.
4982 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4985 True in case of success, False otherwise.
4988 This operation can create gaps in numeration of elements.
4989 Call :meth:`RenumberElements` to remove the gaps.
4997 # (0,0,1) 4.---------.7 * |
5004 # (0,0,0) 0.---------.3
5005 pattern_tetra = "!!! Nb of points: \n 8 \n\
5015 !!! Indices of points of 6 tetras: \n\
5023 pattern = self.smeshpyD.GetPattern()
5024 isDone = pattern.LoadFromFile(pattern_tetra)
5026 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5029 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5030 isDone = pattern.MakeMesh(self.mesh, False, False)
5031 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5033 # split quafrangle faces near triangular facets of volumes
5034 self.SplitQuadsNearTriangularFacets()
5038 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5040 Split hexahedrons into prisms.
5042 Uses the :doc:`pattern_mapping` functionality for splitting.
5045 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5046 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5047 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5048 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5049 will be mapped into the *theNode001* -th node of each volume.
5050 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5053 True in case of success, False otherwise.
5056 This operation can create gaps in numeration of elements.
5057 Call :meth:`RenumberElements` to remove the gaps.
5059 # Pattern: 5.---------.6
5064 # (0,0,1) 4.---------.7 |
5071 # (0,0,0) 0.---------.3
5072 pattern_prism = "!!! Nb of points: \n 8 \n\
5082 !!! Indices of points of 2 prisms: \n\
5086 pattern = self.smeshpyD.GetPattern()
5087 isDone = pattern.LoadFromFile(pattern_prism)
5089 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5092 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5093 isDone = pattern.MakeMesh(self.mesh, False, False)
5094 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5096 # Split quafrangle faces near triangular facets of volumes
5097 self.SplitQuadsNearTriangularFacets()
5101 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5102 MaxNbOfIterations, MaxAspectRatio, Method):
5107 IDsOfElements: the list if ids of elements to smooth
5108 IDsOfFixedNodes: the list of ids of fixed nodes.
5109 Note that nodes built on edges and boundary nodes are always fixed.
5110 MaxNbOfIterations: the maximum number of iterations
5111 MaxAspectRatio: varies in range [1.0, inf]
5112 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5113 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5116 True in case of success, False otherwise.
5119 if IDsOfElements == []:
5120 IDsOfElements = self.GetElementsId()
5121 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5122 self.mesh.SetParameters(Parameters)
5123 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5124 MaxNbOfIterations, MaxAspectRatio, Method)
5126 def SmoothObject(self, theObject, IDsOfFixedNodes,
5127 MaxNbOfIterations, MaxAspectRatio, Method):
5129 Smooth elements which belong to the given object
5132 theObject: the object to smooth
5133 IDsOfFixedNodes: the list of ids of fixed nodes.
5134 Note that nodes built on edges and boundary nodes are always fixed.
5135 MaxNbOfIterations: the maximum number of iterations
5136 MaxAspectRatio: varies in range [1.0, inf]
5137 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5138 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5141 True in case of success, False otherwise.
5144 if ( isinstance( theObject, Mesh )):
5145 theObject = theObject.GetMesh()
5146 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5147 MaxNbOfIterations, MaxAspectRatio, Method)
5149 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5150 MaxNbOfIterations, MaxAspectRatio, Method):
5152 Parametrically smooth the given elements
5155 IDsOfElements: the list if ids of elements to smooth
5156 IDsOfFixedNodes: the list of ids of fixed nodes.
5157 Note that nodes built on edges and boundary nodes are always fixed.
5158 MaxNbOfIterations: the maximum number of iterations
5159 MaxAspectRatio: varies in range [1.0, inf]
5160 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5161 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5164 True in case of success, False otherwise.
5167 if IDsOfElements == []:
5168 IDsOfElements = self.GetElementsId()
5169 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5170 self.mesh.SetParameters(Parameters)
5171 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5172 MaxNbOfIterations, MaxAspectRatio, Method)
5174 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5175 MaxNbOfIterations, MaxAspectRatio, Method):
5177 Parametrically smooth the elements which belong to the given object
5180 theObject: the object to smooth
5181 IDsOfFixedNodes: the list of ids of fixed nodes.
5182 Note that nodes built on edges and boundary nodes are always fixed.
5183 MaxNbOfIterations: the maximum number of iterations
5184 MaxAspectRatio: varies in range [1.0, inf]
5185 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5186 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5189 True in case of success, False otherwise.
5192 if ( isinstance( theObject, Mesh )):
5193 theObject = theObject.GetMesh()
5194 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5195 MaxNbOfIterations, MaxAspectRatio, Method)
5197 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5199 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5200 them with quadratic with the same id.
5203 theForce3d: method of new node creation:
5205 * False - the medium node lies at the geometrical entity from which the mesh element is built
5206 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5207 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5208 theToBiQuad: If True, converts the mesh to bi-quadratic
5211 :class:`SMESH.ComputeError` which can hold a warning
5214 If *theSubMesh* is provided, the mesh can become non-conformal
5217 This operation can create gaps in numeration of nodes or elements.
5218 Call :meth:`RenumberElements` to remove the gaps.
5221 if isinstance( theSubMesh, Mesh ):
5222 theSubMesh = theSubMesh.mesh
5224 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5227 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5229 self.editor.ConvertToQuadratic(theForce3d)
5230 error = self.editor.GetLastError()
5231 if error and error.comment:
5232 print(error.comment)
5235 def ConvertFromQuadratic(self, theSubMesh=None):
5237 Convert the mesh from quadratic to ordinary,
5238 deletes old quadratic elements,
5239 replacing them with ordinary mesh elements with the same id.
5242 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5245 If *theSubMesh* is provided, the mesh can become non-conformal
5248 This operation can create gaps in numeration of nodes or elements.
5249 Call :meth:`RenumberElements` to remove the gaps.
5253 self.editor.ConvertFromQuadraticObject(theSubMesh)
5255 return self.editor.ConvertFromQuadratic()
5257 def Make2DMeshFrom3D(self):
5259 Create 2D mesh as skin on boundary faces of a 3D mesh
5262 True if operation has been completed successfully, False otherwise
5265 return self.editor.Make2DMeshFrom3D()
5267 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5268 toCopyElements=False, toCopyExistingBondary=False):
5270 Create missing boundary elements
5273 elements: elements whose boundary is to be checked:
5274 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5275 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5276 dimension: defines type of boundary elements to create, either of
5277 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5278 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5279 groupName: a name of group to store created boundary elements in,
5280 "" means not to create the group
5281 meshName: a name of new mesh to store created boundary elements in,
5282 "" means not to create the new mesh
5283 toCopyElements: if True, the checked elements will be copied into
5284 the new mesh else only boundary elements will be copied into the new mesh
5285 toCopyExistingBondary: if True, not only new but also pre-existing
5286 boundary elements will be copied into the new mesh
5289 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5292 unRegister = genObjUnRegister()
5293 if isinstance( elements, Mesh ):
5294 elements = elements.GetMesh()
5295 if ( isinstance( elements, list )):
5296 elemType = SMESH.ALL
5297 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5298 elements = self.editor.MakeIDSource(elements, elemType)
5299 unRegister.set( elements )
5300 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5301 toCopyElements,toCopyExistingBondary)
5302 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5305 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5306 toCopyAll=False, groups=[]):
5308 Create missing boundary elements around either the whole mesh or
5312 dimension: defines type of boundary elements to create, either of
5313 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5314 groupName: a name of group to store all boundary elements in,
5315 "" means not to create the group
5316 meshName: a name of a new mesh, which is a copy of the initial
5317 mesh + created boundary elements; "" means not to create the new mesh
5318 toCopyAll: if True, the whole initial mesh will be copied into
5319 the new mesh else only boundary elements will be copied into the new mesh
5320 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5323 tuple( long, mesh, group )
5324 - long - number of added boundary elements
5325 - mesh - the :class:`Mesh` where elements were added to
5326 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5329 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5331 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5332 return nb, mesh, group
5334 def RenumberNodes(self):
5336 Renumber mesh nodes to remove unused node IDs
5338 self.editor.RenumberNodes()
5340 def RenumberElements(self):
5342 Renumber mesh elements to remove unused element IDs
5344 self.editor.RenumberElements()
5346 def _getIdSourceList(self, arg, idType, unRegister):
5348 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5350 if arg and isinstance( arg, list ):
5351 if isinstance( arg[0], int ):
5352 arg = self.GetIDSource( arg, idType )
5353 unRegister.set( arg )
5354 elif isinstance( arg[0], Mesh ):
5355 arg[0] = arg[0].GetMesh()
5356 elif isinstance( arg, Mesh ):
5358 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5362 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5363 MakeGroups=False, TotalAngle=False):
5365 Generate new elements by rotation of the given elements and nodes around the axis
5368 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5369 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5370 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5371 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5372 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5373 which defines angle in degrees
5374 NbOfSteps: the number of steps
5375 Tolerance: tolerance
5376 MakeGroups: forces the generation of new groups from existing ones
5377 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5378 of all steps, else - size of each step
5381 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5384 unRegister = genObjUnRegister()
5385 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5386 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5387 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5389 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5390 Axis = self.smeshpyD.GetAxisStruct( Axis )
5391 if isinstance( Axis, list ):
5392 Axis = SMESH.AxisStruct( *Axis )
5394 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5395 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5396 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5397 self.mesh.SetParameters(Parameters)
5398 if TotalAngle and NbOfSteps:
5399 AngleInRadians /= NbOfSteps
5400 return self.editor.RotationSweepObjects( nodes, edges, faces,
5401 Axis, AngleInRadians,
5402 NbOfSteps, Tolerance, MakeGroups)
5404 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5405 MakeGroups=False, TotalAngle=False):
5407 Generate new elements by rotation of the elements around the axis
5410 IDsOfElements: the list of ids of elements to sweep
5411 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5412 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5413 NbOfSteps: the number of steps
5414 Tolerance: tolerance
5415 MakeGroups: forces the generation of new groups from existing ones
5416 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5417 of all steps, else - size of each step
5420 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5423 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5424 AngleInRadians, NbOfSteps, Tolerance,
5425 MakeGroups, TotalAngle)
5427 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5428 MakeGroups=False, TotalAngle=False):
5430 Generate new elements by rotation of the elements of object around the axis
5431 theObject object which elements should be sweeped.
5432 It can be a mesh, a sub mesh or a group.
5435 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5436 AngleInRadians: the angle of Rotation
5437 NbOfSteps: number of steps
5438 Tolerance: tolerance
5439 MakeGroups: forces the generation of new groups from existing ones
5440 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5441 of all steps, else - size of each step
5444 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5447 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5448 AngleInRadians, NbOfSteps, Tolerance,
5449 MakeGroups, TotalAngle )
5451 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5452 MakeGroups=False, TotalAngle=False):
5454 Generate new elements by rotation of the elements of object around the axis
5455 theObject object which elements should be sweeped.
5456 It can be a mesh, a sub mesh or a group.
5459 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5460 AngleInRadians: the angle of Rotation
5461 NbOfSteps: number of steps
5462 Tolerance: tolerance
5463 MakeGroups: forces the generation of new groups from existing ones
5464 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5465 of all steps, else - size of each step
5468 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5469 empty list otherwise
5472 return self.RotationSweepObjects([],theObject,[], Axis,
5473 AngleInRadians, NbOfSteps, Tolerance,
5474 MakeGroups, TotalAngle)
5476 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5477 MakeGroups=False, TotalAngle=False):
5479 Generate new elements by rotation of the elements of object around the axis
5480 theObject object which elements should be sweeped.
5481 It can be a mesh, a sub mesh or a group.
5484 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5485 AngleInRadians: the angle of Rotation
5486 NbOfSteps: number of steps
5487 Tolerance: tolerance
5488 MakeGroups: forces the generation of new groups from existing ones
5489 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5490 of all steps, else - size of each step
5493 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5496 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5497 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5499 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5500 scaleFactors=[], linearVariation=False, basePoint=[],
5501 angles=[], anglesVariation=False):
5503 Generate new elements by extrusion of the given elements and nodes
5506 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5507 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5508 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5509 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5510 the direction and value of extrusion for one step (the total extrusion
5511 length will be NbOfSteps * ||StepVector||)
5512 NbOfSteps: the number of steps
5513 MakeGroups: forces the generation of new groups from existing ones
5514 scaleFactors: optional scale factors to apply during extrusion
5515 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5516 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5517 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5518 nodes and elements being extruded is used as the scaling center.
5521 - a list of tree components of the point or
5524 angles: list of angles in radians. Nodes at each extrusion step are rotated
5525 around *basePoint*, additionally to previous steps.
5526 anglesVariation: forces the computation of rotation angles as linear
5527 variation of the given *angles* along path steps
5529 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5531 Example: :ref:`tui_extrusion`
5533 unRegister = genObjUnRegister()
5534 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5535 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5536 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5538 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5539 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5540 if isinstance( StepVector, list ):
5541 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5543 if isinstance( basePoint, int):
5544 xyz = self.GetNodeXYZ( basePoint )
5546 raise RuntimeError("Invalid node ID: %s" % basePoint)
5548 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5549 basePoint = self.geompyD.PointCoordinates( basePoint )
5551 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5552 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5553 angles,angleParameters,hasVars = ParseAngles(angles)
5554 Parameters = StepVector.PS.parameters + var_separator + \
5555 Parameters + var_separator + \
5556 scaleParameters + var_separator + angleParameters
5557 self.mesh.SetParameters(Parameters)
5559 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5560 StepVector, NbOfSteps, MakeGroups,
5561 scaleFactors, linearVariation, basePoint,
5562 angles, anglesVariation )
5565 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5567 Generate new elements by extrusion of the elements with given ids
5570 IDsOfElements: the list of ids of elements or nodes for extrusion
5571 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5572 the direction and value of extrusion for one step (the total extrusion
5573 length will be NbOfSteps * ||StepVector||)
5574 NbOfSteps: the number of steps
5575 MakeGroups: forces the generation of new groups from existing ones
5576 IsNodes: is True if elements with given ids are nodes
5579 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5581 Example: :ref:`tui_extrusion`
5584 if IsNodes: n = IDsOfElements
5585 else : e,f, = IDsOfElements,IDsOfElements
5586 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5588 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5589 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5591 Generate new elements by extrusion along the normal to a discretized surface or wire
5594 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5595 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5596 StepSize: length of one extrusion step (the total extrusion
5597 length will be *NbOfSteps* *StepSize*).
5598 NbOfSteps: number of extrusion steps.
5599 ByAverageNormal: if True each node is translated by *StepSize*
5600 along the average of the normal vectors to the faces sharing the node;
5601 else each node is translated along the same average normal till
5602 intersection with the plane got by translation of the face sharing
5603 the node along its own normal by *StepSize*.
5604 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5605 for every node of *Elements*.
5606 MakeGroups: forces generation of new groups from existing ones.
5607 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5608 is not yet implemented. This parameter is used if *Elements* contains
5609 both faces and edges, i.e. *Elements* is a Mesh.
5612 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5613 empty list otherwise.
5614 Example: :ref:`tui_extrusion`
5617 unRegister = genObjUnRegister()
5618 if isinstance( Elements, Mesh ):
5619 Elements = [ Elements.GetMesh() ]
5620 if isinstance( Elements, list ):
5622 raise RuntimeError("Elements empty!")
5623 if isinstance( Elements[0], Mesh ):
5624 Elements = [ Elements[0].GetMesh() ]
5625 if isinstance( Elements[0], int ):
5626 Elements = self.GetIDSource( Elements, SMESH.ALL )
5627 unRegister.set( Elements )
5628 if not isinstance( Elements, list ):
5629 Elements = [ Elements ]
5630 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5631 self.mesh.SetParameters(Parameters)
5632 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5633 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5635 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5637 Generate new elements by extrusion of the elements or nodes which belong to the object
5640 theObject: the object whose elements or nodes should be processed.
5641 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5642 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5643 the direction and value of extrusion for one step (the total extrusion
5644 length will be NbOfSteps * ||StepVector||)
5645 NbOfSteps: the number of steps
5646 MakeGroups: forces the generation of new groups from existing ones
5647 IsNodes: is True if elements to extrude are nodes
5650 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5651 Example: :ref:`tui_extrusion`
5655 if IsNodes: n = theObject
5656 else : e,f, = theObject,theObject
5657 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5659 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5661 Generate new elements by extrusion of edges which belong to the object
5664 theObject: object whose 1D elements should be processed.
5665 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5666 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5667 the direction and value of extrusion for one step (the total extrusion
5668 length will be NbOfSteps * ||StepVector||)
5669 NbOfSteps: the number of steps
5670 MakeGroups: to generate new groups from existing ones
5673 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5674 Example: :ref:`tui_extrusion`
5677 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5679 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5681 Generate new elements by extrusion of faces which belong to the object
5684 theObject: object whose 2D elements should be processed.
5685 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5686 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5687 the direction and value of extrusion for one step (the total extrusion
5688 length will be NbOfSteps * ||StepVector||)
5689 NbOfSteps: the number of steps
5690 MakeGroups: forces the generation of new groups from existing ones
5693 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5694 Example: :ref:`tui_extrusion`
5697 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5699 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5700 ExtrFlags, SewTolerance, MakeGroups=False):
5702 Generate new elements by extrusion of the elements with given ids
5705 IDsOfElements: is ids of elements
5706 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5707 the direction and value of extrusion for one step (the total extrusion
5708 length will be NbOfSteps * ||StepVector||)
5709 NbOfSteps: the number of steps
5710 ExtrFlags: sets flags for extrusion
5711 SewTolerance: uses for comparing locations of nodes if flag
5712 EXTRUSION_FLAG_SEW is set
5713 MakeGroups: forces the generation of new groups from existing ones
5716 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5719 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5720 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5721 if isinstance( StepVector, list ):
5722 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5723 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5724 ExtrFlags, SewTolerance, MakeGroups)
5726 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5727 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5728 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5729 ScaleFactors=[], ScalesVariation=False):
5731 Generate new elements by extrusion of the given elements and nodes along the path.
5732 The path of extrusion must be a meshed edge.
5735 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5736 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5737 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5738 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5739 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
5740 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5741 HasAngles: not used obsolete
5742 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5743 around *basePoint*, additionally to previous steps.
5744 LinearVariation: forces the computation of rotation angles as linear
5745 variation of the given Angles along path steps
5746 HasRefPoint: allows using the reference point
5747 RefPoint: optional scaling and rotation center (mass center of the extruded
5748 elements by default). The User can specify any point as the Reference Point.
5749 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5750 MakeGroups: forces the generation of new groups from existing ones
5751 ScaleFactors: optional scale factors to apply during extrusion
5752 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5753 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5756 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5757 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5758 Example: :ref:`tui_extrusion_along_path`
5761 unRegister = genObjUnRegister()
5762 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5763 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5764 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5766 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5767 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5768 if isinstance( RefPoint, list ):
5769 if not RefPoint: RefPoint = [0,0,0]
5770 RefPoint = SMESH.PointStruct( *RefPoint )
5771 if isinstance( PathObject, Mesh ):
5772 PathObject = PathObject.GetMesh()
5773 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5774 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5775 Parameters = AnglesParameters + var_separator + \
5776 RefPoint.parameters + var_separator + ScalesParameters
5777 self.mesh.SetParameters(Parameters)
5778 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5779 PathObject, PathShape, NodeStart,
5780 HasAngles, Angles, LinearVariation,
5781 HasRefPoint, RefPoint, MakeGroups,
5782 ScaleFactors, ScalesVariation)
5784 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5785 HasAngles=False, Angles=[], LinearVariation=False,
5786 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5787 ElemType=SMESH.FACE):
5789 Generate new elements by extrusion of the given elements.
5790 The path of extrusion must be a meshed edge.
5793 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5794 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5795 NodeStart: the start node from Path. Defines the direction of extrusion
5796 HasAngles: not used obsolete
5797 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5798 around *basePoint*, additionally to previous steps.
5799 LinearVariation: forces the computation of rotation angles as linear
5800 variation of the given Angles along path steps
5801 HasRefPoint: allows using the reference point
5802 RefPoint: the reference point around which the elements are rotated (the mass
5803 center of the elements by default).
5804 The User can specify any point as the Reference Point.
5805 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5806 MakeGroups: forces the generation of new groups from existing ones
5807 ElemType: type of elements for extrusion (if param Base is a mesh)
5810 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5811 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5812 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5814 Example: :ref:`tui_extrusion_along_path`
5818 if ElemType == SMESH.NODE: n = Base
5819 if ElemType == SMESH.EDGE: e = Base
5820 if ElemType == SMESH.FACE: f = Base
5821 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5822 HasAngles, Angles, LinearVariation,
5823 HasRefPoint, RefPoint, MakeGroups)
5824 if MakeGroups: return gr,er
5827 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5828 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5829 MakeGroups=False, LinearVariation=False):
5831 Generate new elements by extrusion of the given elements.
5832 The path of extrusion must be a meshed edge.
5835 IDsOfElements: ids of elements
5836 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5837 PathShape: shape (edge) defines the sub-mesh for the path
5838 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5839 HasAngles: not used obsolete
5840 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5841 around *basePoint*, additionally to previous steps.
5842 HasRefPoint: allows using the reference point
5843 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5844 The User can specify any point as the Reference Point.
5845 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5846 MakeGroups: forces the generation of new groups from existing ones
5847 LinearVariation: forces the computation of rotation angles as linear
5848 variation of the given Angles along path steps
5851 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5852 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5853 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5854 Example: :ref:`tui_extrusion_along_path`
5857 if not IDsOfElements:
5858 IDsOfElements = [ self.GetMesh() ]
5859 n,e,f = [],IDsOfElements,IDsOfElements
5860 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5861 NodeStart, HasAngles, Angles,
5863 HasRefPoint, RefPoint, MakeGroups)
5864 if MakeGroups: return gr,er
5867 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5868 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5869 MakeGroups=False, LinearVariation=False):
5871 Generate new elements by extrusion of the elements which belong to the object.
5872 The path of extrusion must be a meshed edge.
5875 theObject: the object whose elements should be processed.
5876 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5877 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5878 PathShape: shape (edge) defines the sub-mesh for the path
5879 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5880 HasAngles: not used obsolete
5881 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5882 around *basePoint*, additionally to previous steps.
5883 HasRefPoint: allows using the reference point
5884 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5885 The User can specify any point as the Reference Point.
5886 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5887 MakeGroups: forces the generation of new groups from existing ones
5888 LinearVariation: forces the computation of rotation angles as linear
5889 variation of the given Angles along path steps
5892 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5893 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5894 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5895 Example: :ref:`tui_extrusion_along_path`
5898 n,e,f = [],theObject,theObject
5899 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5900 HasAngles, Angles, LinearVariation,
5901 HasRefPoint, RefPoint, MakeGroups)
5902 if MakeGroups: return gr,er
5905 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5906 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5907 MakeGroups=False, LinearVariation=False):
5909 Generate new elements by extrusion of mesh segments which belong to the object.
5910 The path of extrusion must be a meshed edge.
5913 theObject: the object whose 1D elements should be processed.
5914 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5915 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5916 PathShape: shape (edge) defines the sub-mesh for the path
5917 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5918 HasAngles: not used obsolete
5919 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5920 around *basePoint*, additionally to previous steps.
5921 HasRefPoint: allows using the reference point
5922 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5923 The User can specify any point as the Reference Point.
5924 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5925 MakeGroups: forces the generation of new groups from existing ones
5926 LinearVariation: forces the computation of rotation angles as linear
5927 variation of the given Angles along path steps
5930 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5931 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5932 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5933 Example: :ref:`tui_extrusion_along_path`
5936 n,e,f = [],theObject,[]
5937 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5938 HasAngles, Angles, LinearVariation,
5939 HasRefPoint, RefPoint, MakeGroups)
5940 if MakeGroups: return gr,er
5943 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5944 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5945 MakeGroups=False, LinearVariation=False):
5947 Generate new elements by extrusion of faces which belong to the object.
5948 The path of extrusion must be a meshed edge.
5951 theObject: the object whose 2D elements should be processed.
5952 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5953 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5954 PathShape: shape (edge) defines the sub-mesh for the path
5955 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5956 HasAngles: not used obsolete
5957 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5958 around *basePoint*, additionally to previous steps.
5959 HasRefPoint: allows using the reference point
5960 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5961 The User can specify any point as the Reference Point.
5962 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5963 MakeGroups: forces the generation of new groups from existing ones
5964 LinearVariation: forces the computation of rotation angles as linear
5965 variation of the given Angles along path steps
5968 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5969 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5970 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5971 Example: :ref:`tui_extrusion_along_path`
5974 n,e,f = [],[],theObject
5975 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5976 HasAngles, Angles, LinearVariation,
5977 HasRefPoint, RefPoint, MakeGroups)
5978 if MakeGroups: return gr,er
5981 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5983 Create a symmetrical copy of mesh elements
5986 IDsOfElements: list of elements ids
5987 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5988 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5989 If the *Mirror* is a geom object this parameter is unnecessary
5990 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5991 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5994 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5997 if IDsOfElements == []:
5998 IDsOfElements = self.GetElementsId()
5999 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6000 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6001 theMirrorType = Mirror._mirrorType
6003 self.mesh.SetParameters(Mirror.parameters)
6004 if Copy and MakeGroups:
6005 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6006 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6009 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6011 Create a new mesh by a symmetrical copy of mesh elements
6014 IDsOfElements: the list of elements ids
6015 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6016 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6017 If the *Mirror* is a geom object this parameter is unnecessary
6018 MakeGroups: to generate new groups from existing ones
6019 NewMeshName: a name of the new mesh to create
6022 instance of class :class:`Mesh`
6025 if IDsOfElements == []:
6026 IDsOfElements = self.GetElementsId()
6027 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6028 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6029 theMirrorType = Mirror._mirrorType
6031 self.mesh.SetParameters(Mirror.parameters)
6032 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6033 MakeGroups, NewMeshName)
6034 return Mesh(self.smeshpyD,self.geompyD,mesh)
6036 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6038 Create a symmetrical copy of the object
6041 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6042 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6043 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6044 If the *Mirror* is a geom object this parameter is unnecessary
6045 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6046 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6049 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6052 if ( isinstance( theObject, Mesh )):
6053 theObject = theObject.GetMesh()
6054 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6055 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6056 theMirrorType = Mirror._mirrorType
6058 self.mesh.SetParameters(Mirror.parameters)
6059 if Copy and MakeGroups:
6060 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6061 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6064 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6066 Create a new mesh by a symmetrical copy of the object
6069 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6070 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6071 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6072 If the *Mirror* is a geom object this parameter is unnecessary
6073 MakeGroups: forces the generation of new groups from existing ones
6074 NewMeshName: the name of the new mesh to create
6077 instance of class :class:`Mesh`
6080 if ( isinstance( theObject, Mesh )):
6081 theObject = theObject.GetMesh()
6082 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6083 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6084 theMirrorType = Mirror._mirrorType
6086 self.mesh.SetParameters(Mirror.parameters)
6087 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6088 MakeGroups, NewMeshName)
6089 return Mesh( self.smeshpyD,self.geompyD,mesh )
6091 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6093 Translate the elements
6096 IDsOfElements: list of elements ids
6097 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6098 Copy: allows copying the translated elements
6099 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6102 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6105 if IDsOfElements == []:
6106 IDsOfElements = self.GetElementsId()
6107 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6108 Vector = self.smeshpyD.GetDirStruct(Vector)
6109 if isinstance( Vector, list ):
6110 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6111 self.mesh.SetParameters(Vector.PS.parameters)
6112 if Copy and MakeGroups:
6113 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6114 self.editor.Translate(IDsOfElements, Vector, Copy)
6117 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6119 Create a new mesh of translated elements
6122 IDsOfElements: list of elements ids
6123 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6124 MakeGroups: forces the generation of new groups from existing ones
6125 NewMeshName: the name of the newly created mesh
6128 instance of class :class:`Mesh`
6131 if IDsOfElements == []:
6132 IDsOfElements = self.GetElementsId()
6133 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6134 Vector = self.smeshpyD.GetDirStruct(Vector)
6135 if isinstance( Vector, list ):
6136 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6137 self.mesh.SetParameters(Vector.PS.parameters)
6138 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6139 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6141 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6143 Translate the object
6146 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6147 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6148 Copy: allows copying the translated elements
6149 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6152 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6155 if ( isinstance( theObject, Mesh )):
6156 theObject = theObject.GetMesh()
6157 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6158 Vector = self.smeshpyD.GetDirStruct(Vector)
6159 if isinstance( Vector, list ):
6160 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6161 self.mesh.SetParameters(Vector.PS.parameters)
6162 if Copy and MakeGroups:
6163 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6164 self.editor.TranslateObject(theObject, Vector, Copy)
6167 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6169 Create a new mesh from the translated object
6172 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6173 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6174 MakeGroups: forces the generation of new groups from existing ones
6175 NewMeshName: the name of the newly created mesh
6178 instance of class :class:`Mesh`
6181 if isinstance( theObject, Mesh ):
6182 theObject = theObject.GetMesh()
6183 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6184 Vector = self.smeshpyD.GetDirStruct(Vector)
6185 if isinstance( Vector, list ):
6186 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6187 self.mesh.SetParameters(Vector.PS.parameters)
6188 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6189 return Mesh( self.smeshpyD, self.geompyD, mesh )
6193 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6198 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6199 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6200 theScaleFact: list of 1-3 scale factors for axises
6201 Copy: allows copying the translated elements
6202 MakeGroups: forces the generation of new groups from existing
6206 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6207 empty list otherwise
6209 unRegister = genObjUnRegister()
6210 if ( isinstance( theObject, Mesh )):
6211 theObject = theObject.GetMesh()
6212 if ( isinstance( theObject, list )):
6213 theObject = self.GetIDSource(theObject, SMESH.ALL)
6214 unRegister.set( theObject )
6215 if ( isinstance( thePoint, list )):
6216 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6217 if ( isinstance( theScaleFact, float )):
6218 theScaleFact = [theScaleFact]
6219 if ( isinstance( theScaleFact, int )):
6220 theScaleFact = [ float(theScaleFact)]
6222 self.mesh.SetParameters(thePoint.parameters)
6224 if Copy and MakeGroups:
6225 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6226 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6229 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6231 Create a new mesh from the translated object
6234 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6235 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6236 theScaleFact: list of 1-3 scale factors for axises
6237 MakeGroups: forces the generation of new groups from existing ones
6238 NewMeshName: the name of the newly created mesh
6241 instance of class :class:`Mesh`
6243 unRegister = genObjUnRegister()
6244 if (isinstance(theObject, Mesh)):
6245 theObject = theObject.GetMesh()
6246 if ( isinstance( theObject, list )):
6247 theObject = self.GetIDSource(theObject,SMESH.ALL)
6248 unRegister.set( theObject )
6249 if ( isinstance( thePoint, list )):
6250 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6251 if ( isinstance( theScaleFact, float )):
6252 theScaleFact = [theScaleFact]
6253 if ( isinstance( theScaleFact, int )):
6254 theScaleFact = [ float(theScaleFact)]
6256 self.mesh.SetParameters(thePoint.parameters)
6257 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6258 MakeGroups, NewMeshName)
6259 return Mesh( self.smeshpyD, self.geompyD, mesh )
6263 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6268 IDsOfElements: list of elements ids
6269 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6270 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6271 Copy: allows copying the rotated elements
6272 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6275 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6279 if IDsOfElements == []:
6280 IDsOfElements = self.GetElementsId()
6281 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6282 Axis = self.smeshpyD.GetAxisStruct(Axis)
6283 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6284 Parameters = Axis.parameters + var_separator + Parameters
6285 self.mesh.SetParameters(Parameters)
6286 if Copy and MakeGroups:
6287 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6288 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6291 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6293 Create a new mesh of rotated elements
6296 IDsOfElements: list of element ids
6297 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6298 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6299 MakeGroups: forces the generation of new groups from existing ones
6300 NewMeshName: the name of the newly created mesh
6303 instance of class :class:`Mesh`
6306 if IDsOfElements == []:
6307 IDsOfElements = self.GetElementsId()
6308 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6309 Axis = self.smeshpyD.GetAxisStruct(Axis)
6310 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6311 Parameters = Axis.parameters + var_separator + Parameters
6312 self.mesh.SetParameters(Parameters)
6313 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6314 MakeGroups, NewMeshName)
6315 return Mesh( self.smeshpyD, self.geompyD, mesh )
6317 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6322 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6323 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6324 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6325 Copy: allows copying the rotated elements
6326 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6329 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6332 if (isinstance(theObject, Mesh)):
6333 theObject = theObject.GetMesh()
6334 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6335 Axis = self.smeshpyD.GetAxisStruct(Axis)
6336 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6337 Parameters = Axis.parameters + ":" + Parameters
6338 self.mesh.SetParameters(Parameters)
6339 if Copy and MakeGroups:
6340 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6341 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6344 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6346 Create a new mesh from the rotated object
6349 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6350 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6351 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6352 MakeGroups: forces the generation of new groups from existing ones
6353 NewMeshName: the name of the newly created mesh
6356 instance of class :class:`Mesh`
6359 if (isinstance( theObject, Mesh )):
6360 theObject = theObject.GetMesh()
6361 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6362 Axis = self.smeshpyD.GetAxisStruct(Axis)
6363 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6364 Parameters = Axis.parameters + ":" + Parameters
6365 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6366 MakeGroups, NewMeshName)
6367 self.mesh.SetParameters(Parameters)
6368 return Mesh( self.smeshpyD, self.geompyD, mesh )
6370 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6372 Create an offset mesh from the given 2D object
6375 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6376 theValue (float): signed offset size
6377 MakeGroups (boolean): forces the generation of new groups from existing ones
6378 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6379 False means to remove original elements.
6380 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6383 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6386 if isinstance( theObject, Mesh ):
6387 theObject = theObject.GetMesh()
6388 theValue,Parameters,hasVars = ParseParameters(Value)
6389 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6390 self.mesh.SetParameters(Parameters)
6392 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6395 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6397 Find groups of adjacent nodes within Tolerance.
6400 Tolerance (float): the value of tolerance
6401 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6402 corner and medium nodes in separate groups thus preventing
6403 their further merge.
6406 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6409 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6411 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6412 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6414 Find groups of adjacent nodes within Tolerance.
6417 Tolerance: the value of tolerance
6418 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6419 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6420 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6421 corner and medium nodes in separate groups thus preventing
6422 their further merge.
6425 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6428 unRegister = genObjUnRegister()
6429 if not isinstance( SubMeshOrGroup, list ):
6430 SubMeshOrGroup = [ SubMeshOrGroup ]
6431 for i,obj in enumerate( SubMeshOrGroup ):
6432 if isinstance( obj, Mesh ):
6433 SubMeshOrGroup = [ obj.GetMesh() ]
6435 if isinstance( obj, int ):
6436 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6437 unRegister.set( SubMeshOrGroup )
6440 if not isinstance( exceptNodes, list ):
6441 exceptNodes = [ exceptNodes ]
6442 if exceptNodes and isinstance( exceptNodes[0], int ):
6443 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6444 unRegister.set( exceptNodes )
6446 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6447 exceptNodes, SeparateCornerAndMediumNodes)
6449 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6454 GroupsOfNodes: a list of groups of nodes IDs for merging.
6455 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6456 in all elements and mesh groups by nodes 1 and 25 correspondingly
6457 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6458 If *NodesToKeep* does not include a node to keep for some group to merge,
6459 then the first node in the group is kept.
6460 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6464 This operation can create gaps in numeration of nodes or elements.
6465 Call :meth:`RenumberElements` to remove the gaps.
6467 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6469 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6471 Find the elements built on the same nodes.
6474 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6475 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6479 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6482 unRegister = genObjUnRegister()
6483 if MeshOrSubMeshOrGroup is None:
6484 MeshOrSubMeshOrGroup = [ self.mesh ]
6485 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6486 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6487 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6488 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6489 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6490 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6491 unRegister.set( MeshOrSubMeshOrGroup )
6492 for item in MeshOrSubMeshOrGroup:
6493 if isinstance( item, Mesh ):
6494 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6496 if not isinstance( exceptElements, list ):
6497 exceptElements = [ exceptElements ]
6498 if exceptElements and isinstance( exceptElements[0], int ):
6499 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6500 unRegister.set( exceptElements )
6502 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6504 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6506 Merge elements in each given group.
6509 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6510 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6511 replaced in all mesh groups by elements 1 and 25)
6512 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6513 If *ElementsToKeep* does not include an element to keep for some group to merge,
6514 then the first element in the group is kept.
6517 This operation can create gaps in numeration of elements.
6518 Call :meth:`RenumberElements` to remove the gaps.
6521 unRegister = genObjUnRegister()
6523 if not isinstance( ElementsToKeep, list ):
6524 ElementsToKeep = [ ElementsToKeep ]
6525 if isinstance( ElementsToKeep[0], int ):
6526 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6527 unRegister.set( ElementsToKeep )
6529 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6531 def MergeEqualElements(self):
6533 Leave one element and remove all other elements built on the same nodes.
6536 This operation can create gaps in numeration of elements.
6537 Call :meth:`RenumberElements` to remove the gaps.
6540 self.editor.MergeEqualElements()
6542 def FindFreeBorders(self, ClosedOnly=True):
6544 Returns all or only closed free borders
6547 list of SMESH.FreeBorder's
6550 return self.editor.FindFreeBorders( ClosedOnly )
6552 def FillHole(self, holeNodes, groupName=""):
6554 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6557 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6558 must describe all sequential nodes of the hole border. The first and the last
6559 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6560 groupName (string): name of a group to add new faces
6562 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6566 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6567 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6568 if not isinstance( holeNodes, SMESH.FreeBorder ):
6569 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6570 return self.editor.FillHole( holeNodes, groupName )
6572 def FindCoincidentFreeBorders (self, tolerance=0.):
6574 Return groups of FreeBorder's coincident within the given tolerance.
6577 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6578 size of elements adjacent to free borders being compared is used.
6581 SMESH.CoincidentFreeBorders structure
6584 return self.editor.FindCoincidentFreeBorders( tolerance )
6586 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6588 Sew FreeBorder's of each group
6591 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6592 where each enclosed list contains node IDs of a group of coincident free
6593 borders such that each consequent triple of IDs within a group describes
6594 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6595 last node of a border.
6596 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6597 groups of coincident free borders, each group including two borders.
6598 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6599 polygons if a node of opposite border falls on a face edge, else such
6600 faces are split into several ones.
6601 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6602 polyhedra if a node of opposite border falls on a volume edge, else such
6603 volumes, if any, remain intact and the mesh becomes non-conformal.
6606 a number of successfully sewed groups
6609 This operation can create gaps in numeration of nodes or elements.
6610 Call :meth:`RenumberElements` to remove the gaps.
6613 if freeBorders and isinstance( freeBorders, list ):
6614 # construct SMESH.CoincidentFreeBorders
6615 if isinstance( freeBorders[0], int ):
6616 freeBorders = [freeBorders]
6618 coincidentGroups = []
6619 for nodeList in freeBorders:
6620 if not nodeList or len( nodeList ) % 3:
6621 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6624 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6625 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6626 nodeList = nodeList[3:]
6628 coincidentGroups.append( group )
6630 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6632 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6634 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6635 FirstNodeID2, SecondNodeID2, LastNodeID2,
6636 CreatePolygons, CreatePolyedrs):
6641 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6644 This operation can create gaps in numeration of nodes or elements.
6645 Call :meth:`RenumberElements` to remove the gaps.
6648 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6649 FirstNodeID2, SecondNodeID2, LastNodeID2,
6650 CreatePolygons, CreatePolyedrs)
6652 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6653 FirstNodeID2, SecondNodeID2):
6655 Sew conform free borders
6658 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6661 This operation can create gaps in numeration of elements.
6662 Call :meth:`RenumberElements` to remove the gaps.
6665 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6666 FirstNodeID2, SecondNodeID2)
6668 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6669 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6674 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6677 This operation can create gaps in numeration of elements.
6678 Call :meth:`RenumberElements` to remove the gaps.
6681 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6682 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6684 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6685 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6686 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6688 Sew two sides of a mesh. The nodes belonging to Side1 are
6689 merged with the nodes of elements of Side2.
6690 The number of elements in theSide1 and in theSide2 must be
6691 equal and they should have similar nodal connectivity.
6692 The nodes to merge should belong to side borders and
6693 the first node should be linked to the second.
6696 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6699 This operation can create gaps in numeration of nodes.
6700 Call :meth:`RenumberElements` to remove the gaps.
6703 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6704 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6705 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6707 def ChangeElemNodes(self, ide, newIDs):
6709 Set new nodes for the given element. Number of nodes should be kept.
6716 False if the number of nodes does not correspond to the type of element
6719 return self.editor.ChangeElemNodes(ide, newIDs)
6721 def GetLastCreatedNodes(self):
6723 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6724 created, this method return the list of their IDs.
6725 If new nodes were not created - return empty list
6728 the list of integer values (can be empty)
6731 return self.editor.GetLastCreatedNodes()
6733 def GetLastCreatedElems(self):
6735 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6736 created this method return the list of their IDs.
6737 If new elements were not created - return empty list
6740 the list of integer values (can be empty)
6743 return self.editor.GetLastCreatedElems()
6745 def ClearLastCreated(self):
6747 Forget what nodes and elements were created by the last mesh edition operation
6750 self.editor.ClearLastCreated()
6752 def DoubleElements(self, theElements, theGroupName=""):
6754 Create duplicates of given elements, i.e. create new elements based on the
6755 same nodes as the given ones.
6758 theElements: container of elements to duplicate. It can be a
6759 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6760 or a list of element IDs. If *theElements* is
6761 a :class:`Mesh`, elements of highest dimension are duplicated
6762 theGroupName: a name of group to contain the generated elements.
6763 If a group with such a name already exists, the new elements
6764 are added to the existing group, else a new group is created.
6765 If *theGroupName* is empty, new elements are not added
6769 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6770 None if *theGroupName* == "".
6773 unRegister = genObjUnRegister()
6774 if isinstance( theElements, Mesh ):
6775 theElements = theElements.mesh
6776 elif isinstance( theElements, list ):
6777 theElements = self.GetIDSource( theElements, SMESH.ALL )
6778 unRegister.set( theElements )
6779 return self.editor.DoubleElements(theElements, theGroupName)
6781 def DoubleNodes(self, theNodes, theModifiedElems):
6783 Create a hole in a mesh by doubling the nodes of some particular elements
6786 theNodes: IDs of nodes to be doubled
6787 theModifiedElems: IDs of elements to be updated by the new (doubled)
6788 nodes. If list of element identifiers is empty then nodes are doubled but
6789 they not assigned to elements
6792 True if operation has been completed successfully, False otherwise
6795 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6797 def DoubleNode(self, theNodeId, theModifiedElems):
6799 Create a hole in a mesh by doubling the nodes of some particular elements.
6800 This method provided for convenience works as :meth:`DoubleNodes`.
6803 theNodeId: IDs of node to double
6804 theModifiedElems: IDs of elements to update
6807 True if operation has been completed successfully, False otherwise
6810 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6812 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6814 Create a hole in a mesh by doubling the nodes of some particular elements.
6815 This method provided for convenience works as :meth:`DoubleNodes`.
6818 theNodes: group of nodes to double.
6819 theModifiedElems: group of elements to update.
6820 theMakeGroup: forces the generation of a group containing new nodes.
6823 True or a created group if operation has been completed successfully,
6824 False or None otherwise
6828 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6829 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6831 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6833 Create a hole in a mesh by doubling the nodes of some particular elements.
6834 This method provided for convenience works as :meth:`DoubleNodes`.
6837 theNodes: list of groups of nodes to double.
6838 theModifiedElems: list of groups of elements to update.
6839 theMakeGroup: forces the generation of a group containing new nodes.
6842 True if operation has been completed successfully, False otherwise
6846 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6847 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6849 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6851 Create a hole in a mesh by doubling the nodes of some particular elements
6854 theElems: the list of elements (edges or faces) to replicate.
6855 The nodes for duplication could be found from these elements
6856 theNodesNot: list of nodes NOT to replicate
6857 theAffectedElems: the list of elements (cells and edges) to which the
6858 replicated nodes should be associated to
6861 True if operation has been completed successfully, False otherwise
6864 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6866 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6868 Create a hole in a mesh by doubling the nodes of some particular elements
6871 theElems: the list of elements (edges or faces) to replicate.
6872 The nodes for duplication could be found from these elements
6873 theNodesNot: list of nodes NOT to replicate
6874 theShape: shape to detect affected elements (element which geometric center
6875 located on or inside shape).
6876 The replicated nodes should be associated to affected elements.
6879 True if operation has been completed successfully, False otherwise
6882 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6884 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6885 theMakeGroup=False, theMakeNodeGroup=False):
6887 Create a hole in a mesh by doubling the nodes of some particular elements.
6888 This method provided for convenience works as :meth:`DoubleNodes`.
6891 theElems: group of of elements (edges or faces) to replicate.
6892 theNodesNot: group of nodes NOT to replicate.
6893 theAffectedElems: group of elements to which the replicated nodes
6894 should be associated to.
6895 theMakeGroup: forces the generation of a group containing new elements.
6896 theMakeNodeGroup: forces the generation of a group containing new nodes.
6899 True or created groups (one or two) if operation has been completed successfully,
6900 False or None otherwise
6903 if theMakeGroup or theMakeNodeGroup:
6904 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6906 theMakeGroup, theMakeNodeGroup)
6907 if theMakeGroup and theMakeNodeGroup:
6910 return twoGroups[ int(theMakeNodeGroup) ]
6911 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6913 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6915 Create a hole in a mesh by doubling the nodes of some particular elements.
6916 This method provided for convenience works as :meth:`DoubleNodes`.
6919 theElems: group of of elements (edges or faces) to replicate
6920 theNodesNot: group of nodes not to replicate
6921 theShape: shape to detect affected elements (element which geometric center
6922 located on or inside shape).
6923 The replicated nodes should be associated to affected elements
6926 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6928 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6929 theMakeGroup=False, theMakeNodeGroup=False):
6931 Create a hole in a mesh by doubling the nodes of some particular elements.
6932 This method provided for convenience works as :meth:`DoubleNodes`.
6935 theElems: list of groups of elements (edges or faces) to replicate
6936 theNodesNot: list of groups of nodes NOT to replicate
6937 theAffectedElems: group of elements to which the replicated nodes
6938 should be associated to
6939 theMakeGroup: forces generation of a group containing new elements.
6940 theMakeNodeGroup: forces generation of a group containing new nodes
6943 True or created groups (one or two) if operation has been completed successfully,
6944 False or None otherwise
6947 if theMakeGroup or theMakeNodeGroup:
6948 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6950 theMakeGroup, theMakeNodeGroup)
6951 if theMakeGroup and theMakeNodeGroup:
6954 return twoGroups[ int(theMakeNodeGroup) ]
6955 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6957 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6959 Create a hole in a mesh by doubling the nodes of some particular elements.
6960 This method provided for convenience works as :meth:`DoubleNodes`.
6963 theElems: list of groups of elements (edges or faces) to replicate
6964 theNodesNot: list of groups of nodes NOT to replicate
6965 theShape: shape to detect affected elements (element which geometric center
6966 located on or inside shape).
6967 The replicated nodes should be associated to affected elements
6970 True if operation has been completed successfully, False otherwise
6973 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6975 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6977 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6978 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6981 theElems: list of groups of nodes or elements (edges or faces) to replicate
6982 theNodesNot: list of groups of nodes NOT to replicate
6983 theShape: shape to detect affected elements (element which geometric center
6984 located on or inside shape).
6985 The replicated nodes should be associated to affected elements
6988 groups of affected elements in order: volumes, faces, edges
6991 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6993 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6996 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6997 The list of groups must describe a partition of the mesh volumes.
6998 The nodes of the internal faces at the boundaries of the groups are doubled.
6999 In option, the internal faces are replaced by flat elements.
7000 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7003 theDomains: list of groups of volumes
7004 createJointElems: if True, create the elements
7005 onAllBoundaries: if True, the nodes and elements are also created on
7006 the boundary between *theDomains* and the rest mesh
7009 True if operation has been completed successfully, False otherwise
7012 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7014 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7016 Double nodes on some external faces and create flat elements.
7017 Flat elements are mainly used by some types of mechanic calculations.
7019 Each group of the list must be constituted of faces.
7020 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7023 theGroupsOfFaces: list of groups of faces
7026 True if operation has been completed successfully, False otherwise
7029 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7031 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7033 Identify all the elements around a geom shape, get the faces delimiting the hole
7035 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7037 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7039 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7040 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7041 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7042 If there are several paths connecting a pair of points, the shortest path is
7043 selected by the module. Position of the cutting plane is defined by the two
7044 points and an optional vector lying on the plane specified by a PolySegment.
7045 By default the vector is defined by Mesh module as following. A middle point
7046 of the two given points is computed. The middle point is projected to the mesh.
7047 The vector goes from the middle point to the projection point. In case of planar
7048 mesh, the vector is normal to the mesh.
7050 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7053 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7054 groupName: optional name of a group where created mesh segments will be added.
7057 editor = self.editor
7059 editor = self.mesh.GetMeshEditPreviewer()
7060 segmentsRes = editor.MakePolyLine( segments, groupName )
7061 for i, seg in enumerate( segmentsRes ):
7062 segments[i].vector = seg.vector
7064 return editor.GetPreviewData()
7067 def MakeSlot(self, segmentGroup, width ):
7069 Create a slot of given width around given 1D elements lying on a triangle mesh.
7070 The slot is constructed by cutting faces by cylindrical surfaces made
7071 around each segment. Segments are expected to be created by MakePolyLine().
7074 FaceEdge's located at the slot boundary
7076 return self.editor.MakeSlot( segmentGroup, width )
7078 def GetFunctor(self, funcType ):
7080 Return a cached numerical functor by its type.
7083 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7084 Note that not all items correspond to numerical functors.
7087 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7090 fn = self.functors[ funcType._v ]
7092 fn = self.smeshpyD.GetFunctor(funcType)
7093 fn.SetMesh(self.mesh)
7094 self.functors[ funcType._v ] = fn
7097 def FunctorValue(self, funcType, elemId, isElem=True):
7099 Return value of a functor for a given element
7102 funcType: an item of :class:`SMESH.FunctorType` enum.
7103 elemId: element or node ID
7104 isElem: *elemId* is ID of element or node
7107 the functor value or zero in case of invalid arguments
7110 fn = self.GetFunctor( funcType )
7111 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7112 val = fn.GetValue(elemId)
7117 def GetLength(self, elemId=None):
7119 Get length of given 1D elements or of all 1D mesh elements
7122 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.
7125 Sum of lengths of given elements
7130 length = self.smeshpyD.GetLength(self)
7131 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7132 length = self.smeshpyD.GetLength(elemId)
7135 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7137 length += self.smeshpyD.GetLength(obj)
7138 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7139 unRegister = genObjUnRegister()
7140 obj = self.GetIDSource( elemId )
7141 unRegister.set( obj )
7142 length = self.smeshpyD.GetLength( obj )
7144 length = self.FunctorValue(SMESH.FT_Length, elemId)
7147 def GetArea(self, elemId=None):
7149 Get area of given 2D elements or of all 2D mesh elements
7152 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.
7155 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7160 area = self.smeshpyD.GetArea(self)
7161 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7162 area = self.smeshpyD.GetArea(elemId)
7165 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7167 area += self.smeshpyD.GetArea(obj)
7168 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7169 unRegister = genObjUnRegister()
7170 obj = self.GetIDSource( elemId )
7171 unRegister.set( obj )
7172 area = self.smeshpyD.GetArea( obj )
7174 area = self.FunctorValue(SMESH.FT_Area, elemId)
7177 def GetVolume(self, elemId=None):
7179 Get volume of given 3D elements or of all 3D mesh elements
7182 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.
7185 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7190 volume= self.smeshpyD.GetVolume(self)
7191 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7192 volume= self.smeshpyD.GetVolume(elemId)
7195 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7197 volume+= self.smeshpyD.GetVolume(obj)
7198 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7199 unRegister = genObjUnRegister()
7200 obj = self.GetIDSource( elemId )
7201 unRegister.set( obj )
7202 volume= self.smeshpyD.GetVolume( obj )
7204 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7207 def GetAngle(self, node1, node2, node3 ):
7209 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7212 node1,node2,node3: IDs of the three nodes
7215 Angle in radians [0,PI]. -1 if failure case.
7217 p1 = self.GetNodeXYZ( node1 )
7218 p2 = self.GetNodeXYZ( node2 )
7219 p3 = self.GetNodeXYZ( node3 )
7220 if p1 and p2 and p3:
7221 return self.smeshpyD.GetAngle( p1,p2,p3 )
7225 def GetMaxElementLength(self, elemId):
7227 Get maximum element length.
7230 elemId: mesh element ID
7233 element's maximum length value
7236 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7237 ftype = SMESH.FT_MaxElementLength3D
7239 ftype = SMESH.FT_MaxElementLength2D
7240 return self.FunctorValue(ftype, elemId)
7242 def GetAspectRatio(self, elemId):
7244 Get aspect ratio of 2D or 3D element.
7247 elemId: mesh element ID
7250 element's aspect ratio value
7253 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7254 ftype = SMESH.FT_AspectRatio3D
7256 ftype = SMESH.FT_AspectRatio
7257 return self.FunctorValue(ftype, elemId)
7259 def GetWarping(self, elemId):
7261 Get warping angle of 2D element.
7264 elemId: mesh element ID
7267 element's warping angle value
7270 return self.FunctorValue(SMESH.FT_Warping, elemId)
7272 def GetMinimumAngle(self, elemId):
7274 Get minimum angle of 2D element.
7277 elemId: mesh element ID
7280 element's minimum angle value
7283 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7285 def GetTaper(self, elemId):
7287 Get taper of 2D element.
7290 elemId: mesh element ID
7293 element's taper value
7296 return self.FunctorValue(SMESH.FT_Taper, elemId)
7298 def GetSkew(self, elemId):
7300 Get skew of 2D element.
7303 elemId: mesh element ID
7306 element's skew value
7309 return self.FunctorValue(SMESH.FT_Skew, elemId)
7311 def GetMinMax(self, funType, meshPart=None):
7313 Return minimal and maximal value of a given functor.
7316 funType (SMESH.FunctorType): a functor type.
7317 Note that not all items of :class:`SMESH.FunctorType` corresponds
7318 to numerical functors.
7319 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7325 unRegister = genObjUnRegister()
7326 if isinstance( meshPart, list ):
7327 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7328 unRegister.set( meshPart )
7329 if isinstance( meshPart, Mesh ):
7330 meshPart = meshPart.mesh
7331 fun = self.GetFunctor( funType )
7334 if hasattr( meshPart, "SetMesh" ):
7335 meshPart.SetMesh( self.mesh ) # set mesh to filter
7336 hist = fun.GetLocalHistogram( 1, False, meshPart )
7338 hist = fun.GetHistogram( 1, False )
7340 return hist[0].min, hist[0].max
7343 pass # end of Mesh class
7346 class meshProxy(SMESH._objref_SMESH_Mesh):
7348 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7349 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7351 def __init__(self,*args):
7352 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7353 def __deepcopy__(self, memo=None):
7354 new = self.__class__(self)
7356 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7357 if len( args ) == 3:
7358 args += SMESH.ALL_NODES, True
7359 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7360 def ExportToMEDX(self, *args): # function removed
7361 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7362 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7363 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7364 def ExportToMED(self, *args): # function removed
7365 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7366 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7368 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7370 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7371 def ExportPartToMED(self, *args): # 'version' parameter removed
7372 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7373 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7374 def ExportMED(self, *args): # signature of method changed
7375 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7377 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7379 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7381 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7384 class submeshProxy(SMESH._objref_SMESH_subMesh):
7387 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7389 def __init__(self,*args):
7390 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7392 def __deepcopy__(self, memo=None):
7393 new = self.__class__(self)
7396 def Compute(self,refresh=False):
7398 Compute the sub-mesh and return the status of the computation
7401 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7406 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7407 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7411 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7413 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7415 if salome.sg.hasDesktop():
7416 if refresh: salome.sg.updateObjBrowser()
7421 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7424 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7426 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7427 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7430 def __init__(self,*args):
7431 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7433 def __getattr__(self, name ): # method called if an attribute not found
7434 if not self.mesh: # look for name() method in Mesh class
7435 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7436 if hasattr( self.mesh, name ):
7437 return getattr( self.mesh, name )
7438 if name == "ExtrusionAlongPathObjX":
7439 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7440 print("meshEditor: attribute '%s' NOT FOUND" % name)
7442 def __deepcopy__(self, memo=None):
7443 new = self.__class__(self)
7445 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7446 if len( args ) == 1: args += False,
7447 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7448 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7449 if len( args ) == 2: args += False,
7450 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7451 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7452 if len( args ) == 1:
7453 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7454 NodesToKeep = args[1]
7455 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7456 unRegister = genObjUnRegister()
7458 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7459 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7460 if not isinstance( NodesToKeep, list ):
7461 NodesToKeep = [ NodesToKeep ]
7462 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7464 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7466 class Pattern(SMESH._objref_SMESH_Pattern):
7468 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7469 variables in some methods
7472 def LoadFromFile(self, patternTextOrFile ):
7473 text = patternTextOrFile
7474 if os.path.exists( text ):
7475 text = open( patternTextOrFile ).read()
7477 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7479 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7480 decrFun = lambda i: i-1
7481 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7482 theMesh.SetParameters(Parameters)
7483 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7485 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7486 decrFun = lambda i: i-1
7487 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7488 theMesh.SetParameters(Parameters)
7489 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7491 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7492 if isinstance( mesh, Mesh ):
7493 mesh = mesh.GetMesh()
7494 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7496 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7498 Registering the new proxy for Pattern
7503 Private class used to bind methods creating algorithms to the class Mesh
7506 def __init__(self, method):
7508 self.defaultAlgoType = ""
7509 self.algoTypeToClass = {}
7510 self.method = method
7512 def add(self, algoClass):
7514 Store a python class of algorithm
7516 if inspect.isclass(algoClass) and \
7517 hasattr( algoClass, "algoType"):
7518 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7519 if not self.defaultAlgoType and \
7520 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7521 self.defaultAlgoType = algoClass.algoType
7522 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7524 def copy(self, mesh):
7526 Create a copy of self and assign mesh to the copy
7529 other = algoCreator( self.method )
7530 other.defaultAlgoType = self.defaultAlgoType
7531 other.algoTypeToClass = self.algoTypeToClass
7535 def __call__(self,algo="",geom=0,*args):
7537 Create an instance of algorithm
7541 if isinstance( algo, str ):
7543 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7544 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7549 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7551 elif not algoType and isinstance( geom, str ):
7556 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7558 elif isinstance( arg, str ) and not algoType:
7561 import traceback, sys
7562 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7563 sys.stderr.write( msg + '\n' )
7564 tb = traceback.extract_stack(None,2)
7565 traceback.print_list( [tb[0]] )
7567 algoType = self.defaultAlgoType
7568 if not algoType and self.algoTypeToClass:
7569 algoType = sorted( self.algoTypeToClass.keys() )[0]
7570 if algoType in self.algoTypeToClass:
7571 #print("Create algo",algoType)
7572 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7573 raise RuntimeError( "No class found for algo type %s" % algoType)
7576 class hypMethodWrapper:
7578 Private class used to substitute and store variable parameters of hypotheses.
7581 def __init__(self, hyp, method):
7583 self.method = method
7584 #print("REBIND:", method.__name__)
7587 def __call__(self,*args):
7589 call a method of hypothesis with calling SetVarParameter() before
7593 return self.method( self.hyp, *args ) # hypothesis method with no args
7595 #print("MethWrapper.__call__", self.method.__name__, args)
7597 parsed = ParseParameters(*args) # replace variables with their values
7598 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7599 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7600 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7601 # maybe there is a replaced string arg which is not variable
7602 result = self.method( self.hyp, *args )
7603 except ValueError as detail: # raised by ParseParameters()
7605 result = self.method( self.hyp, *args )
7606 except omniORB.CORBA.BAD_PARAM:
7607 raise ValueError(detail) # wrong variable name
7612 class genObjUnRegister:
7614 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7617 def __init__(self, genObj=None):
7618 self.genObjList = []
7622 def set(self, genObj):
7623 "Store one or a list of of SALOME.GenericObj'es"
7624 if isinstance( genObj, list ):
7625 self.genObjList.extend( genObj )
7627 self.genObjList.append( genObj )
7631 for genObj in self.genObjList:
7632 if genObj and hasattr( genObj, "UnRegister" ):
7635 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7637 Bind methods creating mesher plug-ins to the Mesh class
7640 # print("pluginName: ", pluginName)
7641 pluginBuilderName = pluginName + "Builder"
7643 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7644 except Exception as e:
7645 from salome_utils import verbose
7646 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7648 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7649 plugin = eval( pluginBuilderName )
7650 # print(" plugin:" , str(plugin))
7652 # add methods creating algorithms to Mesh
7653 for k in dir( plugin ):
7654 if k[0] == '_': continue
7655 algo = getattr( plugin, k )
7656 #print(" algo:", str(algo))
7657 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7658 #print(" meshMethod:" , str(algo.meshMethod))
7659 if not hasattr( Mesh, algo.meshMethod ):
7660 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7662 _mmethod = getattr( Mesh, algo.meshMethod )
7663 if hasattr( _mmethod, "add" ):