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()
1656 so = salome.ObjectToSObject( self.geom )
1657 comp = so.GetFatherComponent()
1658 if comp.ComponentDataType() == "SHAPERSTUDY":
1659 import shaperBuilder
1660 self.geompyD = shaperBuilder.New()
1663 if not self.geompyD:
1664 self.geompyD = self.geom.GetGen()
1670 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1673 a :class:`SMESH.SMESH_Mesh` object
1678 def GetEngine(self):
1680 Return a smeshBuilder instance created this mesh
1682 return self.smeshpyD
1684 def GetGeomEngine(self):
1686 Return a geomBuilder instance
1692 Get the name of the mesh
1695 the name of the mesh as a string
1698 name = GetName(self.GetMesh())
1701 def SetName(self, name):
1703 Set a name to the mesh
1706 name: a new name of the mesh
1709 self.smeshpyD.SetName(self.GetMesh(), name)
1711 def GetSubMesh(self, geom, name):
1713 Get a sub-mesh object associated to a *geom* geometrical object.
1716 geom: a geometrical object (shape)
1717 name: a name for the sub-mesh in the Object Browser
1720 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1721 which lies on the given shape
1724 A sub-mesh is implicitly created when a sub-shape is specified at
1725 creating an algorithm, for example::
1727 algo1D = mesh.Segment(geom=Edge_1)
1729 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1730 The created sub-mesh can be retrieved from the algorithm::
1732 submesh = algo1D.GetSubMesh()
1735 AssureGeomPublished( self, geom, name )
1736 submesh = self.mesh.GetSubMesh( geom, name )
1741 Return the shape associated to the mesh
1749 def SetShape(self, geom):
1751 Associate the given shape to the mesh (entails the recreation of the mesh)
1754 geom: the shape to be meshed (GEOM_Object)
1757 self.mesh = self.smeshpyD.CreateMesh(geom)
1759 def HasShapeToMesh(self):
1761 Return ``True`` if this mesh is based on geometry
1763 return self.mesh.HasShapeToMesh()
1767 Load mesh from the study after opening the study
1771 def IsReadyToCompute(self, theSubObject):
1773 Return true if the hypotheses are defined well
1776 theSubObject: a sub-shape of a mesh shape
1782 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1784 def GetAlgoState(self, theSubObject):
1786 Return errors of hypotheses definition.
1787 The list of errors is empty if everything is OK.
1790 theSubObject: a sub-shape of a mesh shape
1796 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1798 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1800 Return a geometrical object on which the given element was built.
1801 The returned geometrical object, if not nil, is either found in the
1802 study or published by this method with the given name
1805 theElementID: the id of the mesh element
1806 theGeomName: the user-defined name of the geometrical object
1809 GEOM.GEOM_Object instance
1812 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1814 def MeshDimension(self):
1816 Return the mesh dimension depending on the dimension of the underlying shape
1817 or, if the mesh is not based on any shape, basing on deimension of elements
1820 mesh dimension as an integer value [0,3]
1823 if self.mesh.HasShapeToMesh():
1824 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1825 if len( shells ) > 0 :
1827 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1829 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1834 if self.NbVolumes() > 0: return 3
1835 if self.NbFaces() > 0: return 2
1836 if self.NbEdges() > 0: return 1
1839 def Evaluate(self, geom=0):
1841 Evaluate size of prospective mesh on a shape
1844 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1845 To know predicted number of e.g. edges, inquire it this way::
1847 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1850 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1852 geom = self.mesh.GetShapeToMesh()
1855 return self.smeshpyD.Evaluate(self.mesh, geom)
1858 def Compute(self, geom=0, discardModifs=False, refresh=False):
1860 Compute the mesh and return the status of the computation
1863 geom: geomtrical shape on which mesh data should be computed
1864 discardModifs: if True and the mesh has been edited since
1865 a last total re-compute and that may prevent successful partial re-compute,
1866 then the mesh is cleaned before Compute()
1867 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1873 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1874 geom = self.mesh.GetShapeToMesh()
1877 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1879 ok = self.smeshpyD.Compute(self.mesh, geom)
1880 except SALOME.SALOME_Exception as ex:
1881 print("Mesh computation failed, exception caught:")
1882 print(" ", ex.details.text)
1885 print("Mesh computation failed, exception caught:")
1886 traceback.print_exc()
1890 # Treat compute errors
1891 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1893 for err in computeErrors:
1894 if self.mesh.HasShapeToMesh():
1895 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1897 stdErrors = ["OK", #COMPERR_OK
1898 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1899 "std::exception", #COMPERR_STD_EXCEPTION
1900 "OCC exception", #COMPERR_OCC_EXCEPTION
1901 "..", #COMPERR_SLM_EXCEPTION
1902 "Unknown exception", #COMPERR_EXCEPTION
1903 "Memory allocation problem", #COMPERR_MEMORY_PB
1904 "Algorithm failed", #COMPERR_ALGO_FAILED
1905 "Unexpected geometry", #COMPERR_BAD_SHAPE
1906 "Warning", #COMPERR_WARNING
1907 "Computation cancelled",#COMPERR_CANCELED
1908 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1910 if err.code < len(stdErrors): errText = stdErrors[err.code]
1912 errText = "code %s" % -err.code
1913 if errText: errText += ". "
1914 errText += err.comment
1915 if allReasons: allReasons += "\n"
1917 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1919 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1923 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1925 if err.isGlobalAlgo:
1933 reason = '%s %sD algorithm is missing' % (glob, dim)
1934 elif err.state == HYP_MISSING:
1935 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1936 % (glob, dim, name, dim))
1937 elif err.state == HYP_NOTCONFORM:
1938 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1939 elif err.state == HYP_BAD_PARAMETER:
1940 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1941 % ( glob, dim, name ))
1942 elif err.state == HYP_BAD_GEOMETRY:
1943 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1944 'geometry' % ( glob, dim, name ))
1945 elif err.state == HYP_HIDDEN_ALGO:
1946 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1947 'algorithm of upper dimension generating %sD mesh'
1948 % ( glob, dim, name, glob, dim ))
1950 reason = ("For unknown reason. "
1951 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1953 if allReasons: allReasons += "\n"
1954 allReasons += "- " + reason
1956 if not ok or allReasons != "":
1957 msg = '"' + GetName(self.mesh) + '"'
1958 if ok: msg += " has been computed with warnings"
1959 else: msg += " has not been computed"
1960 if allReasons != "": msg += ":"
1965 if salome.sg.hasDesktop():
1966 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1967 if refresh: salome.sg.updateObjBrowser()
1971 def GetComputeErrors(self, shape=0 ):
1973 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1977 shape = self.mesh.GetShapeToMesh()
1978 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1980 def GetSubShapeName(self, subShapeID ):
1982 Return a name of a sub-shape by its ID.
1983 Possible variants (for *subShapeID* == 3):
1985 - **"Face_12"** - published sub-shape
1986 - **FACE #3** - not published sub-shape
1987 - **sub-shape #3** - invalid sub-shape ID
1988 - **#3** - error in this function
1991 subShapeID: a unique ID of a sub-shape
1994 a string describing the sub-shape
1998 if not self.mesh.HasShapeToMesh():
2002 mainIOR = salome.orb.object_to_string( self.GetShape() )
2004 mainSO = s.FindObjectIOR(mainIOR)
2007 shapeText = '"%s"' % mainSO.GetName()
2008 subIt = s.NewChildIterator(mainSO)
2010 subSO = subIt.Value()
2012 obj = subSO.GetObject()
2013 if not obj: continue
2014 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2017 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2020 if ids == subShapeID:
2021 shapeText = '"%s"' % subSO.GetName()
2024 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2026 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2028 shapeText = 'sub-shape #%s' % (subShapeID)
2030 shapeText = "#%s" % (subShapeID)
2033 def GetFailedShapes(self, publish=False):
2035 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2036 error of an algorithm
2039 publish: if *True*, the returned groups will be published in the study
2042 a list of GEOM groups each named after a failed algorithm
2047 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2048 for err in computeErrors:
2049 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2050 if not shape: continue
2051 if err.algoName in algo2shapes:
2052 algo2shapes[ err.algoName ].append( shape )
2054 algo2shapes[ err.algoName ] = [ shape ]
2058 for algoName, shapes in list(algo2shapes.items()):
2060 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2061 otherTypeShapes = []
2063 group = self.geompyD.CreateGroup( self.geom, groupType )
2064 for shape in shapes:
2065 if shape.GetShapeType() == shapes[0].GetShapeType():
2066 sameTypeShapes.append( shape )
2068 otherTypeShapes.append( shape )
2069 self.geompyD.UnionList( group, sameTypeShapes )
2071 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2073 group.SetName( algoName )
2074 groups.append( group )
2075 shapes = otherTypeShapes
2078 for group in groups:
2079 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2082 def GetMeshOrder(self):
2084 Return sub-mesh objects list in meshing order
2087 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2090 return self.mesh.GetMeshOrder()
2092 def SetMeshOrder(self, submeshes):
2094 Set priority of sub-meshes. It works in two ways:
2096 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2097 *several dimensions*, it sets the order in which the sub-meshes are computed.
2098 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2099 when looking for meshing parameters to apply to a sub-shape. To impose the
2100 order in which sub-meshes with uni-dimensional algorithms are computed,
2101 call **submesh.Compute()** in a desired order.
2104 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2106 Warning: the method is for setting the order for all sub-meshes at once:
2107 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2110 return self.mesh.SetMeshOrder(submeshes)
2112 def Clear(self, refresh=False):
2114 Remove all nodes and elements generated on geometry. Imported elements remain.
2117 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2121 if ( salome.sg.hasDesktop() ):
2122 if refresh: salome.sg.updateObjBrowser()
2124 def ClearSubMesh(self, geomId, refresh=False):
2126 Remove all nodes and elements of indicated shape
2129 geomId: the ID of a sub-shape to remove elements on
2130 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2133 self.mesh.ClearSubMesh(geomId)
2134 if salome.sg.hasDesktop():
2135 if refresh: salome.sg.updateObjBrowser()
2137 def AutomaticTetrahedralization(self, fineness=0):
2139 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2142 fineness: [0.0,1.0] defines mesh fineness
2148 dim = self.MeshDimension()
2150 self.RemoveGlobalHypotheses()
2151 self.Segment().AutomaticLength(fineness)
2153 self.Triangle().LengthFromEdges()
2158 return self.Compute()
2160 def AutomaticHexahedralization(self, fineness=0):
2162 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2165 fineness: [0.0, 1.0] defines mesh fineness
2171 dim = self.MeshDimension()
2172 # assign the hypotheses
2173 self.RemoveGlobalHypotheses()
2174 self.Segment().AutomaticLength(fineness)
2181 return self.Compute()
2183 def AddHypothesis(self, hyp, geom=0):
2188 hyp: a hypothesis to assign
2189 geom: a subhape of mesh geometry
2192 :class:`SMESH.Hypothesis_Status`
2195 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2196 hyp, geom = geom, hyp
2197 if isinstance( hyp, Mesh_Algorithm ):
2198 hyp = hyp.GetAlgorithm()
2203 geom = self.mesh.GetShapeToMesh()
2206 if self.mesh.HasShapeToMesh():
2207 hyp_type = hyp.GetName()
2208 lib_name = hyp.GetLibName()
2209 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2210 # if checkAll and geom:
2211 # checkAll = geom.GetType() == 37
2213 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2215 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2216 status = self.mesh.AddHypothesis(geom, hyp)
2218 status = HYP_BAD_GEOMETRY, ""
2219 hyp_name = GetName( hyp )
2222 geom_name = geom.GetName()
2223 isAlgo = hyp._narrow( SMESH_Algo )
2224 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2227 def IsUsedHypothesis(self, hyp, geom):
2229 Return True if an algorithm or hypothesis is assigned to a given shape
2232 hyp: an algorithm or hypothesis to check
2233 geom: a subhape of mesh geometry
2239 if not hyp: # or not geom
2241 if isinstance( hyp, Mesh_Algorithm ):
2242 hyp = hyp.GetAlgorithm()
2244 hyps = self.GetHypothesisList(geom)
2246 if h.GetId() == hyp.GetId():
2250 def RemoveHypothesis(self, hyp, geom=0):
2252 Unassign a hypothesis
2255 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2256 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2259 :class:`SMESH.Hypothesis_Status`
2264 if isinstance( hyp, Mesh_Algorithm ):
2265 hyp = hyp.GetAlgorithm()
2271 if self.IsUsedHypothesis( hyp, shape ):
2272 return self.mesh.RemoveHypothesis( shape, hyp )
2273 hypName = GetName( hyp )
2274 geoName = GetName( shape )
2275 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2278 def GetHypothesisList(self, geom):
2280 Get the list of hypotheses added on a geometry
2283 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2286 the sequence of :class:`SMESH.SMESH_Hypothesis`
2289 return self.mesh.GetHypothesisList( geom )
2291 def RemoveGlobalHypotheses(self):
2293 Remove all global hypotheses
2296 current_hyps = self.mesh.GetHypothesisList( self.geom )
2297 for hyp in current_hyps:
2298 self.mesh.RemoveHypothesis( self.geom, hyp )
2301 def ExportMED(self, *args, **kwargs):
2303 Export the mesh in a file in MED format
2304 allowing to overwrite the file if it exists or add the exported data to its contents
2307 fileName: is the file name
2308 auto_groups (boolean): parameter for creating/not creating
2309 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2310 the typical use is auto_groups=False.
2311 version (int): define the version (xy, where version is x.y.z) of MED file format.
2312 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2313 The rules of compatibility to write a mesh in an older version than
2314 the current version depend on the current version. For instance,
2315 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2316 or 3.2.1 or 3.3.1 formats.
2317 If the version is equal to -1, the version is not changed (default).
2318 overwrite (boolean): parameter for overwriting/not overwriting the file
2319 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2320 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2322 - 1D if all mesh nodes lie on OX coordinate axis, or
2323 - 2D if all mesh nodes lie on XOY coordinate plane, or
2324 - 3D in the rest cases.
2326 If *autoDimension* is *False*, the space dimension is always 3.
2327 fields: list of GEOM fields defined on the shape to mesh.
2328 geomAssocFields: each character of this string means a need to export a
2329 corresponding field; correspondence between fields and characters
2332 - 'v' stands for "_vertices_" field;
2333 - 'e' stands for "_edges_" field;
2334 - 'f' stands for "_faces_" field;
2335 - 's' stands for "_solids_" field.
2337 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2338 close to zero within a given tolerance, the coordinate is set to zero.
2339 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2341 # process positional arguments
2342 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2344 auto_groups = args[1] if len(args) > 1 else False
2345 version = args[2] if len(args) > 2 else -1
2346 overwrite = args[3] if len(args) > 3 else True
2347 meshPart = args[4] if len(args) > 4 else None
2348 autoDimension = args[5] if len(args) > 5 else True
2349 fields = args[6] if len(args) > 6 else []
2350 geomAssocFields = args[7] if len(args) > 7 else ''
2351 z_tolerance = args[8] if len(args) > 8 else -1.
2352 # process keywords arguments
2353 auto_groups = kwargs.get("auto_groups", auto_groups)
2354 version = kwargs.get("version", version)
2355 version = kwargs.get("minor", version)
2356 overwrite = kwargs.get("overwrite", overwrite)
2357 meshPart = kwargs.get("meshPart", meshPart)
2358 autoDimension = kwargs.get("autoDimension", autoDimension)
2359 fields = kwargs.get("fields", fields)
2360 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2361 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2363 # invoke engine's function
2364 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2365 unRegister = genObjUnRegister()
2366 if isinstance( meshPart, list ):
2367 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2368 unRegister.set( meshPart )
2370 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2371 self.mesh.SetParameters(Parameters)
2373 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2374 version, overwrite, autoDimension,
2375 fields, geomAssocFields, z_tolerance)
2377 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2379 def ExportSAUV(self, f, auto_groups=0):
2381 Export the mesh in a file in SAUV format
2386 auto_groups: boolean parameter for creating/not creating
2387 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2388 the typical use is auto_groups=False.
2391 self.mesh.ExportSAUV(f, auto_groups)
2393 def ExportDAT(self, f, meshPart=None):
2395 Export the mesh in a file in DAT format
2399 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2403 unRegister = genObjUnRegister()
2404 if isinstance( meshPart, list ):
2405 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2406 unRegister.set( meshPart )
2407 self.mesh.ExportPartToDAT( meshPart, f )
2409 self.mesh.ExportDAT(f)
2411 def ExportUNV(self, f, meshPart=None):
2413 Export the mesh in a file in UNV format
2417 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2421 unRegister = genObjUnRegister()
2422 if isinstance( meshPart, list ):
2423 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2424 unRegister.set( meshPart )
2425 self.mesh.ExportPartToUNV( meshPart, f )
2427 self.mesh.ExportUNV(f)
2429 def ExportSTL(self, f, ascii=1, meshPart=None):
2431 Export the mesh in a file in STL format
2435 ascii: defines the file encoding
2436 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2440 unRegister = genObjUnRegister()
2441 if isinstance( meshPart, list ):
2442 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2443 unRegister.set( meshPart )
2444 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2446 self.mesh.ExportSTL(f, ascii)
2448 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2450 Export the mesh in a file in CGNS format
2454 overwrite: boolean parameter for overwriting/not overwriting the file
2455 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2456 groupElemsByType: if True all elements of same entity type are exported at ones,
2457 else elements are exported in order of their IDs which can cause creation
2458 of multiple cgns sections
2461 unRegister = genObjUnRegister()
2462 if isinstance( meshPart, list ):
2463 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2464 unRegister.set( meshPart )
2465 if isinstance( meshPart, Mesh ):
2466 meshPart = meshPart.mesh
2468 meshPart = self.mesh
2469 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2471 def ExportGMF(self, f, meshPart=None):
2473 Export the mesh in a file in GMF format.
2474 GMF files must have .mesh extension for the ASCII format and .meshb for
2475 the bynary format. Other extensions are not allowed.
2479 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2482 unRegister = genObjUnRegister()
2483 if isinstance( meshPart, list ):
2484 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2485 unRegister.set( meshPart )
2486 if isinstance( meshPart, Mesh ):
2487 meshPart = meshPart.mesh
2489 meshPart = self.mesh
2490 self.mesh.ExportGMF(meshPart, f, True)
2492 def ExportToMED(self, *args, **kwargs):
2494 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2495 Export the mesh in a file in MED format
2496 allowing to overwrite the file if it exists or add the exported data to its contents
2499 fileName: the file name
2500 opt (boolean): parameter for creating/not creating
2501 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2502 overwrite: boolean parameter for overwriting/not overwriting the file
2503 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2505 - 1D if all mesh nodes lie on OX coordinate axis, or
2506 - 2D if all mesh nodes lie on XOY coordinate plane, or
2507 - 3D in the rest cases.
2509 If **autoDimension** is *False*, the space dimension is always 3.
2512 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2513 # process positional arguments
2514 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2516 auto_groups = args[1] if len(args) > 1 else False
2517 overwrite = args[2] if len(args) > 2 else True
2518 autoDimension = args[3] if len(args) > 3 else True
2519 # process keywords arguments
2520 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2521 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2522 overwrite = kwargs.get("overwrite", overwrite)
2523 autoDimension = kwargs.get("autoDimension", autoDimension)
2525 # invoke engine's function
2526 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2528 def ExportToMEDX(self, *args, **kwargs):
2530 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2531 Export the mesh in a file in MED format
2534 fileName: the file name
2535 opt (boolean): parameter for creating/not creating
2536 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2537 overwrite: boolean parameter for overwriting/not overwriting the file
2538 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2540 - 1D if all mesh nodes lie on OX coordinate axis, or
2541 - 2D if all mesh nodes lie on XOY coordinate plane, or
2542 - 3D in the rest cases.
2544 If **autoDimension** is *False*, the space dimension is always 3.
2547 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2548 # process positional arguments
2549 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2551 auto_groups = args[1] if len(args) > 1 else False
2552 overwrite = args[2] if len(args) > 2 else True
2553 autoDimension = args[3] if len(args) > 3 else True
2554 # process keywords arguments
2555 auto_groups = kwargs.get("auto_groups", auto_groups)
2556 overwrite = kwargs.get("overwrite", overwrite)
2557 autoDimension = kwargs.get("autoDimension", autoDimension)
2559 # invoke engine's function
2560 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2564 def Append(self, meshes, uniteIdenticalGroups = True,
2565 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2567 Append given meshes into this mesh.
2568 All groups of input meshes will be created in this mesh.
2571 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2572 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2573 mergeNodesAndElements: if True, equal nodes and elements are merged
2574 mergeTolerance: tolerance for merging nodes
2575 allGroups: forces creation of groups corresponding to every input mesh
2577 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2578 mergeNodesAndElements, mergeTolerance, allGroups,
2579 meshToAppendTo = self.GetMesh() )
2581 # Operations with groups:
2582 # ----------------------
2583 def CreateEmptyGroup(self, elementType, name):
2585 Create an empty standalone mesh group
2588 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2589 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2590 name: the name of the mesh group
2593 :class:`SMESH.SMESH_Group`
2596 return self.mesh.CreateGroup(elementType, name)
2598 def Group(self, grp, name=""):
2600 Create a mesh group based on the geometric object *grp*
2601 and give it a *name*.
2602 If *name* is not defined the name of the geometric group is used
2605 Works like :meth:`GroupOnGeom`.
2608 grp: a geometric group, a vertex, an edge, a face or a solid
2609 name: the name of the mesh group
2612 :class:`SMESH.SMESH_GroupOnGeom`
2615 return self.GroupOnGeom(grp, name)
2617 def GroupOnGeom(self, grp, name="", typ=None):
2619 Create a mesh group based on the geometrical object *grp*
2620 and give it a *name*.
2621 if *name* is not defined the name of the geometric group is used
2624 grp: a geometrical group, a vertex, an edge, a face or a solid
2625 name: the name of the mesh group
2626 typ: the type of elements in the group; either of
2627 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2628 automatically detected by the type of the geometry
2631 :class:`SMESH.SMESH_GroupOnGeom`
2634 AssureGeomPublished( self, grp, name )
2636 name = grp.GetName()
2638 typ = self._groupTypeFromShape( grp )
2639 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2641 def _groupTypeFromShape( self, shape ):
2643 Pivate method to get a type of group on geometry
2645 tgeo = str(shape.GetShapeType())
2646 if tgeo == "VERTEX":
2648 elif tgeo == "EDGE" or tgeo == "WIRE":
2650 elif tgeo == "FACE" or tgeo == "SHELL":
2652 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2654 elif tgeo == "COMPOUND":
2655 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2657 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2658 return self._groupTypeFromShape( sub[0] )
2660 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2663 def GroupOnFilter(self, typ, name, filter):
2665 Create a mesh group with given *name* based on the *filter*.
2666 It is a special type of group dynamically updating it's contents during
2670 typ: the type of elements in the group; either of
2671 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2672 name: the name of the mesh group
2673 filter (SMESH.Filter): the filter defining group contents
2676 :class:`SMESH.SMESH_GroupOnFilter`
2679 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2681 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2683 Create a mesh group by the given ids of elements
2686 groupName: the name of the mesh group
2687 elementType: the type of elements in the group; either of
2688 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2689 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2692 :class:`SMESH.SMESH_Group`
2695 group = self.mesh.CreateGroup(elementType, groupName)
2696 if isinstance( elemIDs, Mesh ):
2697 elemIDs = elemIDs.GetMesh()
2698 if hasattr( elemIDs, "GetIDs" ):
2699 if hasattr( elemIDs, "SetMesh" ):
2700 elemIDs.SetMesh( self.GetMesh() )
2701 group.AddFrom( elemIDs )
2709 CritType=FT_Undefined,
2712 UnaryOp=FT_Undefined,
2715 Create a mesh group by the given conditions
2718 groupName: the name of the mesh group
2719 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2720 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2721 Note that the items starting from FT_LessThan are not suitable for CritType.
2722 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2723 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2724 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2725 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2726 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2729 :class:`SMESH.SMESH_GroupOnFilter`
2732 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2733 group = self.MakeGroupByCriterion(groupName, aCriterion)
2736 def MakeGroupByCriterion(self, groupName, Criterion):
2738 Create a mesh group by the given criterion
2741 groupName: the name of the mesh group
2742 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2745 :class:`SMESH.SMESH_GroupOnFilter`
2748 :meth:`smeshBuilder.GetCriterion`
2751 return self.MakeGroupByCriteria( groupName, [Criterion] )
2753 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2755 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2758 groupName: the name of the mesh group
2759 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2760 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2763 :class:`SMESH.SMESH_GroupOnFilter`
2766 :meth:`smeshBuilder.GetCriterion`
2769 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2770 group = self.MakeGroupByFilter(groupName, aFilter)
2773 def MakeGroupByFilter(self, groupName, theFilter):
2775 Create a mesh group by the given filter
2778 groupName (string): the name of the mesh group
2779 theFilter (SMESH.Filter): the filter
2782 :class:`SMESH.SMESH_GroupOnFilter`
2785 :meth:`smeshBuilder.GetFilter`
2788 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2789 #theFilter.SetMesh( self.mesh )
2790 #group.AddFrom( theFilter )
2791 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2794 def RemoveGroup(self, group):
2799 group (SMESH.SMESH_GroupBase): group to remove
2802 self.mesh.RemoveGroup(group)
2804 def RemoveGroupWithContents(self, group):
2806 Remove a group with its contents
2809 group (SMESH.SMESH_GroupBase): group to remove
2812 This operation can create gaps in numeration of nodes or elements.
2813 Call :meth:`RenumberElements` to remove the gaps.
2816 self.mesh.RemoveGroupWithContents(group)
2818 def GetGroups(self, elemType = SMESH.ALL):
2820 Get the list of groups existing in the mesh in the order of creation
2821 (starting from the oldest one)
2824 elemType (SMESH.ElementType): type of elements the groups contain;
2825 by default groups of elements of all types are returned
2828 a list of :class:`SMESH.SMESH_GroupBase`
2831 groups = self.mesh.GetGroups()
2832 if elemType == SMESH.ALL:
2836 if g.GetType() == elemType:
2837 typedGroups.append( g )
2844 Get the number of groups existing in the mesh
2847 the quantity of groups as an integer value
2850 return self.mesh.NbGroups()
2852 def GetGroupNames(self):
2854 Get the list of names of groups existing in the mesh
2860 groups = self.GetGroups()
2862 for group in groups:
2863 names.append(group.GetName())
2866 def GetGroupByName(self, name, elemType = None):
2868 Find groups by name and type
2871 name (string): name of the group of interest
2872 elemType (SMESH.ElementType): type of elements the groups contain;
2873 by default one group of any type is returned;
2874 if elemType == SMESH.ALL then all groups of any type are returned
2877 a list of :class:`SMESH.SMESH_GroupBase`
2881 for group in self.GetGroups():
2882 if group.GetName() == name:
2883 if elemType is None:
2885 if ( elemType == SMESH.ALL or
2886 group.GetType() == elemType ):
2887 groups.append( group )
2890 def UnionGroups(self, group1, group2, name):
2892 Produce a union of two groups.
2893 A new group is created. All mesh elements that are
2894 present in the initial groups are added to the new one
2897 group1 (SMESH.SMESH_GroupBase): a group
2898 group2 (SMESH.SMESH_GroupBase): another group
2901 instance of :class:`SMESH.SMESH_Group`
2904 return self.mesh.UnionGroups(group1, group2, name)
2906 def UnionListOfGroups(self, groups, name):
2908 Produce a union list of groups.
2909 New group is created. All mesh elements that are present in
2910 initial groups are added to the new one
2913 groups: list of :class:`SMESH.SMESH_GroupBase`
2916 instance of :class:`SMESH.SMESH_Group`
2918 return self.mesh.UnionListOfGroups(groups, name)
2920 def IntersectGroups(self, group1, group2, name):
2922 Prodice an intersection of two groups.
2923 A new group is created. All mesh elements that are common
2924 for the two initial groups are added to the new one.
2927 group1 (SMESH.SMESH_GroupBase): a group
2928 group2 (SMESH.SMESH_GroupBase): another group
2931 instance of :class:`SMESH.SMESH_Group`
2934 return self.mesh.IntersectGroups(group1, group2, name)
2936 def IntersectListOfGroups(self, groups, name):
2938 Produce an intersection of groups.
2939 New group is created. All mesh elements that are present in all
2940 initial groups simultaneously are added to the new one
2943 groups: a list of :class:`SMESH.SMESH_GroupBase`
2946 instance of :class:`SMESH.SMESH_Group`
2948 return self.mesh.IntersectListOfGroups(groups, name)
2950 def CutGroups(self, main_group, tool_group, name):
2952 Produce a cut of two groups.
2953 A new group is created. All mesh elements that are present in
2954 the main group but are not present in the tool group are added to the new one
2957 main_group (SMESH.SMESH_GroupBase): a group to cut from
2958 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2961 an instance of :class:`SMESH.SMESH_Group`
2964 return self.mesh.CutGroups(main_group, tool_group, name)
2966 def CutListOfGroups(self, main_groups, tool_groups, name):
2968 Produce a cut of groups.
2969 A new group is created. All mesh elements that are present in main groups
2970 but do not present in tool groups are added to the new one
2973 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2974 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2977 an instance of :class:`SMESH.SMESH_Group`
2980 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2982 def CreateDimGroup(self, groups, elemType, name,
2983 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2985 Create a standalone group of entities basing on nodes of other groups.
2988 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2989 elemType: a type of elements to include to the new group; either of
2990 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2991 name: a name of the new group.
2992 nbCommonNodes: a criterion of inclusion of an element to the new group
2993 basing on number of element nodes common with reference *groups*.
2994 Meaning of possible values are:
2996 - SMESH.ALL_NODES - include if all nodes are common,
2997 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2998 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2999 - SMEHS.MAJORITY - include if half of nodes or more are common.
3000 underlyingOnly: if *True* (default), an element is included to the
3001 new group provided that it is based on nodes of an element of *groups*;
3002 in this case the reference *groups* are supposed to be of higher dimension
3003 than *elemType*, which can be useful for example to get all faces lying on
3004 volumes of the reference *groups*.
3007 an instance of :class:`SMESH.SMESH_Group`
3010 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3012 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3014 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3016 Distribute all faces of the mesh among groups using sharp edges and optionally
3017 existing 1D elements as group boundaries.
3020 sharpAngle: edge is considered sharp if an angle between normals of
3021 adjacent faces is more than \a sharpAngle in degrees.
3022 createEdges (boolean): to create 1D elements for detected sharp edges.
3023 useExistingEdges (boolean): to use existing edges as group boundaries
3025 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3027 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3028 self.mesh.SetParameters(Parameters)
3029 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3031 def ConvertToStandalone(self, group):
3033 Convert group on geom into standalone group
3036 return self.mesh.ConvertToStandalone(group)
3038 # Get some info about mesh:
3039 # ------------------------
3041 def GetLog(self, clearAfterGet):
3043 Return the log of nodes and elements added or removed
3044 since the previous clear of the log.
3047 clearAfterGet: log is emptied after Get (safe if concurrents access)
3050 list of SMESH.log_block structures { commandType, number, coords, indexes }
3053 return self.mesh.GetLog(clearAfterGet)
3057 Clear the log of nodes and elements added or removed since the previous
3058 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3061 self.mesh.ClearLog()
3063 def SetAutoColor(self, theAutoColor):
3065 Toggle auto color mode on the object.
3066 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3069 theAutoColor (boolean): the flag which toggles auto color mode.
3072 self.mesh.SetAutoColor(theAutoColor)
3074 def GetAutoColor(self):
3076 Get flag of object auto color mode.
3082 return self.mesh.GetAutoColor()
3089 integer value, which is the internal Id of the mesh
3092 return self.mesh.GetId()
3094 def HasDuplicatedGroupNamesMED(self):
3096 Check the group names for duplications.
3097 Consider the maximum group name length stored in MED file.
3103 return self.mesh.HasDuplicatedGroupNamesMED()
3105 def GetMeshEditor(self):
3107 Obtain the mesh editor tool
3110 an instance of :class:`SMESH.SMESH_MeshEditor`
3115 def GetIDSource(self, ids, elemType = SMESH.ALL):
3117 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3118 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3122 elemType: type of elements; this parameter is used to distinguish
3123 IDs of nodes from IDs of elements; by default ids are treated as
3124 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3127 an instance of :class:`SMESH.SMESH_IDSource`
3130 call UnRegister() for the returned object as soon as it is no more useful::
3132 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3133 mesh.DoSomething( idSrc )
3137 if isinstance( ids, int ):
3139 return self.editor.MakeIDSource(ids, elemType)
3142 # Get information about mesh contents:
3143 # ------------------------------------
3145 def GetMeshInfo(self, obj = None):
3147 Get the mesh statistic.
3150 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3153 if not obj: obj = self.mesh
3154 return self.smeshpyD.GetMeshInfo(obj)
3158 Return the number of nodes in the mesh
3164 return self.mesh.NbNodes()
3166 def NbElements(self):
3168 Return the number of elements in the mesh
3174 return self.mesh.NbElements()
3176 def Nb0DElements(self):
3178 Return the number of 0d elements in the mesh
3184 return self.mesh.Nb0DElements()
3188 Return the number of ball discrete elements in the mesh
3194 return self.mesh.NbBalls()
3198 Return the number of edges in the mesh
3204 return self.mesh.NbEdges()
3206 def NbEdgesOfOrder(self, elementOrder):
3208 Return the number of edges with the given order in the mesh
3211 elementOrder: the order of elements
3212 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3218 return self.mesh.NbEdgesOfOrder(elementOrder)
3222 Return the number of faces in the mesh
3228 return self.mesh.NbFaces()
3230 def NbFacesOfOrder(self, elementOrder):
3232 Return the number of faces with the given order in the mesh
3235 elementOrder: the order of elements
3236 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3242 return self.mesh.NbFacesOfOrder(elementOrder)
3244 def NbTriangles(self):
3246 Return the number of triangles in the mesh
3252 return self.mesh.NbTriangles()
3254 def NbTrianglesOfOrder(self, elementOrder):
3256 Return the number of triangles with the given order in the mesh
3259 elementOrder: is the order of elements
3260 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3266 return self.mesh.NbTrianglesOfOrder(elementOrder)
3268 def NbBiQuadTriangles(self):
3270 Return the number of biquadratic triangles in the mesh
3276 return self.mesh.NbBiQuadTriangles()
3278 def NbQuadrangles(self):
3280 Return the number of quadrangles in the mesh
3286 return self.mesh.NbQuadrangles()
3288 def NbQuadranglesOfOrder(self, elementOrder):
3290 Return the number of quadrangles with the given order in the mesh
3293 elementOrder: the order of elements
3294 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3300 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3302 def NbBiQuadQuadrangles(self):
3304 Return the number of biquadratic quadrangles in the mesh
3310 return self.mesh.NbBiQuadQuadrangles()
3312 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3314 Return the number of polygons of given order in the mesh
3317 elementOrder: the order of elements
3318 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3324 return self.mesh.NbPolygonsOfOrder(elementOrder)
3326 def NbVolumes(self):
3328 Return the number of volumes in the mesh
3334 return self.mesh.NbVolumes()
3337 def NbVolumesOfOrder(self, elementOrder):
3339 Return the number of volumes with the given order in the mesh
3342 elementOrder: the order of elements
3343 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3349 return self.mesh.NbVolumesOfOrder(elementOrder)
3353 Return the number of tetrahedrons in the mesh
3359 return self.mesh.NbTetras()
3361 def NbTetrasOfOrder(self, elementOrder):
3363 Return the number of tetrahedrons with the given order in the mesh
3366 elementOrder: the order of elements
3367 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3373 return self.mesh.NbTetrasOfOrder(elementOrder)
3377 Return the number of hexahedrons in the mesh
3383 return self.mesh.NbHexas()
3385 def NbHexasOfOrder(self, elementOrder):
3387 Return the number of hexahedrons with the given order in the mesh
3390 elementOrder: the order of elements
3391 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3397 return self.mesh.NbHexasOfOrder(elementOrder)
3399 def NbTriQuadraticHexas(self):
3401 Return the number of triquadratic hexahedrons in the mesh
3407 return self.mesh.NbTriQuadraticHexas()
3409 def NbPyramids(self):
3411 Return the number of pyramids in the mesh
3417 return self.mesh.NbPyramids()
3419 def NbPyramidsOfOrder(self, elementOrder):
3421 Return the number of pyramids with the given order in the mesh
3424 elementOrder: the order of elements
3425 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3431 return self.mesh.NbPyramidsOfOrder(elementOrder)
3435 Return the number of prisms in the mesh
3441 return self.mesh.NbPrisms()
3443 def NbPrismsOfOrder(self, elementOrder):
3445 Return the number of prisms with the given order in the mesh
3448 elementOrder: the order of elements
3449 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3455 return self.mesh.NbPrismsOfOrder(elementOrder)
3457 def NbHexagonalPrisms(self):
3459 Return the number of hexagonal prisms in the mesh
3465 return self.mesh.NbHexagonalPrisms()
3467 def NbPolyhedrons(self):
3469 Return the number of polyhedrons in the mesh
3475 return self.mesh.NbPolyhedrons()
3477 def NbSubMesh(self):
3479 Return the number of submeshes in the mesh
3485 return self.mesh.NbSubMesh()
3487 def GetElementsId(self):
3489 Return the list of all mesh elements IDs
3492 the list of integer values
3495 :meth:`GetElementsByType`
3498 return self.mesh.GetElementsId()
3500 def GetElementsByType(self, elementType):
3502 Return the list of IDs of mesh elements with the given type
3505 elementType (SMESH.ElementType): the required type of elements
3508 list of integer values
3511 return self.mesh.GetElementsByType(elementType)
3513 def GetNodesId(self):
3515 Return the list of mesh nodes IDs
3518 the list of integer values
3521 return self.mesh.GetNodesId()
3523 # Get the information about mesh elements:
3524 # ------------------------------------
3526 def GetElementType(self, id, iselem=True):
3528 Return the type of mesh element or node
3531 the value from :class:`SMESH.ElementType` enumeration.
3532 Return SMESH.ALL if element or node with the given ID does not exist
3535 return self.mesh.GetElementType(id, iselem)
3537 def GetElementGeomType(self, id):
3539 Return the geometric type of mesh element
3542 the value from :class:`SMESH.EntityType` enumeration.
3545 return self.mesh.GetElementGeomType(id)
3547 def GetElementShape(self, id):
3549 Return the shape type of mesh element
3552 the value from :class:`SMESH.GeometryType` enumeration.
3555 return self.mesh.GetElementShape(id)
3557 def GetSubMeshElementsId(self, Shape):
3559 Return the list of sub-mesh elements IDs
3562 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3563 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3566 list of integer values
3569 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3570 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3573 return self.mesh.GetSubMeshElementsId(ShapeID)
3575 def GetSubMeshNodesId(self, Shape, all):
3577 Return the list of sub-mesh nodes IDs
3580 Shape: a geom object (sub-shape).
3581 *Shape* must be the sub-shape of a :meth:`GetShape`
3582 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3585 list of integer values
3588 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3589 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3592 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3594 def GetSubMeshElementType(self, Shape):
3596 Return type of elements on given shape
3599 Shape: a geom object (sub-shape).
3600 *Shape* must be a sub-shape of a ShapeToMesh()
3603 :class:`SMESH.ElementType`
3606 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3607 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3610 return self.mesh.GetSubMeshElementType(ShapeID)
3614 Get the mesh description
3620 return self.mesh.Dump()
3623 # Get the information about nodes and elements of a mesh by its IDs:
3624 # -----------------------------------------------------------
3626 def GetNodeXYZ(self, id):
3628 Get XYZ coordinates of a node.
3629 If there is no node for the given ID - return an empty list
3632 list of float values
3635 return self.mesh.GetNodeXYZ(id)
3637 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3639 Return list of IDs of inverse elements for the given node.
3640 If there is no node for the given ID - return an empty list
3644 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3647 list of integer values
3650 return self.mesh.GetNodeInverseElements(id,elemType)
3652 def GetNodePosition(self,NodeID):
3654 Return the position of a node on the shape
3657 :class:`SMESH.NodePosition`
3660 return self.mesh.GetNodePosition(NodeID)
3662 def GetElementPosition(self,ElemID):
3664 Return the position of an element on the shape
3667 :class:`SMESH.ElementPosition`
3670 return self.mesh.GetElementPosition(ElemID)
3672 def GetShapeID(self, id):
3674 Return the ID of the shape, on which the given node was generated.
3677 an integer value > 0 or -1 if there is no node for the given
3678 ID or the node is not assigned to any geometry
3681 return self.mesh.GetShapeID(id)
3683 def GetShapeIDForElem(self,id):
3685 Return the ID of the shape, on which the given element was generated.
3688 an integer value > 0 or -1 if there is no element for the given
3689 ID or the element is not assigned to any geometry
3692 return self.mesh.GetShapeIDForElem(id)
3694 def GetElemNbNodes(self, id):
3696 Return the number of nodes of the given element
3699 an integer value > 0 or -1 if there is no element for the given ID
3702 return self.mesh.GetElemNbNodes(id)
3704 def GetElemNode(self, id, index):
3706 Return the node ID the given (zero based) index for the given element.
3708 * If there is no element for the given ID - return -1.
3709 * If there is no node for the given index - return -2.
3712 id (int): element ID
3713 index (int): node index within the element
3716 an integer value (ID)
3719 :meth:`GetElemNodes`
3722 return self.mesh.GetElemNode(id, index)
3724 def GetElemNodes(self, id):
3726 Return the IDs of nodes of the given element
3729 a list of integer values
3732 return self.mesh.GetElemNodes(id)
3734 def IsMediumNode(self, elementID, nodeID):
3736 Return true if the given node is the medium node in the given quadratic element
3739 return self.mesh.IsMediumNode(elementID, nodeID)
3741 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3743 Return true if the given node is the medium node in one of quadratic elements
3746 nodeID: ID of the node
3747 elementType: the type of elements to check a state of the node, either of
3748 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3751 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3753 def ElemNbEdges(self, id):
3755 Return the number of edges for the given element
3758 return self.mesh.ElemNbEdges(id)
3760 def ElemNbFaces(self, id):
3762 Return the number of faces for the given element
3765 return self.mesh.ElemNbFaces(id)
3767 def GetElemFaceNodes(self,elemId, faceIndex):
3769 Return nodes of given face (counted from zero) for given volumic element.
3772 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3774 def GetFaceNormal(self, faceId, normalized=False):
3776 Return three components of normal of given mesh face
3777 (or an empty array in KO case)
3780 return self.mesh.GetFaceNormal(faceId,normalized)
3782 def FindElementByNodes(self, nodes):
3784 Return an element based on all given nodes.
3787 return self.mesh.FindElementByNodes(nodes)
3789 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3791 Return elements including all given nodes.
3794 return self.mesh.GetElementsByNodes( nodes, elemType )
3796 def IsPoly(self, id):
3798 Return true if the given element is a polygon
3801 return self.mesh.IsPoly(id)
3803 def IsQuadratic(self, id):
3805 Return true if the given element is quadratic
3808 return self.mesh.IsQuadratic(id)
3810 def GetBallDiameter(self, id):
3812 Return diameter of a ball discrete element or zero in case of an invalid *id*
3815 return self.mesh.GetBallDiameter(id)
3817 def BaryCenter(self, id):
3819 Return XYZ coordinates of the barycenter of the given element.
3820 If there is no element for the given ID - return an empty list
3823 a list of three double values
3826 :meth:`smeshBuilder.GetGravityCenter`
3829 return self.mesh.BaryCenter(id)
3831 def GetIdsFromFilter(self, filter, meshParts=[] ):
3833 Pass mesh elements through the given filter and return IDs of fitting elements
3836 filter: :class:`SMESH.Filter`
3837 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3843 :meth:`SMESH.Filter.GetIDs`
3844 :meth:`SMESH.Filter.GetElementsIdFromParts`
3847 filter.SetMesh( self.mesh )
3850 if isinstance( meshParts, Mesh ):
3851 filter.SetMesh( meshParts.GetMesh() )
3852 return theFilter.GetIDs()
3853 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3854 meshParts = [ meshParts ]
3855 return filter.GetElementsIdFromParts( meshParts )
3857 return filter.GetIDs()
3859 # Get mesh measurements information:
3860 # ------------------------------------
3862 def GetFreeBorders(self):
3864 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3865 Return a list of special structures (borders).
3868 a list of :class:`SMESH.FreeEdges.Border`
3871 aFilterMgr = self.smeshpyD.CreateFilterManager()
3872 aPredicate = aFilterMgr.CreateFreeEdges()
3873 aPredicate.SetMesh(self.mesh)
3874 aBorders = aPredicate.GetBorders()
3875 aFilterMgr.UnRegister()
3878 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3880 Get minimum distance between two nodes, elements or distance to the origin
3883 id1: first node/element id
3884 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3885 isElem1: *True* if *id1* is element id, *False* if it is node id
3886 isElem2: *True* if *id2* is element id, *False* if it is node id
3889 minimum distance value
3891 :meth:`GetMinDistance`
3894 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3895 return aMeasure.value
3897 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3899 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3902 id1: first node/element id
3903 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3904 isElem1: *True* if *id1* is element id, *False* if it is node id
3905 isElem2: *True* if *id2* is element id, *False* if it is node id
3908 :class:`SMESH.Measure` structure
3914 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3916 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3919 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3921 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3926 aMeasurements = self.smeshpyD.CreateMeasurements()
3927 aMeasure = aMeasurements.MinDistance(id1, id2)
3928 genObjUnRegister([aMeasurements,id1, id2])
3931 def BoundingBox(self, objects=None, isElem=False):
3933 Get bounding box of the specified object(s)
3936 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3937 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3938 *False* specifies that *objects* are nodes
3941 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3944 :meth:`GetBoundingBox()`
3947 result = self.GetBoundingBox(objects, isElem)
3951 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3954 def GetBoundingBox(self, objects=None, isElem=False):
3956 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3959 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3960 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3961 False means that *objects* are nodes
3964 :class:`SMESH.Measure` structure
3967 :meth:`BoundingBox()`
3971 objects = [self.mesh]
3972 elif isinstance(objects, tuple):
3973 objects = list(objects)
3974 if not isinstance(objects, list):
3976 if len(objects) > 0 and isinstance(objects[0], int):
3979 unRegister = genObjUnRegister()
3981 if isinstance(o, Mesh):
3982 srclist.append(o.mesh)
3983 elif hasattr(o, "_narrow"):
3984 src = o._narrow(SMESH.SMESH_IDSource)
3985 if src: srclist.append(src)
3987 elif isinstance(o, list):
3989 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3991 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3992 unRegister.set( srclist[-1] )
3995 aMeasurements = self.smeshpyD.CreateMeasurements()
3996 unRegister.set( aMeasurements )
3997 aMeasure = aMeasurements.BoundingBox(srclist)
4000 # Mesh edition (SMESH_MeshEditor functionality):
4001 # ---------------------------------------------
4003 def RemoveElements(self, IDsOfElements):
4005 Remove the elements from the mesh by ids
4008 IDsOfElements: is a list of ids of elements to remove
4014 This operation can create gaps in numeration of elements.
4015 Call :meth:`RenumberElements` to remove the gaps.
4018 return self.editor.RemoveElements(IDsOfElements)
4020 def RemoveNodes(self, IDsOfNodes):
4022 Remove nodes from mesh by ids
4025 IDsOfNodes: is a list of ids of nodes to remove
4031 This operation can create gaps in numeration of nodes.
4032 Call :meth:`RenumberElements` to remove the gaps.
4035 return self.editor.RemoveNodes(IDsOfNodes)
4037 def RemoveOrphanNodes(self):
4039 Remove all orphan (free) nodes from mesh
4042 number of the removed nodes
4045 This operation can create gaps in numeration of nodes.
4046 Call :meth:`RenumberElements` to remove the gaps.
4049 return self.editor.RemoveOrphanNodes()
4051 def AddNode(self, x, y, z):
4053 Add a node to the mesh by coordinates
4059 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4060 if hasVars: self.mesh.SetParameters(Parameters)
4061 return self.editor.AddNode( x, y, z)
4063 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4065 Create a 0D element on a node with given number.
4068 IDOfNode: the ID of node for creation of the element.
4069 DuplicateElements: to add one more 0D element to a node or not
4072 ID of the new 0D element
4075 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4077 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4079 Create 0D elements on all nodes of the given elements except those
4080 nodes on which a 0D element already exists.
4083 theObject: an object on whose nodes 0D elements will be created.
4084 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4085 theGroupName: optional name of a group to add 0D elements created
4086 and/or found on nodes of *theObject*.
4087 DuplicateElements: to add one more 0D element to a node or not
4090 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4091 IDs of new and/or found 0D elements. IDs of 0D elements
4092 can be retrieved from the returned object by
4093 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4096 unRegister = genObjUnRegister()
4097 if isinstance( theObject, Mesh ):
4098 theObject = theObject.GetMesh()
4099 elif isinstance( theObject, list ):
4100 theObject = self.GetIDSource( theObject, SMESH.ALL )
4101 unRegister.set( theObject )
4102 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4104 def AddBall(self, IDOfNode, diameter):
4106 Create a ball element on a node with given ID.
4109 IDOfNode: the ID of node for creation of the element.
4110 diameter: the bal diameter.
4113 ID of the new ball element
4116 return self.editor.AddBall( IDOfNode, diameter )
4118 def AddEdge(self, IDsOfNodes):
4120 Create a linear or quadratic edge (this is determined
4121 by the number of given nodes).
4124 IDsOfNodes: list of node IDs for creation of the element.
4125 The order of nodes in this list should correspond to
4126 the :ref:`connectivity convention <connectivity_page>`.
4132 return self.editor.AddEdge(IDsOfNodes)
4134 def AddFace(self, IDsOfNodes):
4136 Create a linear or quadratic face (this is determined
4137 by the number of given nodes).
4140 IDsOfNodes: list of node IDs for creation of the element.
4141 The order of nodes in this list should correspond to
4142 the :ref:`connectivity convention <connectivity_page>`.
4148 return self.editor.AddFace(IDsOfNodes)
4150 def AddPolygonalFace(self, IdsOfNodes):
4152 Add a polygonal face defined by a list of node IDs
4155 IdsOfNodes: the list of node IDs for creation of the element.
4161 return self.editor.AddPolygonalFace(IdsOfNodes)
4163 def AddQuadPolygonalFace(self, IdsOfNodes):
4165 Add a quadratic polygonal face defined by a list of node IDs
4168 IdsOfNodes: the list of node IDs for creation of the element;
4169 corner nodes follow first.
4175 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4177 def AddVolume(self, IDsOfNodes):
4179 Create both simple and quadratic volume (this is determined
4180 by the number of given nodes).
4183 IDsOfNodes: list of node IDs for creation of the element.
4184 The order of nodes in this list should correspond to
4185 the :ref:`connectivity convention <connectivity_page>`.
4188 ID of the new volumic element
4191 return self.editor.AddVolume(IDsOfNodes)
4193 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4195 Create a volume of many faces, giving nodes for each face.
4198 IdsOfNodes: list of node IDs for volume creation, face by face.
4199 Quantities: list of integer values, Quantities[i]
4200 gives the quantity of nodes in face number i.
4203 ID of the new volumic element
4206 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4208 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4210 Create a volume of many faces, giving the IDs of the existing faces.
4213 The created volume will refer only to the nodes
4214 of the given faces, not to the faces themselves.
4217 IdsOfFaces: the list of face IDs for volume creation.
4220 ID of the new volumic element
4223 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4226 def SetNodeOnVertex(self, NodeID, Vertex):
4228 Bind a node to a vertex
4232 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4235 True if succeed else raises an exception
4238 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4239 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4243 self.editor.SetNodeOnVertex(NodeID, VertexID)
4244 except SALOME.SALOME_Exception as inst:
4245 raise ValueError(inst.details.text)
4249 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4251 Store the node position on an edge
4255 Edge: an edge (GEOM.GEOM_Object) or edge ID
4256 paramOnEdge: a parameter on the edge where the node is located
4259 True if succeed else raises an exception
4262 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4263 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4267 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4268 except SALOME.SALOME_Exception as inst:
4269 raise ValueError(inst.details.text)
4272 def SetNodeOnFace(self, NodeID, Face, u, v):
4274 Store node position on a face
4278 Face: a face (GEOM.GEOM_Object) or face ID
4279 u: U parameter on the face where the node is located
4280 v: V parameter on the face where the node is located
4283 True if succeed else raises an exception
4286 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4287 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4291 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4292 except SALOME.SALOME_Exception as inst:
4293 raise ValueError(inst.details.text)
4296 def SetNodeInVolume(self, NodeID, Solid):
4298 Bind a node to a solid
4302 Solid: a solid (GEOM.GEOM_Object) or solid ID
4305 True if succeed else raises an exception
4308 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4309 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4313 self.editor.SetNodeInVolume(NodeID, SolidID)
4314 except SALOME.SALOME_Exception as inst:
4315 raise ValueError(inst.details.text)
4318 def SetMeshElementOnShape(self, ElementID, Shape):
4320 Bind an element to a shape
4323 ElementID: an element ID
4324 Shape: a shape (GEOM.GEOM_Object) or shape ID
4327 True if succeed else raises an exception
4330 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4331 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4335 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4336 except SALOME.SALOME_Exception as inst:
4337 raise ValueError(inst.details.text)
4341 def MoveNode(self, NodeID, x, y, z):
4343 Move the node with the given id
4346 NodeID: the id of the node
4347 x: a new X coordinate
4348 y: a new Y coordinate
4349 z: a new Z coordinate
4352 True if succeed else False
4355 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4356 if hasVars: self.mesh.SetParameters(Parameters)
4357 return self.editor.MoveNode(NodeID, x, y, z)
4359 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4361 Find the node closest to a point and moves it to a point location
4364 x: the X coordinate of a point
4365 y: the Y coordinate of a point
4366 z: the Z coordinate of a point
4367 NodeID: if specified (>0), the node with this ID is moved,
4368 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4371 the ID of a moved node
4374 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4375 if hasVars: self.mesh.SetParameters(Parameters)
4376 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4378 def FindNodeClosestTo(self, x, y, z):
4380 Find the node closest to a point
4383 x: the X coordinate of a point
4384 y: the Y coordinate of a point
4385 z: the Z coordinate of a point
4391 return self.editor.FindNodeClosestTo(x, y, z)
4393 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4395 Find the elements where a point lays IN or ON
4398 x,y,z (float): coordinates of the point
4399 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4400 means elements of any type excluding nodes, discrete and 0D elements.
4401 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4404 list of IDs of found elements
4407 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4409 return self.editor.FindElementsByPoint(x, y, z, elementType)
4411 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4413 Project a point to a mesh object.
4414 Return ID of an element of given type where the given point is projected
4415 and coordinates of the projection point.
4416 In the case if nothing found, return -1 and []
4418 if isinstance( meshObject, Mesh ):
4419 meshObject = meshObject.GetMesh()
4421 meshObject = self.GetMesh()
4422 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4424 def GetPointState(self, x, y, z):
4426 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4427 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4428 UNKNOWN state means that either mesh is wrong or the analysis fails.
4431 return self.editor.GetPointState(x, y, z)
4433 def IsManifold(self):
4435 Check if a 2D mesh is manifold
4438 return self.editor.IsManifold()
4440 def IsCoherentOrientation2D(self):
4442 Check if orientation of 2D elements is coherent
4445 return self.editor.IsCoherentOrientation2D()
4447 def Get1DBranches( self, edges, startNode = 0 ):
4449 Partition given 1D elements into groups of contiguous edges.
4450 A node where number of meeting edges != 2 is a group end.
4451 An optional startNode is used to orient groups it belongs to.
4454 A list of edge groups and a list of corresponding node groups,
4455 where the group is a list of IDs of edges or nodes, like follows
4456 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4457 If a group is closed, the first and last nodes of the group are same.
4459 if isinstance( edges, Mesh ):
4460 edges = edges.GetMesh()
4461 unRegister = genObjUnRegister()
4462 if isinstance( edges, list ):
4463 edges = self.GetIDSource( edges, SMESH.EDGE )
4464 unRegister.set( edges )
4465 return self.editor.Get1DBranches( edges, startNode )
4467 def FindSharpEdges( self, angle, addExisting=False ):
4469 Return sharp edges of faces and non-manifold ones.
4470 Optionally add existing edges.
4473 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4474 addExisting: to return existing edges (1D elements) as well
4477 list of FaceEdge structures
4479 angle = ParseParameters( angle )[0]
4480 return self.editor.FindSharpEdges( angle, addExisting )
4482 def MeshToPassThroughAPoint(self, x, y, z):
4484 Find the node closest to a point and moves it to a point location
4487 x: the X coordinate of a point
4488 y: the Y coordinate of a point
4489 z: the Z coordinate of a point
4492 the ID of a moved node
4495 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4497 def InverseDiag(self, NodeID1, NodeID2):
4499 Replace two neighbour triangles sharing Node1-Node2 link
4500 with the triangles built on the same 4 nodes but having other common link.
4503 NodeID1: the ID of the first node
4504 NodeID2: the ID of the second node
4507 False if proper faces were not found
4509 return self.editor.InverseDiag(NodeID1, NodeID2)
4511 def DeleteDiag(self, NodeID1, NodeID2):
4513 Replace two neighbour triangles sharing *Node1-Node2* link
4514 with a quadrangle built on the same 4 nodes.
4517 NodeID1: ID of the first node
4518 NodeID2: ID of the second node
4521 False if proper faces were not found
4524 This operation can create gaps in numeration of elements.
4525 Call :meth:`RenumberElements` to remove the gaps.
4528 return self.editor.DeleteDiag(NodeID1, NodeID2)
4530 def Reorient(self, IDsOfElements=None):
4532 Reorient elements by ids
4535 IDsOfElements: if undefined reorients all mesh elements
4538 True if succeed else False
4541 if IDsOfElements == None:
4542 IDsOfElements = self.GetElementsId()
4543 return self.editor.Reorient(IDsOfElements)
4545 def ReorientObject(self, theObject):
4547 Reorient all elements of the object
4550 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4553 True if succeed else False
4556 if ( isinstance( theObject, Mesh )):
4557 theObject = theObject.GetMesh()
4558 return self.editor.ReorientObject(theObject)
4560 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4562 Reorient faces contained in *the2DObject*.
4565 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4566 theDirection: a desired direction of normal of *theFace*.
4567 It can be either a GEOM vector or a list of coordinates [x,y,z].
4568 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4569 compared with theDirection. It can be either ID of face or a point
4570 by which the face will be found. The point can be given as either
4571 a GEOM vertex or a list of point coordinates.
4574 number of reoriented faces
4577 unRegister = genObjUnRegister()
4579 if isinstance( the2DObject, Mesh ):
4580 the2DObject = the2DObject.GetMesh()
4581 if isinstance( the2DObject, list ):
4582 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4583 unRegister.set( the2DObject )
4584 # check theDirection
4585 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4586 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4587 if isinstance( theDirection, list ):
4588 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4589 # prepare theFace and thePoint
4590 theFace = theFaceOrPoint
4591 thePoint = PointStruct(0,0,0)
4592 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4593 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4595 if isinstance( theFaceOrPoint, list ):
4596 thePoint = PointStruct( *theFaceOrPoint )
4598 if isinstance( theFaceOrPoint, PointStruct ):
4599 thePoint = theFaceOrPoint
4601 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4603 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4605 Reorient faces according to adjacent volumes.
4608 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4609 either IDs of faces or face groups.
4610 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4611 theOutsideNormal: to orient faces to have their normals
4612 pointing either *outside* or *inside* the adjacent volumes.
4615 number of reoriented faces.
4618 unRegister = genObjUnRegister()
4620 if not isinstance( the2DObject, list ):
4621 the2DObject = [ the2DObject ]
4622 elif the2DObject and isinstance( the2DObject[0], int ):
4623 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4624 unRegister.set( the2DObject )
4625 the2DObject = [ the2DObject ]
4626 for i,obj2D in enumerate( the2DObject ):
4627 if isinstance( obj2D, Mesh ):
4628 the2DObject[i] = obj2D.GetMesh()
4629 if isinstance( obj2D, list ):
4630 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4631 unRegister.set( the2DObject[i] )
4633 if isinstance( the3DObject, Mesh ):
4634 the3DObject = the3DObject.GetMesh()
4635 if isinstance( the3DObject, list ):
4636 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4637 unRegister.set( the3DObject )
4638 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4640 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4642 Fuse the neighbouring triangles into quadrangles.
4645 IDsOfElements: The triangles to be fused.
4646 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4647 applied to possible quadrangles to choose a neighbour to fuse with.
4648 Note that not all items of :class:`SMESH.FunctorType` corresponds
4649 to numerical functors.
4650 MaxAngle: is the maximum angle between element normals at which the fusion
4651 is still performed; theMaxAngle is measured in radians.
4652 Also it could be a name of variable which defines angle in degrees.
4655 True in case of success, False otherwise.
4658 This operation can create gaps in numeration of elements.
4659 Call :meth:`RenumberElements` to remove the gaps.
4662 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4663 self.mesh.SetParameters(Parameters)
4664 if not IDsOfElements:
4665 IDsOfElements = self.GetElementsId()
4666 Functor = self.smeshpyD.GetFunctor(theCriterion)
4667 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4669 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4671 Fuse the neighbouring triangles of the object into quadrangles
4674 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4675 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4676 applied to possible quadrangles to choose a neighbour to fuse with.
4677 Note that not all items of :class:`SMESH.FunctorType` corresponds
4678 to numerical functors.
4679 MaxAngle: a max angle between element normals at which the fusion
4680 is still performed; theMaxAngle is measured in radians.
4683 True in case of success, False otherwise.
4686 This operation can create gaps in numeration of elements.
4687 Call :meth:`RenumberElements` to remove the gaps.
4690 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4691 self.mesh.SetParameters(Parameters)
4692 if isinstance( theObject, Mesh ):
4693 theObject = theObject.GetMesh()
4694 Functor = self.smeshpyD.GetFunctor(theCriterion)
4695 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4697 def QuadToTri (self, IDsOfElements, theCriterion = None):
4699 Split quadrangles into triangles.
4702 IDsOfElements: the faces to be splitted.
4703 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4704 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4705 value, then quadrangles will be split by the smallest diagonal.
4706 Note that not all items of :class:`SMESH.FunctorType` corresponds
4707 to numerical functors.
4710 True in case of success, False otherwise.
4713 This operation can create gaps in numeration of elements.
4714 Call :meth:`RenumberElements` to remove the gaps.
4716 if IDsOfElements == []:
4717 IDsOfElements = self.GetElementsId()
4718 if theCriterion is None:
4719 theCriterion = FT_MaxElementLength2D
4720 Functor = self.smeshpyD.GetFunctor(theCriterion)
4721 return self.editor.QuadToTri(IDsOfElements, Functor)
4723 def QuadToTriObject (self, theObject, theCriterion = None):
4725 Split quadrangles into triangles.
4728 theObject: the object from which the list of elements is taken,
4729 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4730 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4731 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4732 value, then quadrangles will be split by the smallest diagonal.
4733 Note that not all items of :class:`SMESH.FunctorType` corresponds
4734 to numerical functors.
4737 True in case of success, False otherwise.
4740 This operation can create gaps in numeration of elements.
4741 Call :meth:`RenumberElements` to remove the gaps.
4743 if ( isinstance( theObject, Mesh )):
4744 theObject = theObject.GetMesh()
4745 if theCriterion is None:
4746 theCriterion = FT_MaxElementLength2D
4747 Functor = self.smeshpyD.GetFunctor(theCriterion)
4748 return self.editor.QuadToTriObject(theObject, Functor)
4750 def QuadTo4Tri (self, theElements=[]):
4752 Split each of given quadrangles into 4 triangles. A node is added at the center of
4756 theElements: the faces to be splitted. This can be either
4757 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4758 or a list of face IDs. By default all quadrangles are split
4761 This operation can create gaps in numeration of elements.
4762 Call :meth:`RenumberElements` to remove the gaps.
4764 unRegister = genObjUnRegister()
4765 if isinstance( theElements, Mesh ):
4766 theElements = theElements.mesh
4767 elif not theElements:
4768 theElements = self.mesh
4769 elif isinstance( theElements, list ):
4770 theElements = self.GetIDSource( theElements, SMESH.FACE )
4771 unRegister.set( theElements )
4772 return self.editor.QuadTo4Tri( theElements )
4774 def SplitQuad (self, IDsOfElements, Diag13):
4776 Split quadrangles into triangles.
4779 IDsOfElements: the faces to be splitted
4780 Diag13 (boolean): is used to choose a diagonal for splitting.
4783 True in case of success, False otherwise.
4786 This operation can create gaps in numeration of elements.
4787 Call :meth:`RenumberElements` to remove the gaps.
4789 if IDsOfElements == []:
4790 IDsOfElements = self.GetElementsId()
4791 return self.editor.SplitQuad(IDsOfElements, Diag13)
4793 def SplitQuadObject (self, theObject, Diag13):
4795 Split quadrangles into triangles.
4798 theObject: the object from which the list of elements is taken,
4799 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4800 Diag13 (boolean): is used to choose a diagonal for splitting.
4803 True in case of success, False otherwise.
4806 This operation can create gaps in numeration of elements.
4807 Call :meth:`RenumberElements` to remove the gaps.
4809 if ( isinstance( theObject, Mesh )):
4810 theObject = theObject.GetMesh()
4811 return self.editor.SplitQuadObject(theObject, Diag13)
4813 def BestSplit (self, IDOfQuad, theCriterion):
4815 Find a better splitting of the given quadrangle.
4818 IDOfQuad: the ID of the quadrangle to be splitted.
4819 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4820 choose a diagonal for splitting.
4821 Note that not all items of :class:`SMESH.FunctorType` corresponds
4822 to numerical functors.
4825 * 1 if 1-3 diagonal is better,
4826 * 2 if 2-4 diagonal is better,
4827 * 0 if error occurs.
4830 This operation can create gaps in numeration of elements.
4831 Call :meth:`RenumberElements` to remove the gaps.
4833 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4835 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4837 Split volumic elements into tetrahedrons
4840 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4841 method: flags passing splitting method:
4842 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4843 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4846 This operation can create gaps in numeration of elements.
4847 Call :meth:`RenumberElements` to remove the gaps.
4849 unRegister = genObjUnRegister()
4850 if isinstance( elems, Mesh ):
4851 elems = elems.GetMesh()
4852 if ( isinstance( elems, list )):
4853 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4854 unRegister.set( elems )
4855 self.editor.SplitVolumesIntoTetra(elems, method)
4858 def SplitBiQuadraticIntoLinear(self, elems=None):
4860 Split bi-quadratic elements into linear ones without creation of additional nodes:
4862 - bi-quadratic triangle will be split into 3 linear quadrangles;
4863 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4864 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4866 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4867 will be split in order to keep the mesh conformal.
4870 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4871 if None (default), all bi-quadratic elements will be split
4874 This operation can create gaps in numeration of elements.
4875 Call :meth:`RenumberElements` to remove the gaps.
4877 unRegister = genObjUnRegister()
4878 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4879 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4880 unRegister.set( elems )
4882 elems = [ self.GetMesh() ]
4883 if isinstance( elems, Mesh ):
4884 elems = [ elems.GetMesh() ]
4885 if not isinstance( elems, list ):
4887 self.editor.SplitBiQuadraticIntoLinear( elems )
4889 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4890 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4892 Split hexahedra into prisms
4895 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4896 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4897 gives a normal vector defining facets to split into triangles.
4898 *startHexPoint* can be either a triple of coordinates or a vertex.
4899 facetNormal: a normal to a facet to split into triangles of a
4900 hexahedron found by *startHexPoint*.
4901 *facetNormal* can be either a triple of coordinates or an edge.
4902 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4903 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4904 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4905 to *startHexPoint* are split, else *startHexPoint*
4906 is used to find the facet to split in all domains present in *elems*.
4909 This operation can create gaps in numeration of elements.
4910 Call :meth:`RenumberElements` to remove the gaps.
4913 unRegister = genObjUnRegister()
4914 if isinstance( elems, Mesh ):
4915 elems = elems.GetMesh()
4916 if ( isinstance( elems, list )):
4917 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4918 unRegister.set( elems )
4921 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4922 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4923 elif isinstance( startHexPoint, list ):
4924 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4927 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4928 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4929 elif isinstance( facetNormal, list ):
4930 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4933 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4935 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4937 def SplitQuadsNearTriangularFacets(self):
4939 Split quadrangle faces near triangular facets of volumes
4942 This operation can create gaps in numeration of elements.
4943 Call :meth:`RenumberElements` to remove the gaps.
4945 faces_array = self.GetElementsByType(SMESH.FACE)
4946 for face_id in faces_array:
4947 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4948 quad_nodes = self.mesh.GetElemNodes(face_id)
4949 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4950 isVolumeFound = False
4951 for node1_elem in node1_elems:
4952 if not isVolumeFound:
4953 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4954 nb_nodes = self.GetElemNbNodes(node1_elem)
4955 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4956 volume_elem = node1_elem
4957 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4958 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4959 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4960 isVolumeFound = True
4961 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4962 self.SplitQuad([face_id], False) # diagonal 2-4
4963 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4964 isVolumeFound = True
4965 self.SplitQuad([face_id], True) # diagonal 1-3
4966 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4967 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4968 isVolumeFound = True
4969 self.SplitQuad([face_id], True) # diagonal 1-3
4971 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4973 Split hexahedrons into tetrahedrons.
4975 This operation uses :doc:`pattern_mapping` functionality for splitting.
4978 theObject: the object from which the list of hexahedrons is taken;
4979 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4980 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4981 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4982 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4983 key-point will be mapped into *theNode001*-th node of each volume.
4984 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4987 True in case of success, False otherwise.
4990 This operation can create gaps in numeration of elements.
4991 Call :meth:`RenumberElements` to remove the gaps.
4999 # (0,0,1) 4.---------.7 * |
5006 # (0,0,0) 0.---------.3
5007 pattern_tetra = "!!! Nb of points: \n 8 \n\
5017 !!! Indices of points of 6 tetras: \n\
5025 pattern = self.smeshpyD.GetPattern()
5026 isDone = pattern.LoadFromFile(pattern_tetra)
5028 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5031 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5032 isDone = pattern.MakeMesh(self.mesh, False, False)
5033 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5035 # split quafrangle faces near triangular facets of volumes
5036 self.SplitQuadsNearTriangularFacets()
5040 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5042 Split hexahedrons into prisms.
5044 Uses the :doc:`pattern_mapping` functionality for splitting.
5047 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5048 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5049 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5050 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5051 will be mapped into the *theNode001* -th node of each volume.
5052 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5055 True in case of success, False otherwise.
5058 This operation can create gaps in numeration of elements.
5059 Call :meth:`RenumberElements` to remove the gaps.
5061 # Pattern: 5.---------.6
5066 # (0,0,1) 4.---------.7 |
5073 # (0,0,0) 0.---------.3
5074 pattern_prism = "!!! Nb of points: \n 8 \n\
5084 !!! Indices of points of 2 prisms: \n\
5088 pattern = self.smeshpyD.GetPattern()
5089 isDone = pattern.LoadFromFile(pattern_prism)
5091 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5094 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5095 isDone = pattern.MakeMesh(self.mesh, False, False)
5096 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5098 # Split quafrangle faces near triangular facets of volumes
5099 self.SplitQuadsNearTriangularFacets()
5103 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5104 MaxNbOfIterations, MaxAspectRatio, Method):
5109 IDsOfElements: the list if ids of elements to smooth
5110 IDsOfFixedNodes: the list of ids of fixed nodes.
5111 Note that nodes built on edges and boundary nodes are always fixed.
5112 MaxNbOfIterations: the maximum number of iterations
5113 MaxAspectRatio: varies in range [1.0, inf]
5114 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5115 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5118 True in case of success, False otherwise.
5121 if IDsOfElements == []:
5122 IDsOfElements = self.GetElementsId()
5123 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5124 self.mesh.SetParameters(Parameters)
5125 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5126 MaxNbOfIterations, MaxAspectRatio, Method)
5128 def SmoothObject(self, theObject, IDsOfFixedNodes,
5129 MaxNbOfIterations, MaxAspectRatio, Method):
5131 Smooth elements which belong to the given object
5134 theObject: the object to smooth
5135 IDsOfFixedNodes: the list of ids of fixed nodes.
5136 Note that nodes built on edges and boundary nodes are always fixed.
5137 MaxNbOfIterations: the maximum number of iterations
5138 MaxAspectRatio: varies in range [1.0, inf]
5139 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5140 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5143 True in case of success, False otherwise.
5146 if ( isinstance( theObject, Mesh )):
5147 theObject = theObject.GetMesh()
5148 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5149 MaxNbOfIterations, MaxAspectRatio, Method)
5151 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5152 MaxNbOfIterations, MaxAspectRatio, Method):
5154 Parametrically smooth the given elements
5157 IDsOfElements: the list if ids of elements to smooth
5158 IDsOfFixedNodes: the list of ids of fixed nodes.
5159 Note that nodes built on edges and boundary nodes are always fixed.
5160 MaxNbOfIterations: the maximum number of iterations
5161 MaxAspectRatio: varies in range [1.0, inf]
5162 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5163 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5166 True in case of success, False otherwise.
5169 if IDsOfElements == []:
5170 IDsOfElements = self.GetElementsId()
5171 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5172 self.mesh.SetParameters(Parameters)
5173 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5174 MaxNbOfIterations, MaxAspectRatio, Method)
5176 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5177 MaxNbOfIterations, MaxAspectRatio, Method):
5179 Parametrically smooth the elements which belong to the given object
5182 theObject: the object to smooth
5183 IDsOfFixedNodes: the list of ids of fixed nodes.
5184 Note that nodes built on edges and boundary nodes are always fixed.
5185 MaxNbOfIterations: the maximum number of iterations
5186 MaxAspectRatio: varies in range [1.0, inf]
5187 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5188 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5191 True in case of success, False otherwise.
5194 if ( isinstance( theObject, Mesh )):
5195 theObject = theObject.GetMesh()
5196 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5197 MaxNbOfIterations, MaxAspectRatio, Method)
5199 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5201 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5202 them with quadratic with the same id.
5205 theForce3d: method of new node creation:
5207 * False - the medium node lies at the geometrical entity from which the mesh element is built
5208 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5209 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5210 theToBiQuad: If True, converts the mesh to bi-quadratic
5213 :class:`SMESH.ComputeError` which can hold a warning
5216 If *theSubMesh* is provided, the mesh can become non-conformal
5219 This operation can create gaps in numeration of nodes or elements.
5220 Call :meth:`RenumberElements` to remove the gaps.
5223 if isinstance( theSubMesh, Mesh ):
5224 theSubMesh = theSubMesh.mesh
5226 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5229 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5231 self.editor.ConvertToQuadratic(theForce3d)
5232 error = self.editor.GetLastError()
5233 if error and error.comment:
5234 print(error.comment)
5237 def ConvertFromQuadratic(self, theSubMesh=None):
5239 Convert the mesh from quadratic to ordinary,
5240 deletes old quadratic elements,
5241 replacing them with ordinary mesh elements with the same id.
5244 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5247 If *theSubMesh* is provided, the mesh can become non-conformal
5250 This operation can create gaps in numeration of nodes or elements.
5251 Call :meth:`RenumberElements` to remove the gaps.
5255 self.editor.ConvertFromQuadraticObject(theSubMesh)
5257 return self.editor.ConvertFromQuadratic()
5259 def Make2DMeshFrom3D(self):
5261 Create 2D mesh as skin on boundary faces of a 3D mesh
5264 True if operation has been completed successfully, False otherwise
5267 return self.editor.Make2DMeshFrom3D()
5269 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5270 toCopyElements=False, toCopyExistingBondary=False):
5272 Create missing boundary elements
5275 elements: elements whose boundary is to be checked:
5276 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5277 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5278 dimension: defines type of boundary elements to create, either of
5279 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5280 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5281 groupName: a name of group to store created boundary elements in,
5282 "" means not to create the group
5283 meshName: a name of new mesh to store created boundary elements in,
5284 "" means not to create the new mesh
5285 toCopyElements: if True, the checked elements will be copied into
5286 the new mesh else only boundary elements will be copied into the new mesh
5287 toCopyExistingBondary: if True, not only new but also pre-existing
5288 boundary elements will be copied into the new mesh
5291 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5294 unRegister = genObjUnRegister()
5295 if isinstance( elements, Mesh ):
5296 elements = elements.GetMesh()
5297 if ( isinstance( elements, list )):
5298 elemType = SMESH.ALL
5299 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5300 elements = self.editor.MakeIDSource(elements, elemType)
5301 unRegister.set( elements )
5302 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5303 toCopyElements,toCopyExistingBondary)
5304 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5307 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5308 toCopyAll=False, groups=[]):
5310 Create missing boundary elements around either the whole mesh or
5314 dimension: defines type of boundary elements to create, either of
5315 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5316 groupName: a name of group to store all boundary elements in,
5317 "" means not to create the group
5318 meshName: a name of a new mesh, which is a copy of the initial
5319 mesh + created boundary elements; "" means not to create the new mesh
5320 toCopyAll: if True, the whole initial mesh will be copied into
5321 the new mesh else only boundary elements will be copied into the new mesh
5322 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5325 tuple( long, mesh, group )
5326 - long - number of added boundary elements
5327 - mesh - the :class:`Mesh` where elements were added to
5328 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5331 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5333 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5334 return nb, mesh, group
5336 def RenumberNodes(self):
5338 Renumber mesh nodes to remove unused node IDs
5340 self.editor.RenumberNodes()
5342 def RenumberElements(self):
5344 Renumber mesh elements to remove unused element IDs
5346 self.editor.RenumberElements()
5348 def _getIdSourceList(self, arg, idType, unRegister):
5350 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5352 if arg and isinstance( arg, list ):
5353 if isinstance( arg[0], int ):
5354 arg = self.GetIDSource( arg, idType )
5355 unRegister.set( arg )
5356 elif isinstance( arg[0], Mesh ):
5357 arg[0] = arg[0].GetMesh()
5358 elif isinstance( arg, Mesh ):
5360 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5364 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5365 MakeGroups=False, TotalAngle=False):
5367 Generate new elements by rotation of the given elements and nodes around the axis
5370 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5371 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5372 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5373 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5374 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5375 which defines angle in degrees
5376 NbOfSteps: the number of steps
5377 Tolerance: tolerance
5378 MakeGroups: forces the generation of new groups from existing ones
5379 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5380 of all steps, else - size of each step
5383 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5386 unRegister = genObjUnRegister()
5387 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5388 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5389 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5391 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5392 Axis = self.smeshpyD.GetAxisStruct( Axis )
5393 if isinstance( Axis, list ):
5394 Axis = SMESH.AxisStruct( *Axis )
5396 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5397 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5398 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5399 self.mesh.SetParameters(Parameters)
5400 if TotalAngle and NbOfSteps:
5401 AngleInRadians /= NbOfSteps
5402 return self.editor.RotationSweepObjects( nodes, edges, faces,
5403 Axis, AngleInRadians,
5404 NbOfSteps, Tolerance, MakeGroups)
5406 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5407 MakeGroups=False, TotalAngle=False):
5409 Generate new elements by rotation of the elements around the axis
5412 IDsOfElements: the list of ids of elements to sweep
5413 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5414 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5415 NbOfSteps: the number of steps
5416 Tolerance: tolerance
5417 MakeGroups: forces the generation of new groups from existing ones
5418 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5419 of all steps, else - size of each step
5422 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5425 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5426 AngleInRadians, NbOfSteps, Tolerance,
5427 MakeGroups, TotalAngle)
5429 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5430 MakeGroups=False, TotalAngle=False):
5432 Generate new elements by rotation of the elements of object around the axis
5433 theObject object which elements should be sweeped.
5434 It can be a mesh, a sub mesh or a group.
5437 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5438 AngleInRadians: the angle of Rotation
5439 NbOfSteps: number of steps
5440 Tolerance: tolerance
5441 MakeGroups: forces the generation of new groups from existing ones
5442 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5443 of all steps, else - size of each step
5446 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5449 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5450 AngleInRadians, NbOfSteps, Tolerance,
5451 MakeGroups, TotalAngle )
5453 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5454 MakeGroups=False, TotalAngle=False):
5456 Generate new elements by rotation of the elements of object around the axis
5457 theObject object which elements should be sweeped.
5458 It can be a mesh, a sub mesh or a group.
5461 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5462 AngleInRadians: the angle of Rotation
5463 NbOfSteps: number of steps
5464 Tolerance: tolerance
5465 MakeGroups: forces the generation of new groups from existing ones
5466 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5467 of all steps, else - size of each step
5470 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5471 empty list otherwise
5474 return self.RotationSweepObjects([],theObject,[], Axis,
5475 AngleInRadians, NbOfSteps, Tolerance,
5476 MakeGroups, TotalAngle)
5478 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5479 MakeGroups=False, TotalAngle=False):
5481 Generate new elements by rotation of the elements of object around the axis
5482 theObject object which elements should be sweeped.
5483 It can be a mesh, a sub mesh or a group.
5486 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5487 AngleInRadians: the angle of Rotation
5488 NbOfSteps: number of steps
5489 Tolerance: tolerance
5490 MakeGroups: forces the generation of new groups from existing ones
5491 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5492 of all steps, else - size of each step
5495 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5498 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5499 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5501 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5502 scaleFactors=[], linearVariation=False, basePoint=[],
5503 angles=[], anglesVariation=False):
5505 Generate new elements by extrusion of the given elements and nodes
5508 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5509 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5510 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5511 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5512 the direction and value of extrusion for one step (the total extrusion
5513 length will be NbOfSteps * ||StepVector||)
5514 NbOfSteps: the number of steps
5515 MakeGroups: forces the generation of new groups from existing ones
5516 scaleFactors: optional scale factors to apply during extrusion
5517 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5518 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5519 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5520 nodes and elements being extruded is used as the scaling center.
5523 - a list of tree components of the point or
5526 angles: list of angles in radians. Nodes at each extrusion step are rotated
5527 around *basePoint*, additionally to previous steps.
5528 anglesVariation: forces the computation of rotation angles as linear
5529 variation of the given *angles* along path steps
5531 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5533 Example: :ref:`tui_extrusion`
5535 unRegister = genObjUnRegister()
5536 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5537 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5538 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5540 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5541 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5542 if isinstance( StepVector, list ):
5543 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5545 if isinstance( basePoint, int):
5546 xyz = self.GetNodeXYZ( basePoint )
5548 raise RuntimeError("Invalid node ID: %s" % basePoint)
5550 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5551 basePoint = self.geompyD.PointCoordinates( basePoint )
5553 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5554 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5555 angles,angleParameters,hasVars = ParseAngles(angles)
5556 Parameters = StepVector.PS.parameters + var_separator + \
5557 Parameters + var_separator + \
5558 scaleParameters + var_separator + angleParameters
5559 self.mesh.SetParameters(Parameters)
5561 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5562 StepVector, NbOfSteps, MakeGroups,
5563 scaleFactors, linearVariation, basePoint,
5564 angles, anglesVariation )
5567 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5569 Generate new elements by extrusion of the elements with given ids
5572 IDsOfElements: the list of ids of elements or nodes for extrusion
5573 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5574 the direction and value of extrusion for one step (the total extrusion
5575 length will be NbOfSteps * ||StepVector||)
5576 NbOfSteps: the number of steps
5577 MakeGroups: forces the generation of new groups from existing ones
5578 IsNodes: is True if elements with given ids are nodes
5581 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5583 Example: :ref:`tui_extrusion`
5586 if IsNodes: n = IDsOfElements
5587 else : e,f, = IDsOfElements,IDsOfElements
5588 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5590 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5591 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5593 Generate new elements by extrusion along the normal to a discretized surface or wire
5596 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5597 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5598 StepSize: length of one extrusion step (the total extrusion
5599 length will be *NbOfSteps* *StepSize*).
5600 NbOfSteps: number of extrusion steps.
5601 ByAverageNormal: if True each node is translated by *StepSize*
5602 along the average of the normal vectors to the faces sharing the node;
5603 else each node is translated along the same average normal till
5604 intersection with the plane got by translation of the face sharing
5605 the node along its own normal by *StepSize*.
5606 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5607 for every node of *Elements*.
5608 MakeGroups: forces generation of new groups from existing ones.
5609 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5610 is not yet implemented. This parameter is used if *Elements* contains
5611 both faces and edges, i.e. *Elements* is a Mesh.
5614 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5615 empty list otherwise.
5616 Example: :ref:`tui_extrusion`
5619 unRegister = genObjUnRegister()
5620 if isinstance( Elements, Mesh ):
5621 Elements = [ Elements.GetMesh() ]
5622 if isinstance( Elements, list ):
5624 raise RuntimeError("Elements empty!")
5625 if isinstance( Elements[0], Mesh ):
5626 Elements = [ Elements[0].GetMesh() ]
5627 if isinstance( Elements[0], int ):
5628 Elements = self.GetIDSource( Elements, SMESH.ALL )
5629 unRegister.set( Elements )
5630 if not isinstance( Elements, list ):
5631 Elements = [ Elements ]
5632 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5633 self.mesh.SetParameters(Parameters)
5634 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5635 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5637 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5639 Generate new elements by extrusion of the elements or nodes which belong to the object
5642 theObject: the object whose elements or nodes should be processed.
5643 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5644 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5645 the direction and value of extrusion for one step (the total extrusion
5646 length will be NbOfSteps * ||StepVector||)
5647 NbOfSteps: the number of steps
5648 MakeGroups: forces the generation of new groups from existing ones
5649 IsNodes: is True if elements to extrude are nodes
5652 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5653 Example: :ref:`tui_extrusion`
5657 if IsNodes: n = theObject
5658 else : e,f, = theObject,theObject
5659 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5661 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5663 Generate new elements by extrusion of edges which belong to the object
5666 theObject: object whose 1D elements should be processed.
5667 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5668 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5669 the direction and value of extrusion for one step (the total extrusion
5670 length will be NbOfSteps * ||StepVector||)
5671 NbOfSteps: the number of steps
5672 MakeGroups: to generate new groups from existing ones
5675 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5676 Example: :ref:`tui_extrusion`
5679 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5681 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5683 Generate new elements by extrusion of faces which belong to the object
5686 theObject: object whose 2D elements should be processed.
5687 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5688 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5689 the direction and value of extrusion for one step (the total extrusion
5690 length will be NbOfSteps * ||StepVector||)
5691 NbOfSteps: the number of steps
5692 MakeGroups: forces the generation of new groups from existing ones
5695 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5696 Example: :ref:`tui_extrusion`
5699 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5701 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5702 ExtrFlags, SewTolerance, MakeGroups=False):
5704 Generate new elements by extrusion of the elements with given ids
5707 IDsOfElements: is ids of elements
5708 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5709 the direction and value of extrusion for one step (the total extrusion
5710 length will be NbOfSteps * ||StepVector||)
5711 NbOfSteps: the number of steps
5712 ExtrFlags: sets flags for extrusion
5713 SewTolerance: uses for comparing locations of nodes if flag
5714 EXTRUSION_FLAG_SEW is set
5715 MakeGroups: forces the generation of new groups from existing ones
5718 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5721 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5722 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5723 if isinstance( StepVector, list ):
5724 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5725 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5726 ExtrFlags, SewTolerance, MakeGroups)
5728 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5729 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5730 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5731 ScaleFactors=[], ScalesVariation=False):
5733 Generate new elements by extrusion of the given elements and nodes along the path.
5734 The path of extrusion must be a meshed edge.
5737 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5738 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5739 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5740 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5741 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
5742 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5743 HasAngles: not used obsolete
5744 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5745 around *basePoint*, additionally to previous steps.
5746 LinearVariation: forces the computation of rotation angles as linear
5747 variation of the given Angles along path steps
5748 HasRefPoint: allows using the reference point
5749 RefPoint: optional scaling and rotation center (mass center of the extruded
5750 elements by default). The User can specify any point as the Reference Point.
5751 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5752 MakeGroups: forces the generation of new groups from existing ones
5753 ScaleFactors: optional scale factors to apply during extrusion
5754 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5755 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5758 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5759 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5760 Example: :ref:`tui_extrusion_along_path`
5763 unRegister = genObjUnRegister()
5764 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5765 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5766 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5768 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5769 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5770 if isinstance( RefPoint, list ):
5771 if not RefPoint: RefPoint = [0,0,0]
5772 RefPoint = SMESH.PointStruct( *RefPoint )
5773 if isinstance( PathObject, Mesh ):
5774 PathObject = PathObject.GetMesh()
5775 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5776 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5777 Parameters = AnglesParameters + var_separator + \
5778 RefPoint.parameters + var_separator + ScalesParameters
5779 self.mesh.SetParameters(Parameters)
5780 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5781 PathObject, PathShape, NodeStart,
5782 HasAngles, Angles, LinearVariation,
5783 HasRefPoint, RefPoint, MakeGroups,
5784 ScaleFactors, ScalesVariation)
5786 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5787 HasAngles=False, Angles=[], LinearVariation=False,
5788 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5789 ElemType=SMESH.FACE):
5791 Generate new elements by extrusion of the given elements.
5792 The path of extrusion must be a meshed edge.
5795 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5796 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5797 NodeStart: the start node from Path. Defines the direction of extrusion
5798 HasAngles: not used obsolete
5799 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5800 around *basePoint*, additionally to previous steps.
5801 LinearVariation: forces the computation of rotation angles as linear
5802 variation of the given Angles along path steps
5803 HasRefPoint: allows using the reference point
5804 RefPoint: the reference point around which the elements are rotated (the mass
5805 center of the elements by default).
5806 The User can specify any point as the Reference Point.
5807 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5808 MakeGroups: forces the generation of new groups from existing ones
5809 ElemType: type of elements for extrusion (if param Base is a mesh)
5812 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5813 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5814 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5816 Example: :ref:`tui_extrusion_along_path`
5820 if ElemType == SMESH.NODE: n = Base
5821 if ElemType == SMESH.EDGE: e = Base
5822 if ElemType == SMESH.FACE: f = Base
5823 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5824 HasAngles, Angles, LinearVariation,
5825 HasRefPoint, RefPoint, MakeGroups)
5826 if MakeGroups: return gr,er
5829 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5830 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5831 MakeGroups=False, LinearVariation=False):
5833 Generate new elements by extrusion of the given elements.
5834 The path of extrusion must be a meshed edge.
5837 IDsOfElements: ids of elements
5838 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5839 PathShape: shape (edge) defines the sub-mesh for the path
5840 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5841 HasAngles: not used obsolete
5842 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5843 around *basePoint*, additionally to previous steps.
5844 HasRefPoint: allows using the reference point
5845 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5846 The User can specify any point as the Reference Point.
5847 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5848 MakeGroups: forces the generation of new groups from existing ones
5849 LinearVariation: forces the computation of rotation angles as linear
5850 variation of the given Angles along path steps
5853 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5854 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5855 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5856 Example: :ref:`tui_extrusion_along_path`
5859 if not IDsOfElements:
5860 IDsOfElements = [ self.GetMesh() ]
5861 n,e,f = [],IDsOfElements,IDsOfElements
5862 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5863 NodeStart, HasAngles, Angles,
5865 HasRefPoint, RefPoint, MakeGroups)
5866 if MakeGroups: return gr,er
5869 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5870 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5871 MakeGroups=False, LinearVariation=False):
5873 Generate new elements by extrusion of the elements which belong to the object.
5874 The path of extrusion must be a meshed edge.
5877 theObject: the object whose elements should be processed.
5878 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5879 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5880 PathShape: shape (edge) defines the sub-mesh for the path
5881 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5882 HasAngles: not used obsolete
5883 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5884 around *basePoint*, additionally to previous steps.
5885 HasRefPoint: allows using the reference point
5886 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5887 The User can specify any point as the Reference Point.
5888 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5889 MakeGroups: forces the generation of new groups from existing ones
5890 LinearVariation: forces the computation of rotation angles as linear
5891 variation of the given Angles along path steps
5894 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5895 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5896 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5897 Example: :ref:`tui_extrusion_along_path`
5900 n,e,f = [],theObject,theObject
5901 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5902 HasAngles, Angles, LinearVariation,
5903 HasRefPoint, RefPoint, MakeGroups)
5904 if MakeGroups: return gr,er
5907 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5908 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5909 MakeGroups=False, LinearVariation=False):
5911 Generate new elements by extrusion of mesh segments which belong to the object.
5912 The path of extrusion must be a meshed edge.
5915 theObject: the object whose 1D elements should be processed.
5916 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5917 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5918 PathShape: shape (edge) defines the sub-mesh for the path
5919 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5920 HasAngles: not used obsolete
5921 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5922 around *basePoint*, additionally to previous steps.
5923 HasRefPoint: allows using the reference point
5924 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5925 The User can specify any point as the Reference Point.
5926 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5927 MakeGroups: forces the generation of new groups from existing ones
5928 LinearVariation: forces the computation of rotation angles as linear
5929 variation of the given Angles along path steps
5932 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5933 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5934 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5935 Example: :ref:`tui_extrusion_along_path`
5938 n,e,f = [],theObject,[]
5939 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5940 HasAngles, Angles, LinearVariation,
5941 HasRefPoint, RefPoint, MakeGroups)
5942 if MakeGroups: return gr,er
5945 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5946 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5947 MakeGroups=False, LinearVariation=False):
5949 Generate new elements by extrusion of faces which belong to the object.
5950 The path of extrusion must be a meshed edge.
5953 theObject: the object whose 2D elements should be processed.
5954 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5955 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5956 PathShape: shape (edge) defines the sub-mesh for the path
5957 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5958 HasAngles: not used obsolete
5959 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5960 around *basePoint*, additionally to previous steps.
5961 HasRefPoint: allows using the reference point
5962 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5963 The User can specify any point as the Reference Point.
5964 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5965 MakeGroups: forces the generation of new groups from existing ones
5966 LinearVariation: forces the computation of rotation angles as linear
5967 variation of the given Angles along path steps
5970 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5971 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5972 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5973 Example: :ref:`tui_extrusion_along_path`
5976 n,e,f = [],[],theObject
5977 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5978 HasAngles, Angles, LinearVariation,
5979 HasRefPoint, RefPoint, MakeGroups)
5980 if MakeGroups: return gr,er
5983 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5985 Create a symmetrical copy of mesh elements
5988 IDsOfElements: list of elements ids
5989 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5990 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5991 If the *Mirror* is a geom object this parameter is unnecessary
5992 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5993 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5996 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5999 if IDsOfElements == []:
6000 IDsOfElements = self.GetElementsId()
6001 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6002 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6003 theMirrorType = Mirror._mirrorType
6005 self.mesh.SetParameters(Mirror.parameters)
6006 if Copy and MakeGroups:
6007 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6008 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6011 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6013 Create a new mesh by a symmetrical copy of mesh elements
6016 IDsOfElements: the list of elements ids
6017 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6018 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6019 If the *Mirror* is a geom object this parameter is unnecessary
6020 MakeGroups: to generate new groups from existing ones
6021 NewMeshName: a name of the new mesh to create
6024 instance of class :class:`Mesh`
6027 if IDsOfElements == []:
6028 IDsOfElements = self.GetElementsId()
6029 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6030 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6031 theMirrorType = Mirror._mirrorType
6033 self.mesh.SetParameters(Mirror.parameters)
6034 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6035 MakeGroups, NewMeshName)
6036 return Mesh(self.smeshpyD,self.geompyD,mesh)
6038 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6040 Create a symmetrical copy of the object
6043 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6044 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6045 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6046 If the *Mirror* is a geom object this parameter is unnecessary
6047 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6048 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6051 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6054 if ( isinstance( theObject, Mesh )):
6055 theObject = theObject.GetMesh()
6056 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6057 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6058 theMirrorType = Mirror._mirrorType
6060 self.mesh.SetParameters(Mirror.parameters)
6061 if Copy and MakeGroups:
6062 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6063 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6066 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6068 Create a new mesh by a symmetrical copy of the object
6071 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6072 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6073 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6074 If the *Mirror* is a geom object this parameter is unnecessary
6075 MakeGroups: forces the generation of new groups from existing ones
6076 NewMeshName: the name of the new mesh to create
6079 instance of class :class:`Mesh`
6082 if ( isinstance( theObject, Mesh )):
6083 theObject = theObject.GetMesh()
6084 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6085 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6086 theMirrorType = Mirror._mirrorType
6088 self.mesh.SetParameters(Mirror.parameters)
6089 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6090 MakeGroups, NewMeshName)
6091 return Mesh( self.smeshpyD,self.geompyD,mesh )
6093 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6095 Translate the elements
6098 IDsOfElements: list of elements ids
6099 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6100 Copy: allows copying the translated elements
6101 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6104 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6107 if IDsOfElements == []:
6108 IDsOfElements = self.GetElementsId()
6109 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6110 Vector = self.smeshpyD.GetDirStruct(Vector)
6111 if isinstance( Vector, list ):
6112 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6113 self.mesh.SetParameters(Vector.PS.parameters)
6114 if Copy and MakeGroups:
6115 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6116 self.editor.Translate(IDsOfElements, Vector, Copy)
6119 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6121 Create a new mesh of translated elements
6124 IDsOfElements: list of elements ids
6125 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6126 MakeGroups: forces the generation of new groups from existing ones
6127 NewMeshName: the name of the newly created mesh
6130 instance of class :class:`Mesh`
6133 if IDsOfElements == []:
6134 IDsOfElements = self.GetElementsId()
6135 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6136 Vector = self.smeshpyD.GetDirStruct(Vector)
6137 if isinstance( Vector, list ):
6138 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6139 self.mesh.SetParameters(Vector.PS.parameters)
6140 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6141 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6143 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6145 Translate the object
6148 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6149 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6150 Copy: allows copying the translated elements
6151 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6154 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6157 if ( isinstance( theObject, Mesh )):
6158 theObject = theObject.GetMesh()
6159 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6160 Vector = self.smeshpyD.GetDirStruct(Vector)
6161 if isinstance( Vector, list ):
6162 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6163 self.mesh.SetParameters(Vector.PS.parameters)
6164 if Copy and MakeGroups:
6165 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6166 self.editor.TranslateObject(theObject, Vector, Copy)
6169 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6171 Create a new mesh from the translated object
6174 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6175 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6176 MakeGroups: forces the generation of new groups from existing ones
6177 NewMeshName: the name of the newly created mesh
6180 instance of class :class:`Mesh`
6183 if isinstance( theObject, Mesh ):
6184 theObject = theObject.GetMesh()
6185 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6186 Vector = self.smeshpyD.GetDirStruct(Vector)
6187 if isinstance( Vector, list ):
6188 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6189 self.mesh.SetParameters(Vector.PS.parameters)
6190 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6191 return Mesh( self.smeshpyD, self.geompyD, mesh )
6195 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6200 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6201 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6202 theScaleFact: list of 1-3 scale factors for axises
6203 Copy: allows copying the translated elements
6204 MakeGroups: forces the generation of new groups from existing
6208 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6209 empty list otherwise
6211 unRegister = genObjUnRegister()
6212 if ( isinstance( theObject, Mesh )):
6213 theObject = theObject.GetMesh()
6214 if ( isinstance( theObject, list )):
6215 theObject = self.GetIDSource(theObject, SMESH.ALL)
6216 unRegister.set( theObject )
6217 if ( isinstance( thePoint, list )):
6218 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6219 if ( isinstance( theScaleFact, float )):
6220 theScaleFact = [theScaleFact]
6221 if ( isinstance( theScaleFact, int )):
6222 theScaleFact = [ float(theScaleFact)]
6224 self.mesh.SetParameters(thePoint.parameters)
6226 if Copy and MakeGroups:
6227 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6228 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6231 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6233 Create a new mesh from the translated object
6236 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6237 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6238 theScaleFact: list of 1-3 scale factors for axises
6239 MakeGroups: forces the generation of new groups from existing ones
6240 NewMeshName: the name of the newly created mesh
6243 instance of class :class:`Mesh`
6245 unRegister = genObjUnRegister()
6246 if (isinstance(theObject, Mesh)):
6247 theObject = theObject.GetMesh()
6248 if ( isinstance( theObject, list )):
6249 theObject = self.GetIDSource(theObject,SMESH.ALL)
6250 unRegister.set( theObject )
6251 if ( isinstance( thePoint, list )):
6252 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6253 if ( isinstance( theScaleFact, float )):
6254 theScaleFact = [theScaleFact]
6255 if ( isinstance( theScaleFact, int )):
6256 theScaleFact = [ float(theScaleFact)]
6258 self.mesh.SetParameters(thePoint.parameters)
6259 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6260 MakeGroups, NewMeshName)
6261 return Mesh( self.smeshpyD, self.geompyD, mesh )
6265 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6270 IDsOfElements: list of elements ids
6271 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6272 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6273 Copy: allows copying the rotated elements
6274 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6277 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6281 if IDsOfElements == []:
6282 IDsOfElements = self.GetElementsId()
6283 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6284 Axis = self.smeshpyD.GetAxisStruct(Axis)
6285 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6286 Parameters = Axis.parameters + var_separator + Parameters
6287 self.mesh.SetParameters(Parameters)
6288 if Copy and MakeGroups:
6289 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6290 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6293 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6295 Create a new mesh of rotated elements
6298 IDsOfElements: list of element ids
6299 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6300 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6301 MakeGroups: forces the generation of new groups from existing ones
6302 NewMeshName: the name of the newly created mesh
6305 instance of class :class:`Mesh`
6308 if IDsOfElements == []:
6309 IDsOfElements = self.GetElementsId()
6310 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6311 Axis = self.smeshpyD.GetAxisStruct(Axis)
6312 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6313 Parameters = Axis.parameters + var_separator + Parameters
6314 self.mesh.SetParameters(Parameters)
6315 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6316 MakeGroups, NewMeshName)
6317 return Mesh( self.smeshpyD, self.geompyD, mesh )
6319 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6324 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6325 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6326 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6327 Copy: allows copying the rotated elements
6328 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6331 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6334 if (isinstance(theObject, Mesh)):
6335 theObject = theObject.GetMesh()
6336 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6337 Axis = self.smeshpyD.GetAxisStruct(Axis)
6338 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6339 Parameters = Axis.parameters + ":" + Parameters
6340 self.mesh.SetParameters(Parameters)
6341 if Copy and MakeGroups:
6342 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6343 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6346 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6348 Create a new mesh from the rotated object
6351 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6352 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6353 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6354 MakeGroups: forces the generation of new groups from existing ones
6355 NewMeshName: the name of the newly created mesh
6358 instance of class :class:`Mesh`
6361 if (isinstance( theObject, Mesh )):
6362 theObject = theObject.GetMesh()
6363 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6364 Axis = self.smeshpyD.GetAxisStruct(Axis)
6365 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6366 Parameters = Axis.parameters + ":" + Parameters
6367 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6368 MakeGroups, NewMeshName)
6369 self.mesh.SetParameters(Parameters)
6370 return Mesh( self.smeshpyD, self.geompyD, mesh )
6372 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6374 Create an offset mesh from the given 2D object
6377 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6378 theValue (float): signed offset size
6379 MakeGroups (boolean): forces the generation of new groups from existing ones
6380 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6381 False means to remove original elements.
6382 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6385 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6388 if isinstance( theObject, Mesh ):
6389 theObject = theObject.GetMesh()
6390 theValue,Parameters,hasVars = ParseParameters(Value)
6391 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6392 self.mesh.SetParameters(Parameters)
6394 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6397 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6399 Find groups of adjacent nodes within Tolerance.
6402 Tolerance (float): the value of tolerance
6403 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6404 corner and medium nodes in separate groups thus preventing
6405 their further merge.
6408 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6411 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6413 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6414 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6416 Find groups of adjacent nodes within Tolerance.
6419 Tolerance: the value of tolerance
6420 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6421 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6422 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6423 corner and medium nodes in separate groups thus preventing
6424 their further merge.
6427 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6430 unRegister = genObjUnRegister()
6431 if not isinstance( SubMeshOrGroup, list ):
6432 SubMeshOrGroup = [ SubMeshOrGroup ]
6433 for i,obj in enumerate( SubMeshOrGroup ):
6434 if isinstance( obj, Mesh ):
6435 SubMeshOrGroup = [ obj.GetMesh() ]
6437 if isinstance( obj, int ):
6438 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6439 unRegister.set( SubMeshOrGroup )
6442 if not isinstance( exceptNodes, list ):
6443 exceptNodes = [ exceptNodes ]
6444 if exceptNodes and isinstance( exceptNodes[0], int ):
6445 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6446 unRegister.set( exceptNodes )
6448 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6449 exceptNodes, SeparateCornerAndMediumNodes)
6451 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6456 GroupsOfNodes: a list of groups of nodes IDs for merging.
6457 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6458 in all elements and mesh groups by nodes 1 and 25 correspondingly
6459 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6460 If *NodesToKeep* does not include a node to keep for some group to merge,
6461 then the first node in the group is kept.
6462 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6466 This operation can create gaps in numeration of nodes or elements.
6467 Call :meth:`RenumberElements` to remove the gaps.
6469 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6471 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6473 Find the elements built on the same nodes.
6476 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6477 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6481 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6484 unRegister = genObjUnRegister()
6485 if MeshOrSubMeshOrGroup is None:
6486 MeshOrSubMeshOrGroup = [ self.mesh ]
6487 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6488 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6489 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6490 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6491 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6492 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6493 unRegister.set( MeshOrSubMeshOrGroup )
6494 for item in MeshOrSubMeshOrGroup:
6495 if isinstance( item, Mesh ):
6496 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6498 if not isinstance( exceptElements, list ):
6499 exceptElements = [ exceptElements ]
6500 if exceptElements and isinstance( exceptElements[0], int ):
6501 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6502 unRegister.set( exceptElements )
6504 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6506 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6508 Merge elements in each given group.
6511 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6512 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6513 replaced in all mesh groups by elements 1 and 25)
6514 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6515 If *ElementsToKeep* does not include an element to keep for some group to merge,
6516 then the first element in the group is kept.
6519 This operation can create gaps in numeration of elements.
6520 Call :meth:`RenumberElements` to remove the gaps.
6523 unRegister = genObjUnRegister()
6525 if not isinstance( ElementsToKeep, list ):
6526 ElementsToKeep = [ ElementsToKeep ]
6527 if isinstance( ElementsToKeep[0], int ):
6528 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6529 unRegister.set( ElementsToKeep )
6531 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6533 def MergeEqualElements(self):
6535 Leave one element and remove all other elements built on the same nodes.
6538 This operation can create gaps in numeration of elements.
6539 Call :meth:`RenumberElements` to remove the gaps.
6542 self.editor.MergeEqualElements()
6544 def FindFreeBorders(self, ClosedOnly=True):
6546 Returns all or only closed free borders
6549 list of SMESH.FreeBorder's
6552 return self.editor.FindFreeBorders( ClosedOnly )
6554 def FillHole(self, holeNodes, groupName=""):
6556 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6559 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6560 must describe all sequential nodes of the hole border. The first and the last
6561 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6562 groupName (string): name of a group to add new faces
6564 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6568 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6569 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6570 if not isinstance( holeNodes, SMESH.FreeBorder ):
6571 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6572 return self.editor.FillHole( holeNodes, groupName )
6574 def FindCoincidentFreeBorders (self, tolerance=0.):
6576 Return groups of FreeBorder's coincident within the given tolerance.
6579 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6580 size of elements adjacent to free borders being compared is used.
6583 SMESH.CoincidentFreeBorders structure
6586 return self.editor.FindCoincidentFreeBorders( tolerance )
6588 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6590 Sew FreeBorder's of each group
6593 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6594 where each enclosed list contains node IDs of a group of coincident free
6595 borders such that each consequent triple of IDs within a group describes
6596 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6597 last node of a border.
6598 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6599 groups of coincident free borders, each group including two borders.
6600 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6601 polygons if a node of opposite border falls on a face edge, else such
6602 faces are split into several ones.
6603 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6604 polyhedra if a node of opposite border falls on a volume edge, else such
6605 volumes, if any, remain intact and the mesh becomes non-conformal.
6608 a number of successfully sewed groups
6611 This operation can create gaps in numeration of nodes or elements.
6612 Call :meth:`RenumberElements` to remove the gaps.
6615 if freeBorders and isinstance( freeBorders, list ):
6616 # construct SMESH.CoincidentFreeBorders
6617 if isinstance( freeBorders[0], int ):
6618 freeBorders = [freeBorders]
6620 coincidentGroups = []
6621 for nodeList in freeBorders:
6622 if not nodeList or len( nodeList ) % 3:
6623 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6626 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6627 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6628 nodeList = nodeList[3:]
6630 coincidentGroups.append( group )
6632 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6634 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6636 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6637 FirstNodeID2, SecondNodeID2, LastNodeID2,
6638 CreatePolygons, CreatePolyedrs):
6643 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6646 This operation can create gaps in numeration of nodes or elements.
6647 Call :meth:`RenumberElements` to remove the gaps.
6650 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6651 FirstNodeID2, SecondNodeID2, LastNodeID2,
6652 CreatePolygons, CreatePolyedrs)
6654 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6655 FirstNodeID2, SecondNodeID2):
6657 Sew conform free borders
6660 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6663 This operation can create gaps in numeration of elements.
6664 Call :meth:`RenumberElements` to remove the gaps.
6667 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6668 FirstNodeID2, SecondNodeID2)
6670 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6671 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6676 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6679 This operation can create gaps in numeration of elements.
6680 Call :meth:`RenumberElements` to remove the gaps.
6683 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6684 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6686 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6687 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6688 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6690 Sew two sides of a mesh. The nodes belonging to Side1 are
6691 merged with the nodes of elements of Side2.
6692 The number of elements in theSide1 and in theSide2 must be
6693 equal and they should have similar nodal connectivity.
6694 The nodes to merge should belong to side borders and
6695 the first node should be linked to the second.
6698 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6701 This operation can create gaps in numeration of nodes.
6702 Call :meth:`RenumberElements` to remove the gaps.
6705 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6706 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6707 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6709 def ChangeElemNodes(self, ide, newIDs):
6711 Set new nodes for the given element. Number of nodes should be kept.
6718 False if the number of nodes does not correspond to the type of element
6721 return self.editor.ChangeElemNodes(ide, newIDs)
6723 def GetLastCreatedNodes(self):
6725 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6726 created, this method return the list of their IDs.
6727 If new nodes were not created - return empty list
6730 the list of integer values (can be empty)
6733 return self.editor.GetLastCreatedNodes()
6735 def GetLastCreatedElems(self):
6737 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6738 created this method return the list of their IDs.
6739 If new elements were not created - return empty list
6742 the list of integer values (can be empty)
6745 return self.editor.GetLastCreatedElems()
6747 def ClearLastCreated(self):
6749 Forget what nodes and elements were created by the last mesh edition operation
6752 self.editor.ClearLastCreated()
6754 def DoubleElements(self, theElements, theGroupName=""):
6756 Create duplicates of given elements, i.e. create new elements based on the
6757 same nodes as the given ones.
6760 theElements: container of elements to duplicate. It can be a
6761 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6762 or a list of element IDs. If *theElements* is
6763 a :class:`Mesh`, elements of highest dimension are duplicated
6764 theGroupName: a name of group to contain the generated elements.
6765 If a group with such a name already exists, the new elements
6766 are added to the existing group, else a new group is created.
6767 If *theGroupName* is empty, new elements are not added
6771 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6772 None if *theGroupName* == "".
6775 unRegister = genObjUnRegister()
6776 if isinstance( theElements, Mesh ):
6777 theElements = theElements.mesh
6778 elif isinstance( theElements, list ):
6779 theElements = self.GetIDSource( theElements, SMESH.ALL )
6780 unRegister.set( theElements )
6781 return self.editor.DoubleElements(theElements, theGroupName)
6783 def DoubleNodes(self, theNodes, theModifiedElems):
6785 Create a hole in a mesh by doubling the nodes of some particular elements
6788 theNodes: IDs of nodes to be doubled
6789 theModifiedElems: IDs of elements to be updated by the new (doubled)
6790 nodes. If list of element identifiers is empty then nodes are doubled but
6791 they not assigned to elements
6794 True if operation has been completed successfully, False otherwise
6797 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6799 def DoubleNode(self, theNodeId, theModifiedElems):
6801 Create a hole in a mesh by doubling the nodes of some particular elements.
6802 This method provided for convenience works as :meth:`DoubleNodes`.
6805 theNodeId: IDs of node to double
6806 theModifiedElems: IDs of elements to update
6809 True if operation has been completed successfully, False otherwise
6812 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6814 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6816 Create a hole in a mesh by doubling the nodes of some particular elements.
6817 This method provided for convenience works as :meth:`DoubleNodes`.
6820 theNodes: group of nodes to double.
6821 theModifiedElems: group of elements to update.
6822 theMakeGroup: forces the generation of a group containing new nodes.
6825 True or a created group if operation has been completed successfully,
6826 False or None otherwise
6830 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6831 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6833 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6835 Create a hole in a mesh by doubling the nodes of some particular elements.
6836 This method provided for convenience works as :meth:`DoubleNodes`.
6839 theNodes: list of groups of nodes to double.
6840 theModifiedElems: list of groups of elements to update.
6841 theMakeGroup: forces the generation of a group containing new nodes.
6844 True if operation has been completed successfully, False otherwise
6848 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6849 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6851 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6853 Create a hole in a mesh by doubling the nodes of some particular elements
6856 theElems: the list of elements (edges or faces) to replicate.
6857 The nodes for duplication could be found from these elements
6858 theNodesNot: list of nodes NOT to replicate
6859 theAffectedElems: the list of elements (cells and edges) to which the
6860 replicated nodes should be associated to
6863 True if operation has been completed successfully, False otherwise
6866 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6868 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6870 Create a hole in a mesh by doubling the nodes of some particular elements
6873 theElems: the list of elements (edges or faces) to replicate.
6874 The nodes for duplication could be found from these elements
6875 theNodesNot: list of nodes NOT to replicate
6876 theShape: shape to detect affected elements (element which geometric center
6877 located on or inside shape).
6878 The replicated nodes should be associated to affected elements.
6881 True if operation has been completed successfully, False otherwise
6884 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6886 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6887 theMakeGroup=False, theMakeNodeGroup=False):
6889 Create a hole in a mesh by doubling the nodes of some particular elements.
6890 This method provided for convenience works as :meth:`DoubleNodes`.
6893 theElems: group of of elements (edges or faces) to replicate.
6894 theNodesNot: group of nodes NOT to replicate.
6895 theAffectedElems: group of elements to which the replicated nodes
6896 should be associated to.
6897 theMakeGroup: forces the generation of a group containing new elements.
6898 theMakeNodeGroup: forces the generation of a group containing new nodes.
6901 True or created groups (one or two) if operation has been completed successfully,
6902 False or None otherwise
6905 if theMakeGroup or theMakeNodeGroup:
6906 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6908 theMakeGroup, theMakeNodeGroup)
6909 if theMakeGroup and theMakeNodeGroup:
6912 return twoGroups[ int(theMakeNodeGroup) ]
6913 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6915 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6917 Create a hole in a mesh by doubling the nodes of some particular elements.
6918 This method provided for convenience works as :meth:`DoubleNodes`.
6921 theElems: group of of elements (edges or faces) to replicate
6922 theNodesNot: group of nodes not to replicate
6923 theShape: shape to detect affected elements (element which geometric center
6924 located on or inside shape).
6925 The replicated nodes should be associated to affected elements
6928 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6930 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6931 theMakeGroup=False, theMakeNodeGroup=False):
6933 Create a hole in a mesh by doubling the nodes of some particular elements.
6934 This method provided for convenience works as :meth:`DoubleNodes`.
6937 theElems: list of groups of elements (edges or faces) to replicate
6938 theNodesNot: list of groups of nodes NOT to replicate
6939 theAffectedElems: group of elements to which the replicated nodes
6940 should be associated to
6941 theMakeGroup: forces generation of a group containing new elements.
6942 theMakeNodeGroup: forces generation of a group containing new nodes
6945 True or created groups (one or two) if operation has been completed successfully,
6946 False or None otherwise
6949 if theMakeGroup or theMakeNodeGroup:
6950 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6952 theMakeGroup, theMakeNodeGroup)
6953 if theMakeGroup and theMakeNodeGroup:
6956 return twoGroups[ int(theMakeNodeGroup) ]
6957 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6959 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6961 Create a hole in a mesh by doubling the nodes of some particular elements.
6962 This method provided for convenience works as :meth:`DoubleNodes`.
6965 theElems: list of groups of elements (edges or faces) to replicate
6966 theNodesNot: list of groups of nodes NOT to replicate
6967 theShape: shape to detect affected elements (element which geometric center
6968 located on or inside shape).
6969 The replicated nodes should be associated to affected elements
6972 True if operation has been completed successfully, False otherwise
6975 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6977 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6979 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6980 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6983 theElems: list of groups of nodes or elements (edges or faces) to replicate
6984 theNodesNot: list of groups of nodes NOT to replicate
6985 theShape: shape to detect affected elements (element which geometric center
6986 located on or inside shape).
6987 The replicated nodes should be associated to affected elements
6990 groups of affected elements in order: volumes, faces, edges
6993 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6995 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6998 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6999 The list of groups must describe a partition of the mesh volumes.
7000 The nodes of the internal faces at the boundaries of the groups are doubled.
7001 In option, the internal faces are replaced by flat elements.
7002 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7005 theDomains: list of groups of volumes
7006 createJointElems: if True, create the elements
7007 onAllBoundaries: if True, the nodes and elements are also created on
7008 the boundary between *theDomains* and the rest mesh
7011 True if operation has been completed successfully, False otherwise
7014 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7016 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7018 Double nodes on some external faces and create flat elements.
7019 Flat elements are mainly used by some types of mechanic calculations.
7021 Each group of the list must be constituted of faces.
7022 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7025 theGroupsOfFaces: list of groups of faces
7028 True if operation has been completed successfully, False otherwise
7031 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7033 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7035 Identify all the elements around a geom shape, get the faces delimiting the hole
7037 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7039 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7041 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7042 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7043 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7044 If there are several paths connecting a pair of points, the shortest path is
7045 selected by the module. Position of the cutting plane is defined by the two
7046 points and an optional vector lying on the plane specified by a PolySegment.
7047 By default the vector is defined by Mesh module as following. A middle point
7048 of the two given points is computed. The middle point is projected to the mesh.
7049 The vector goes from the middle point to the projection point. In case of planar
7050 mesh, the vector is normal to the mesh.
7052 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7055 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7056 groupName: optional name of a group where created mesh segments will be added.
7059 editor = self.editor
7061 editor = self.mesh.GetMeshEditPreviewer()
7062 segmentsRes = editor.MakePolyLine( segments, groupName )
7063 for i, seg in enumerate( segmentsRes ):
7064 segments[i].vector = seg.vector
7066 return editor.GetPreviewData()
7069 def MakeSlot(self, segmentGroup, width ):
7071 Create a slot of given width around given 1D elements lying on a triangle mesh.
7072 The slot is constructed by cutting faces by cylindrical surfaces made
7073 around each segment. Segments are expected to be created by MakePolyLine().
7076 FaceEdge's located at the slot boundary
7078 return self.editor.MakeSlot( segmentGroup, width )
7080 def GetFunctor(self, funcType ):
7082 Return a cached numerical functor by its type.
7085 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7086 Note that not all items correspond to numerical functors.
7089 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7092 fn = self.functors[ funcType._v ]
7094 fn = self.smeshpyD.GetFunctor(funcType)
7095 fn.SetMesh(self.mesh)
7096 self.functors[ funcType._v ] = fn
7099 def FunctorValue(self, funcType, elemId, isElem=True):
7101 Return value of a functor for a given element
7104 funcType: an item of :class:`SMESH.FunctorType` enum.
7105 elemId: element or node ID
7106 isElem: *elemId* is ID of element or node
7109 the functor value or zero in case of invalid arguments
7112 fn = self.GetFunctor( funcType )
7113 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7114 val = fn.GetValue(elemId)
7119 def GetLength(self, elemId=None):
7121 Get length of given 1D elements or of all 1D mesh elements
7124 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.
7127 Sum of lengths of given elements
7132 length = self.smeshpyD.GetLength(self)
7133 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7134 length = self.smeshpyD.GetLength(elemId)
7137 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7139 length += self.smeshpyD.GetLength(obj)
7140 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7141 unRegister = genObjUnRegister()
7142 obj = self.GetIDSource( elemId )
7143 unRegister.set( obj )
7144 length = self.smeshpyD.GetLength( obj )
7146 length = self.FunctorValue(SMESH.FT_Length, elemId)
7149 def GetArea(self, elemId=None):
7151 Get area of given 2D elements or of all 2D mesh elements
7154 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.
7157 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7162 area = self.smeshpyD.GetArea(self)
7163 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7164 area = self.smeshpyD.GetArea(elemId)
7167 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7169 area += self.smeshpyD.GetArea(obj)
7170 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7171 unRegister = genObjUnRegister()
7172 obj = self.GetIDSource( elemId )
7173 unRegister.set( obj )
7174 area = self.smeshpyD.GetArea( obj )
7176 area = self.FunctorValue(SMESH.FT_Area, elemId)
7179 def GetVolume(self, elemId=None):
7181 Get volume of given 3D elements or of all 3D mesh elements
7184 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.
7187 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7192 volume= self.smeshpyD.GetVolume(self)
7193 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7194 volume= self.smeshpyD.GetVolume(elemId)
7197 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7199 volume+= self.smeshpyD.GetVolume(obj)
7200 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7201 unRegister = genObjUnRegister()
7202 obj = self.GetIDSource( elemId )
7203 unRegister.set( obj )
7204 volume= self.smeshpyD.GetVolume( obj )
7206 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7209 def GetAngle(self, node1, node2, node3 ):
7211 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7214 node1,node2,node3: IDs of the three nodes
7217 Angle in radians [0,PI]. -1 if failure case.
7219 p1 = self.GetNodeXYZ( node1 )
7220 p2 = self.GetNodeXYZ( node2 )
7221 p3 = self.GetNodeXYZ( node3 )
7222 if p1 and p2 and p3:
7223 return self.smeshpyD.GetAngle( p1,p2,p3 )
7227 def GetMaxElementLength(self, elemId):
7229 Get maximum element length.
7232 elemId: mesh element ID
7235 element's maximum length value
7238 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7239 ftype = SMESH.FT_MaxElementLength3D
7241 ftype = SMESH.FT_MaxElementLength2D
7242 return self.FunctorValue(ftype, elemId)
7244 def GetAspectRatio(self, elemId):
7246 Get aspect ratio of 2D or 3D element.
7249 elemId: mesh element ID
7252 element's aspect ratio value
7255 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7256 ftype = SMESH.FT_AspectRatio3D
7258 ftype = SMESH.FT_AspectRatio
7259 return self.FunctorValue(ftype, elemId)
7261 def GetWarping(self, elemId):
7263 Get warping angle of 2D element.
7266 elemId: mesh element ID
7269 element's warping angle value
7272 return self.FunctorValue(SMESH.FT_Warping, elemId)
7274 def GetMinimumAngle(self, elemId):
7276 Get minimum angle of 2D element.
7279 elemId: mesh element ID
7282 element's minimum angle value
7285 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7287 def GetTaper(self, elemId):
7289 Get taper of 2D element.
7292 elemId: mesh element ID
7295 element's taper value
7298 return self.FunctorValue(SMESH.FT_Taper, elemId)
7300 def GetSkew(self, elemId):
7302 Get skew of 2D element.
7305 elemId: mesh element ID
7308 element's skew value
7311 return self.FunctorValue(SMESH.FT_Skew, elemId)
7313 def GetMinMax(self, funType, meshPart=None):
7315 Return minimal and maximal value of a given functor.
7318 funType (SMESH.FunctorType): a functor type.
7319 Note that not all items of :class:`SMESH.FunctorType` corresponds
7320 to numerical functors.
7321 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7327 unRegister = genObjUnRegister()
7328 if isinstance( meshPart, list ):
7329 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7330 unRegister.set( meshPart )
7331 if isinstance( meshPart, Mesh ):
7332 meshPart = meshPart.mesh
7333 fun = self.GetFunctor( funType )
7336 if hasattr( meshPart, "SetMesh" ):
7337 meshPart.SetMesh( self.mesh ) # set mesh to filter
7338 hist = fun.GetLocalHistogram( 1, False, meshPart )
7340 hist = fun.GetHistogram( 1, False )
7342 return hist[0].min, hist[0].max
7345 pass # end of Mesh class
7348 class meshProxy(SMESH._objref_SMESH_Mesh):
7350 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7351 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7353 def __init__(self,*args):
7354 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7355 def __deepcopy__(self, memo=None):
7356 new = self.__class__(self)
7358 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7359 if len( args ) == 3:
7360 args += SMESH.ALL_NODES, True
7361 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7362 def ExportToMEDX(self, *args): # function removed
7363 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7364 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7365 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7366 def ExportToMED(self, *args): # function removed
7367 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7368 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7370 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7372 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7373 def ExportPartToMED(self, *args): # 'version' parameter removed
7374 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7375 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7376 def ExportMED(self, *args): # signature of method changed
7377 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7379 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7381 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7383 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7386 class submeshProxy(SMESH._objref_SMESH_subMesh):
7389 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7391 def __init__(self,*args):
7392 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7394 def __deepcopy__(self, memo=None):
7395 new = self.__class__(self)
7398 def Compute(self,refresh=False):
7400 Compute the sub-mesh and return the status of the computation
7403 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7408 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7409 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7413 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7415 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7417 if salome.sg.hasDesktop():
7418 if refresh: salome.sg.updateObjBrowser()
7423 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7426 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7428 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7429 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7432 def __init__(self,*args):
7433 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7435 def __getattr__(self, name ): # method called if an attribute not found
7436 if not self.mesh: # look for name() method in Mesh class
7437 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7438 if hasattr( self.mesh, name ):
7439 return getattr( self.mesh, name )
7440 if name == "ExtrusionAlongPathObjX":
7441 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7442 print("meshEditor: attribute '%s' NOT FOUND" % name)
7444 def __deepcopy__(self, memo=None):
7445 new = self.__class__(self)
7447 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7448 if len( args ) == 1: args += False,
7449 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7450 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7451 if len( args ) == 2: args += False,
7452 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7453 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7454 if len( args ) == 1:
7455 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7456 NodesToKeep = args[1]
7457 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7458 unRegister = genObjUnRegister()
7460 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7461 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7462 if not isinstance( NodesToKeep, list ):
7463 NodesToKeep = [ NodesToKeep ]
7464 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7466 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7468 class Pattern(SMESH._objref_SMESH_Pattern):
7470 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7471 variables in some methods
7474 def LoadFromFile(self, patternTextOrFile ):
7475 text = patternTextOrFile
7476 if os.path.exists( text ):
7477 text = open( patternTextOrFile ).read()
7479 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7481 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7482 decrFun = lambda i: i-1
7483 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7484 theMesh.SetParameters(Parameters)
7485 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7487 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7488 decrFun = lambda i: i-1
7489 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7490 theMesh.SetParameters(Parameters)
7491 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7493 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7494 if isinstance( mesh, Mesh ):
7495 mesh = mesh.GetMesh()
7496 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7498 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7500 Registering the new proxy for Pattern
7505 Private class used to bind methods creating algorithms to the class Mesh
7508 def __init__(self, method):
7510 self.defaultAlgoType = ""
7511 self.algoTypeToClass = {}
7512 self.method = method
7514 def add(self, algoClass):
7516 Store a python class of algorithm
7518 if inspect.isclass(algoClass) and \
7519 hasattr( algoClass, "algoType"):
7520 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7521 if not self.defaultAlgoType and \
7522 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7523 self.defaultAlgoType = algoClass.algoType
7524 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7526 def copy(self, mesh):
7528 Create a copy of self and assign mesh to the copy
7531 other = algoCreator( self.method )
7532 other.defaultAlgoType = self.defaultAlgoType
7533 other.algoTypeToClass = self.algoTypeToClass
7537 def __call__(self,algo="",geom=0,*args):
7539 Create an instance of algorithm
7543 if isinstance( algo, str ):
7545 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7546 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7551 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7553 elif not algoType and isinstance( geom, str ):
7558 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7560 elif isinstance( arg, str ) and not algoType:
7563 import traceback, sys
7564 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7565 sys.stderr.write( msg + '\n' )
7566 tb = traceback.extract_stack(None,2)
7567 traceback.print_list( [tb[0]] )
7569 algoType = self.defaultAlgoType
7570 if not algoType and self.algoTypeToClass:
7571 algoType = sorted( self.algoTypeToClass.keys() )[0]
7572 if algoType in self.algoTypeToClass:
7573 #print("Create algo",algoType)
7574 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7575 raise RuntimeError( "No class found for algo type %s" % algoType)
7578 class hypMethodWrapper:
7580 Private class used to substitute and store variable parameters of hypotheses.
7583 def __init__(self, hyp, method):
7585 self.method = method
7586 #print("REBIND:", method.__name__)
7589 def __call__(self,*args):
7591 call a method of hypothesis with calling SetVarParameter() before
7595 return self.method( self.hyp, *args ) # hypothesis method with no args
7597 #print("MethWrapper.__call__", self.method.__name__, args)
7599 parsed = ParseParameters(*args) # replace variables with their values
7600 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7601 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7602 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7603 # maybe there is a replaced string arg which is not variable
7604 result = self.method( self.hyp, *args )
7605 except ValueError as detail: # raised by ParseParameters()
7607 result = self.method( self.hyp, *args )
7608 except omniORB.CORBA.BAD_PARAM:
7609 raise ValueError(detail) # wrong variable name
7614 class genObjUnRegister:
7616 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7619 def __init__(self, genObj=None):
7620 self.genObjList = []
7624 def set(self, genObj):
7625 "Store one or a list of of SALOME.GenericObj'es"
7626 if isinstance( genObj, list ):
7627 self.genObjList.extend( genObj )
7629 self.genObjList.append( genObj )
7633 for genObj in self.genObjList:
7634 if genObj and hasattr( genObj, "UnRegister" ):
7637 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7639 Bind methods creating mesher plug-ins to the Mesh class
7642 # print("pluginName: ", pluginName)
7643 pluginBuilderName = pluginName + "Builder"
7645 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7646 except Exception as e:
7647 from salome_utils import verbose
7648 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7650 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7651 plugin = eval( pluginBuilderName )
7652 # print(" plugin:" , str(plugin))
7654 # add methods creating algorithms to Mesh
7655 for k in dir( plugin ):
7656 if k[0] == '_': continue
7657 algo = getattr( plugin, k )
7658 #print(" algo:", str(algo))
7659 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7660 #print(" meshMethod:" , str(algo.meshMethod))
7661 if not hasattr( Mesh, algo.meshMethod ):
7662 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7664 _mmethod = getattr( Mesh, algo.meshMethod )
7665 if hasattr( _mmethod, "add" ):