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 += ":"
1966 if salome.sg.hasDesktop():
1967 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1968 if refresh: salome.sg.updateObjBrowser()
1972 def GetComputeErrors(self, shape=0 ):
1974 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1978 shape = self.mesh.GetShapeToMesh()
1979 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1981 def GetSubShapeName(self, subShapeID ):
1983 Return a name of a sub-shape by its ID.
1984 Possible variants (for *subShapeID* == 3):
1986 - **"Face_12"** - published sub-shape
1987 - **FACE #3** - not published sub-shape
1988 - **sub-shape #3** - invalid sub-shape ID
1989 - **#3** - error in this function
1992 subShapeID: a unique ID of a sub-shape
1995 a string describing the sub-shape
1999 if not self.mesh.HasShapeToMesh():
2003 mainIOR = salome.orb.object_to_string( self.GetShape() )
2005 mainSO = s.FindObjectIOR(mainIOR)
2008 shapeText = '"%s"' % mainSO.GetName()
2009 subIt = s.NewChildIterator(mainSO)
2011 subSO = subIt.Value()
2013 obj = subSO.GetObject()
2014 if not obj: continue
2015 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2018 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2021 if ids == subShapeID:
2022 shapeText = '"%s"' % subSO.GetName()
2025 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2027 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2029 shapeText = 'sub-shape #%s' % (subShapeID)
2031 shapeText = "#%s" % (subShapeID)
2034 def GetFailedShapes(self, publish=False):
2036 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2037 error of an algorithm
2040 publish: if *True*, the returned groups will be published in the study
2043 a list of GEOM groups each named after a failed algorithm
2048 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2049 for err in computeErrors:
2050 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2051 if not shape: continue
2052 if err.algoName in algo2shapes:
2053 algo2shapes[ err.algoName ].append( shape )
2055 algo2shapes[ err.algoName ] = [ shape ]
2059 for algoName, shapes in list(algo2shapes.items()):
2061 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2062 otherTypeShapes = []
2064 group = self.geompyD.CreateGroup( self.geom, groupType )
2065 for shape in shapes:
2066 if shape.GetShapeType() == shapes[0].GetShapeType():
2067 sameTypeShapes.append( shape )
2069 otherTypeShapes.append( shape )
2070 self.geompyD.UnionList( group, sameTypeShapes )
2072 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2074 group.SetName( algoName )
2075 groups.append( group )
2076 shapes = otherTypeShapes
2079 for group in groups:
2080 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2083 def GetMeshOrder(self):
2085 Return sub-mesh objects list in meshing order
2088 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2091 return self.mesh.GetMeshOrder()
2093 def SetMeshOrder(self, submeshes):
2095 Set priority of sub-meshes. It works in two ways:
2097 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2098 *several dimensions*, it sets the order in which the sub-meshes are computed.
2099 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2100 when looking for meshing parameters to apply to a sub-shape. To impose the
2101 order in which sub-meshes with uni-dimensional algorithms are computed,
2102 call **submesh.Compute()** in a desired order.
2105 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2107 Warning: the method is for setting the order for all sub-meshes at once:
2108 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2111 return self.mesh.SetMeshOrder(submeshes)
2113 def Clear(self, refresh=False):
2115 Remove all nodes and elements generated on geometry. Imported elements remain.
2118 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2122 if ( salome.sg.hasDesktop() ):
2123 if refresh: salome.sg.updateObjBrowser()
2125 def ClearSubMesh(self, geomId, refresh=False):
2127 Remove all nodes and elements of indicated shape
2130 geomId: the ID of a sub-shape to remove elements on
2131 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2134 self.mesh.ClearSubMesh(geomId)
2135 if salome.sg.hasDesktop():
2136 if refresh: salome.sg.updateObjBrowser()
2138 def AutomaticTetrahedralization(self, fineness=0):
2140 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2143 fineness: [0.0,1.0] defines mesh fineness
2149 dim = self.MeshDimension()
2151 self.RemoveGlobalHypotheses()
2152 self.Segment().AutomaticLength(fineness)
2154 self.Triangle().LengthFromEdges()
2159 return self.Compute()
2161 def AutomaticHexahedralization(self, fineness=0):
2163 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2166 fineness: [0.0, 1.0] defines mesh fineness
2172 dim = self.MeshDimension()
2173 # assign the hypotheses
2174 self.RemoveGlobalHypotheses()
2175 self.Segment().AutomaticLength(fineness)
2182 return self.Compute()
2184 def AddHypothesis(self, hyp, geom=0):
2189 hyp: a hypothesis to assign
2190 geom: a subhape of mesh geometry
2193 :class:`SMESH.Hypothesis_Status`
2196 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2197 hyp, geom = geom, hyp
2198 if isinstance( hyp, Mesh_Algorithm ):
2199 hyp = hyp.GetAlgorithm()
2204 geom = self.mesh.GetShapeToMesh()
2207 if self.mesh.HasShapeToMesh():
2208 hyp_type = hyp.GetName()
2209 lib_name = hyp.GetLibName()
2210 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2211 # if checkAll and geom:
2212 # checkAll = geom.GetType() == 37
2214 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2216 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2217 status = self.mesh.AddHypothesis(geom, hyp)
2219 status = HYP_BAD_GEOMETRY, ""
2220 hyp_name = GetName( hyp )
2223 geom_name = geom.GetName()
2224 isAlgo = hyp._narrow( SMESH_Algo )
2225 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2228 def IsUsedHypothesis(self, hyp, geom):
2230 Return True if an algorithm or hypothesis is assigned to a given shape
2233 hyp: an algorithm or hypothesis to check
2234 geom: a subhape of mesh geometry
2240 if not hyp: # or not geom
2242 if isinstance( hyp, Mesh_Algorithm ):
2243 hyp = hyp.GetAlgorithm()
2245 hyps = self.GetHypothesisList(geom)
2247 if h.GetId() == hyp.GetId():
2251 def RemoveHypothesis(self, hyp, geom=0):
2253 Unassign a hypothesis
2256 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2257 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2260 :class:`SMESH.Hypothesis_Status`
2265 if isinstance( hyp, Mesh_Algorithm ):
2266 hyp = hyp.GetAlgorithm()
2272 if self.IsUsedHypothesis( hyp, shape ):
2273 return self.mesh.RemoveHypothesis( shape, hyp )
2274 hypName = GetName( hyp )
2275 geoName = GetName( shape )
2276 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2279 def GetHypothesisList(self, geom):
2281 Get the list of hypotheses added on a geometry
2284 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2287 the sequence of :class:`SMESH.SMESH_Hypothesis`
2290 return self.mesh.GetHypothesisList( geom )
2292 def RemoveGlobalHypotheses(self):
2294 Remove all global hypotheses
2297 current_hyps = self.mesh.GetHypothesisList( self.geom )
2298 for hyp in current_hyps:
2299 self.mesh.RemoveHypothesis( self.geom, hyp )
2302 def ExportMED(self, *args, **kwargs):
2304 Export the mesh in a file in MED format
2305 allowing to overwrite the file if it exists or add the exported data to its contents
2308 fileName: is the file name
2309 auto_groups (boolean): parameter for creating/not creating
2310 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2311 the typical use is auto_groups=False.
2312 version (int): define the version (xy, where version is x.y.z) of MED file format.
2313 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2314 The rules of compatibility to write a mesh in an older version than
2315 the current version depend on the current version. For instance,
2316 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2317 or 3.2.1 or 3.3.1 formats.
2318 If the version is equal to -1, the version is not changed (default).
2319 overwrite (boolean): parameter for overwriting/not overwriting the file
2320 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2321 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2323 - 1D if all mesh nodes lie on OX coordinate axis, or
2324 - 2D if all mesh nodes lie on XOY coordinate plane, or
2325 - 3D in the rest cases.
2327 If *autoDimension* is *False*, the space dimension is always 3.
2328 fields: list of GEOM fields defined on the shape to mesh.
2329 geomAssocFields: each character of this string means a need to export a
2330 corresponding field; correspondence between fields and characters
2333 - 'v' stands for "_vertices_" field;
2334 - 'e' stands for "_edges_" field;
2335 - 'f' stands for "_faces_" field;
2336 - 's' stands for "_solids_" field.
2338 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2339 close to zero within a given tolerance, the coordinate is set to zero.
2340 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2342 # process positional arguments
2343 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2345 auto_groups = args[1] if len(args) > 1 else False
2346 version = args[2] if len(args) > 2 else -1
2347 overwrite = args[3] if len(args) > 3 else True
2348 meshPart = args[4] if len(args) > 4 else None
2349 autoDimension = args[5] if len(args) > 5 else True
2350 fields = args[6] if len(args) > 6 else []
2351 geomAssocFields = args[7] if len(args) > 7 else ''
2352 z_tolerance = args[8] if len(args) > 8 else -1.
2353 # process keywords arguments
2354 auto_groups = kwargs.get("auto_groups", auto_groups)
2355 version = kwargs.get("version", version)
2356 version = kwargs.get("minor", version)
2357 overwrite = kwargs.get("overwrite", overwrite)
2358 meshPart = kwargs.get("meshPart", meshPart)
2359 autoDimension = kwargs.get("autoDimension", autoDimension)
2360 fields = kwargs.get("fields", fields)
2361 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2362 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2364 # invoke engine's function
2365 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2366 unRegister = genObjUnRegister()
2367 if isinstance( meshPart, list ):
2368 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2369 unRegister.set( meshPart )
2371 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2372 self.mesh.SetParameters(Parameters)
2374 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2375 version, overwrite, autoDimension,
2376 fields, geomAssocFields, z_tolerance)
2378 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2380 def ExportSAUV(self, f, auto_groups=0):
2382 Export the mesh in a file in SAUV format
2387 auto_groups: boolean parameter for creating/not creating
2388 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2389 the typical use is auto_groups=False.
2392 self.mesh.ExportSAUV(f, auto_groups)
2394 def ExportDAT(self, f, meshPart=None):
2396 Export the mesh in a file in DAT format
2400 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2404 unRegister = genObjUnRegister()
2405 if isinstance( meshPart, list ):
2406 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2407 unRegister.set( meshPart )
2408 self.mesh.ExportPartToDAT( meshPart, f )
2410 self.mesh.ExportDAT(f)
2412 def ExportUNV(self, f, meshPart=None):
2414 Export the mesh in a file in UNV format
2418 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2422 unRegister = genObjUnRegister()
2423 if isinstance( meshPart, list ):
2424 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2425 unRegister.set( meshPart )
2426 self.mesh.ExportPartToUNV( meshPart, f )
2428 self.mesh.ExportUNV(f)
2430 def ExportSTL(self, f, ascii=1, meshPart=None):
2432 Export the mesh in a file in STL format
2436 ascii: defines the file encoding
2437 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2441 unRegister = genObjUnRegister()
2442 if isinstance( meshPart, list ):
2443 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2444 unRegister.set( meshPart )
2445 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2447 self.mesh.ExportSTL(f, ascii)
2449 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2451 Export the mesh in a file in CGNS format
2455 overwrite: boolean parameter for overwriting/not overwriting the file
2456 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2457 groupElemsByType: if True all elements of same entity type are exported at ones,
2458 else elements are exported in order of their IDs which can cause creation
2459 of multiple cgns sections
2462 unRegister = genObjUnRegister()
2463 if isinstance( meshPart, list ):
2464 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2465 unRegister.set( meshPart )
2466 if isinstance( meshPart, Mesh ):
2467 meshPart = meshPart.mesh
2469 meshPart = self.mesh
2470 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2472 def ExportGMF(self, f, meshPart=None):
2474 Export the mesh in a file in GMF format.
2475 GMF files must have .mesh extension for the ASCII format and .meshb for
2476 the bynary format. Other extensions are not allowed.
2480 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2483 unRegister = genObjUnRegister()
2484 if isinstance( meshPart, list ):
2485 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2486 unRegister.set( meshPart )
2487 if isinstance( meshPart, Mesh ):
2488 meshPart = meshPart.mesh
2490 meshPart = self.mesh
2491 self.mesh.ExportGMF(meshPart, f, True)
2493 def ExportToMED(self, *args, **kwargs):
2495 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2496 Export the mesh in a file in MED format
2497 allowing to overwrite the file if it exists or add the exported data to its contents
2500 fileName: the file name
2501 opt (boolean): parameter for creating/not creating
2502 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2503 overwrite: boolean parameter for overwriting/not overwriting the file
2504 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2506 - 1D if all mesh nodes lie on OX coordinate axis, or
2507 - 2D if all mesh nodes lie on XOY coordinate plane, or
2508 - 3D in the rest cases.
2510 If **autoDimension** is *False*, the space dimension is always 3.
2513 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2514 # process positional arguments
2515 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2517 auto_groups = args[1] if len(args) > 1 else False
2518 overwrite = args[2] if len(args) > 2 else True
2519 autoDimension = args[3] if len(args) > 3 else True
2520 # process keywords arguments
2521 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2522 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2523 overwrite = kwargs.get("overwrite", overwrite)
2524 autoDimension = kwargs.get("autoDimension", autoDimension)
2526 # invoke engine's function
2527 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2529 def ExportToMEDX(self, *args, **kwargs):
2531 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2532 Export the mesh in a file in MED format
2535 fileName: the file name
2536 opt (boolean): parameter for creating/not creating
2537 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2538 overwrite: boolean parameter for overwriting/not overwriting the file
2539 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2541 - 1D if all mesh nodes lie on OX coordinate axis, or
2542 - 2D if all mesh nodes lie on XOY coordinate plane, or
2543 - 3D in the rest cases.
2545 If **autoDimension** is *False*, the space dimension is always 3.
2548 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2549 # process positional arguments
2550 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2552 auto_groups = args[1] if len(args) > 1 else False
2553 overwrite = args[2] if len(args) > 2 else True
2554 autoDimension = args[3] if len(args) > 3 else True
2555 # process keywords arguments
2556 auto_groups = kwargs.get("auto_groups", auto_groups)
2557 overwrite = kwargs.get("overwrite", overwrite)
2558 autoDimension = kwargs.get("autoDimension", autoDimension)
2560 # invoke engine's function
2561 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2565 def Append(self, meshes, uniteIdenticalGroups = True,
2566 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2568 Append given meshes into this mesh.
2569 All groups of input meshes will be created in this mesh.
2572 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2573 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2574 mergeNodesAndElements: if True, equal nodes and elements are merged
2575 mergeTolerance: tolerance for merging nodes
2576 allGroups: forces creation of groups corresponding to every input mesh
2578 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2579 mergeNodesAndElements, mergeTolerance, allGroups,
2580 meshToAppendTo = self.GetMesh() )
2582 # Operations with groups:
2583 # ----------------------
2584 def CreateEmptyGroup(self, elementType, name):
2586 Create an empty standalone mesh group
2589 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2590 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2591 name: the name of the mesh group
2594 :class:`SMESH.SMESH_Group`
2597 return self.mesh.CreateGroup(elementType, name)
2599 def Group(self, grp, name=""):
2601 Create a mesh group based on the geometric object *grp*
2602 and give it a *name*.
2603 If *name* is not defined the name of the geometric group is used
2606 Works like :meth:`GroupOnGeom`.
2609 grp: a geometric group, a vertex, an edge, a face or a solid
2610 name: the name of the mesh group
2613 :class:`SMESH.SMESH_GroupOnGeom`
2616 return self.GroupOnGeom(grp, name)
2618 def GroupOnGeom(self, grp, name="", typ=None):
2620 Create a mesh group based on the geometrical object *grp*
2621 and give it a *name*.
2622 if *name* is not defined the name of the geometric group is used
2625 grp: a geometrical group, a vertex, an edge, a face or a solid
2626 name: the name of the mesh group
2627 typ: the type of elements in the group; either of
2628 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2629 automatically detected by the type of the geometry
2632 :class:`SMESH.SMESH_GroupOnGeom`
2635 AssureGeomPublished( self, grp, name )
2637 name = grp.GetName()
2639 typ = self._groupTypeFromShape( grp )
2640 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2642 def _groupTypeFromShape( self, shape ):
2644 Pivate method to get a type of group on geometry
2646 tgeo = str(shape.GetShapeType())
2647 if tgeo == "VERTEX":
2649 elif tgeo == "EDGE" or tgeo == "WIRE":
2651 elif tgeo == "FACE" or tgeo == "SHELL":
2653 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2655 elif tgeo == "COMPOUND":
2656 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2658 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2659 return self._groupTypeFromShape( sub[0] )
2661 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2664 def GroupOnFilter(self, typ, name, filter):
2666 Create a mesh group with given *name* based on the *filter*.
2667 It is a special type of group dynamically updating it's contents during
2671 typ: the type of elements in the group; either of
2672 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2673 name: the name of the mesh group
2674 filter (SMESH.Filter): the filter defining group contents
2677 :class:`SMESH.SMESH_GroupOnFilter`
2680 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2682 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2684 Create a mesh group by the given ids of elements
2687 groupName: the name of the mesh group
2688 elementType: the type of elements in the group; either of
2689 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2690 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2693 :class:`SMESH.SMESH_Group`
2696 group = self.mesh.CreateGroup(elementType, groupName)
2697 if isinstance( elemIDs, Mesh ):
2698 elemIDs = elemIDs.GetMesh()
2699 if hasattr( elemIDs, "GetIDs" ):
2700 if hasattr( elemIDs, "SetMesh" ):
2701 elemIDs.SetMesh( self.GetMesh() )
2702 group.AddFrom( elemIDs )
2710 CritType=FT_Undefined,
2713 UnaryOp=FT_Undefined,
2716 Create a mesh group by the given conditions
2719 groupName: the name of the mesh group
2720 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2721 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2722 Note that the items starting from FT_LessThan are not suitable for CritType.
2723 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2724 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2725 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2726 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2727 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2730 :class:`SMESH.SMESH_GroupOnFilter`
2733 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2734 group = self.MakeGroupByCriterion(groupName, aCriterion)
2737 def MakeGroupByCriterion(self, groupName, Criterion):
2739 Create a mesh group by the given criterion
2742 groupName: the name of the mesh group
2743 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2746 :class:`SMESH.SMESH_GroupOnFilter`
2749 :meth:`smeshBuilder.GetCriterion`
2752 return self.MakeGroupByCriteria( groupName, [Criterion] )
2754 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2756 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2759 groupName: the name of the mesh group
2760 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2761 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2764 :class:`SMESH.SMESH_GroupOnFilter`
2767 :meth:`smeshBuilder.GetCriterion`
2770 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2771 group = self.MakeGroupByFilter(groupName, aFilter)
2774 def MakeGroupByFilter(self, groupName, theFilter):
2776 Create a mesh group by the given filter
2779 groupName (string): the name of the mesh group
2780 theFilter (SMESH.Filter): the filter
2783 :class:`SMESH.SMESH_GroupOnFilter`
2786 :meth:`smeshBuilder.GetFilter`
2789 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2790 #theFilter.SetMesh( self.mesh )
2791 #group.AddFrom( theFilter )
2792 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2795 def RemoveGroup(self, group):
2800 group (SMESH.SMESH_GroupBase): group to remove
2803 self.mesh.RemoveGroup(group)
2805 def RemoveGroupWithContents(self, group):
2807 Remove a group with its contents
2810 group (SMESH.SMESH_GroupBase): group to remove
2813 This operation can create gaps in numeration of nodes or elements.
2814 Call :meth:`RenumberElements` to remove the gaps.
2817 self.mesh.RemoveGroupWithContents(group)
2819 def GetGroups(self, elemType = SMESH.ALL):
2821 Get the list of groups existing in the mesh in the order of creation
2822 (starting from the oldest one)
2825 elemType (SMESH.ElementType): type of elements the groups contain;
2826 by default groups of elements of all types are returned
2829 a list of :class:`SMESH.SMESH_GroupBase`
2832 groups = self.mesh.GetGroups()
2833 if elemType == SMESH.ALL:
2837 if g.GetType() == elemType:
2838 typedGroups.append( g )
2845 Get the number of groups existing in the mesh
2848 the quantity of groups as an integer value
2851 return self.mesh.NbGroups()
2853 def GetGroupNames(self):
2855 Get the list of names of groups existing in the mesh
2861 groups = self.GetGroups()
2863 for group in groups:
2864 names.append(group.GetName())
2867 def GetGroupByName(self, name, elemType = None):
2869 Find groups by name and type
2872 name (string): name of the group of interest
2873 elemType (SMESH.ElementType): type of elements the groups contain;
2874 by default one group of any type is returned;
2875 if elemType == SMESH.ALL then all groups of any type are returned
2878 a list of :class:`SMESH.SMESH_GroupBase`
2882 for group in self.GetGroups():
2883 if group.GetName() == name:
2884 if elemType is None:
2886 if ( elemType == SMESH.ALL or
2887 group.GetType() == elemType ):
2888 groups.append( group )
2891 def UnionGroups(self, group1, group2, name):
2893 Produce a union of two groups.
2894 A new group is created. All mesh elements that are
2895 present in the initial groups are added to the new one
2898 group1 (SMESH.SMESH_GroupBase): a group
2899 group2 (SMESH.SMESH_GroupBase): another group
2902 instance of :class:`SMESH.SMESH_Group`
2905 return self.mesh.UnionGroups(group1, group2, name)
2907 def UnionListOfGroups(self, groups, name):
2909 Produce a union list of groups.
2910 New group is created. All mesh elements that are present in
2911 initial groups are added to the new one
2914 groups: list of :class:`SMESH.SMESH_GroupBase`
2917 instance of :class:`SMESH.SMESH_Group`
2919 return self.mesh.UnionListOfGroups(groups, name)
2921 def IntersectGroups(self, group1, group2, name):
2923 Prodice an intersection of two groups.
2924 A new group is created. All mesh elements that are common
2925 for the two initial groups are added to the new one.
2928 group1 (SMESH.SMESH_GroupBase): a group
2929 group2 (SMESH.SMESH_GroupBase): another group
2932 instance of :class:`SMESH.SMESH_Group`
2935 return self.mesh.IntersectGroups(group1, group2, name)
2937 def IntersectListOfGroups(self, groups, name):
2939 Produce an intersection of groups.
2940 New group is created. All mesh elements that are present in all
2941 initial groups simultaneously are added to the new one
2944 groups: a list of :class:`SMESH.SMESH_GroupBase`
2947 instance of :class:`SMESH.SMESH_Group`
2949 return self.mesh.IntersectListOfGroups(groups, name)
2951 def CutGroups(self, main_group, tool_group, name):
2953 Produce a cut of two groups.
2954 A new group is created. All mesh elements that are present in
2955 the main group but are not present in the tool group are added to the new one
2958 main_group (SMESH.SMESH_GroupBase): a group to cut from
2959 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2962 an instance of :class:`SMESH.SMESH_Group`
2965 return self.mesh.CutGroups(main_group, tool_group, name)
2967 def CutListOfGroups(self, main_groups, tool_groups, name):
2969 Produce a cut of groups.
2970 A new group is created. All mesh elements that are present in main groups
2971 but do not present in tool groups are added to the new one
2974 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2975 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2978 an instance of :class:`SMESH.SMESH_Group`
2981 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2983 def CreateDimGroup(self, groups, elemType, name,
2984 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2986 Create a standalone group of entities basing on nodes of other groups.
2989 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2990 elemType: a type of elements to include to the new group; either of
2991 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2992 name: a name of the new group.
2993 nbCommonNodes: a criterion of inclusion of an element to the new group
2994 basing on number of element nodes common with reference *groups*.
2995 Meaning of possible values are:
2997 - SMESH.ALL_NODES - include if all nodes are common,
2998 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2999 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3000 - SMEHS.MAJORITY - include if half of nodes or more are common.
3001 underlyingOnly: if *True* (default), an element is included to the
3002 new group provided that it is based on nodes of an element of *groups*;
3003 in this case the reference *groups* are supposed to be of higher dimension
3004 than *elemType*, which can be useful for example to get all faces lying on
3005 volumes of the reference *groups*.
3008 an instance of :class:`SMESH.SMESH_Group`
3011 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3013 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3015 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3017 Distribute all faces of the mesh among groups using sharp edges and optionally
3018 existing 1D elements as group boundaries.
3021 sharpAngle: edge is considered sharp if an angle between normals of
3022 adjacent faces is more than \a sharpAngle in degrees.
3023 createEdges (boolean): to create 1D elements for detected sharp edges.
3024 useExistingEdges (boolean): to use existing edges as group boundaries
3026 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3028 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3029 self.mesh.SetParameters(Parameters)
3030 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3032 def ConvertToStandalone(self, group):
3034 Convert group on geom into standalone group
3037 return self.mesh.ConvertToStandalone(group)
3039 # Get some info about mesh:
3040 # ------------------------
3042 def GetLog(self, clearAfterGet):
3044 Return the log of nodes and elements added or removed
3045 since the previous clear of the log.
3048 clearAfterGet: log is emptied after Get (safe if concurrents access)
3051 list of SMESH.log_block structures { commandType, number, coords, indexes }
3054 return self.mesh.GetLog(clearAfterGet)
3058 Clear the log of nodes and elements added or removed since the previous
3059 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3062 self.mesh.ClearLog()
3064 def SetAutoColor(self, theAutoColor):
3066 Toggle auto color mode on the object.
3067 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3070 theAutoColor (boolean): the flag which toggles auto color mode.
3073 self.mesh.SetAutoColor(theAutoColor)
3075 def GetAutoColor(self):
3077 Get flag of object auto color mode.
3083 return self.mesh.GetAutoColor()
3090 integer value, which is the internal Id of the mesh
3093 return self.mesh.GetId()
3095 def HasDuplicatedGroupNamesMED(self):
3097 Check the group names for duplications.
3098 Consider the maximum group name length stored in MED file.
3104 return self.mesh.HasDuplicatedGroupNamesMED()
3106 def GetMeshEditor(self):
3108 Obtain the mesh editor tool
3111 an instance of :class:`SMESH.SMESH_MeshEditor`
3116 def GetIDSource(self, ids, elemType = SMESH.ALL):
3118 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3119 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3123 elemType: type of elements; this parameter is used to distinguish
3124 IDs of nodes from IDs of elements; by default ids are treated as
3125 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3128 an instance of :class:`SMESH.SMESH_IDSource`
3131 call UnRegister() for the returned object as soon as it is no more useful::
3133 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3134 mesh.DoSomething( idSrc )
3138 if isinstance( ids, int ):
3140 return self.editor.MakeIDSource(ids, elemType)
3143 # Get information about mesh contents:
3144 # ------------------------------------
3146 def GetMeshInfo(self, obj = None):
3148 Get the mesh statistic.
3151 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3154 if not obj: obj = self.mesh
3155 return self.smeshpyD.GetMeshInfo(obj)
3159 Return the number of nodes in the mesh
3165 return self.mesh.NbNodes()
3167 def NbElements(self):
3169 Return the number of elements in the mesh
3175 return self.mesh.NbElements()
3177 def Nb0DElements(self):
3179 Return the number of 0d elements in the mesh
3185 return self.mesh.Nb0DElements()
3189 Return the number of ball discrete elements in the mesh
3195 return self.mesh.NbBalls()
3199 Return the number of edges in the mesh
3205 return self.mesh.NbEdges()
3207 def NbEdgesOfOrder(self, elementOrder):
3209 Return the number of edges with the given order in the mesh
3212 elementOrder: the order of elements
3213 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3219 return self.mesh.NbEdgesOfOrder(elementOrder)
3223 Return the number of faces in the mesh
3229 return self.mesh.NbFaces()
3231 def NbFacesOfOrder(self, elementOrder):
3233 Return the number of faces with the given order in the mesh
3236 elementOrder: the order of elements
3237 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3243 return self.mesh.NbFacesOfOrder(elementOrder)
3245 def NbTriangles(self):
3247 Return the number of triangles in the mesh
3253 return self.mesh.NbTriangles()
3255 def NbTrianglesOfOrder(self, elementOrder):
3257 Return the number of triangles with the given order in the mesh
3260 elementOrder: is the order of elements
3261 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3267 return self.mesh.NbTrianglesOfOrder(elementOrder)
3269 def NbBiQuadTriangles(self):
3271 Return the number of biquadratic triangles in the mesh
3277 return self.mesh.NbBiQuadTriangles()
3279 def NbQuadrangles(self):
3281 Return the number of quadrangles in the mesh
3287 return self.mesh.NbQuadrangles()
3289 def NbQuadranglesOfOrder(self, elementOrder):
3291 Return the number of quadrangles with the given order in the mesh
3294 elementOrder: the order of elements
3295 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3301 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3303 def NbBiQuadQuadrangles(self):
3305 Return the number of biquadratic quadrangles in the mesh
3311 return self.mesh.NbBiQuadQuadrangles()
3313 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3315 Return the number of polygons of given order in the mesh
3318 elementOrder: the order of elements
3319 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3325 return self.mesh.NbPolygonsOfOrder(elementOrder)
3327 def NbVolumes(self):
3329 Return the number of volumes in the mesh
3335 return self.mesh.NbVolumes()
3338 def NbVolumesOfOrder(self, elementOrder):
3340 Return the number of volumes with the given order in the mesh
3343 elementOrder: the order of elements
3344 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3350 return self.mesh.NbVolumesOfOrder(elementOrder)
3354 Return the number of tetrahedrons in the mesh
3360 return self.mesh.NbTetras()
3362 def NbTetrasOfOrder(self, elementOrder):
3364 Return the number of tetrahedrons with the given order in the mesh
3367 elementOrder: the order of elements
3368 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3374 return self.mesh.NbTetrasOfOrder(elementOrder)
3378 Return the number of hexahedrons in the mesh
3384 return self.mesh.NbHexas()
3386 def NbHexasOfOrder(self, elementOrder):
3388 Return the number of hexahedrons with the given order in the mesh
3391 elementOrder: the order of elements
3392 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3398 return self.mesh.NbHexasOfOrder(elementOrder)
3400 def NbTriQuadraticHexas(self):
3402 Return the number of triquadratic hexahedrons in the mesh
3408 return self.mesh.NbTriQuadraticHexas()
3410 def NbPyramids(self):
3412 Return the number of pyramids in the mesh
3418 return self.mesh.NbPyramids()
3420 def NbPyramidsOfOrder(self, elementOrder):
3422 Return the number of pyramids with the given order in the mesh
3425 elementOrder: the order of elements
3426 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3432 return self.mesh.NbPyramidsOfOrder(elementOrder)
3436 Return the number of prisms in the mesh
3442 return self.mesh.NbPrisms()
3444 def NbPrismsOfOrder(self, elementOrder):
3446 Return the number of prisms with the given order in the mesh
3449 elementOrder: the order of elements
3450 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3456 return self.mesh.NbPrismsOfOrder(elementOrder)
3458 def NbHexagonalPrisms(self):
3460 Return the number of hexagonal prisms in the mesh
3466 return self.mesh.NbHexagonalPrisms()
3468 def NbPolyhedrons(self):
3470 Return the number of polyhedrons in the mesh
3476 return self.mesh.NbPolyhedrons()
3478 def NbSubMesh(self):
3480 Return the number of submeshes in the mesh
3486 return self.mesh.NbSubMesh()
3488 def GetElementsId(self):
3490 Return the list of all mesh elements IDs
3493 the list of integer values
3496 :meth:`GetElementsByType`
3499 return self.mesh.GetElementsId()
3501 def GetElementsByType(self, elementType):
3503 Return the list of IDs of mesh elements with the given type
3506 elementType (SMESH.ElementType): the required type of elements
3509 list of integer values
3512 return self.mesh.GetElementsByType(elementType)
3514 def GetNodesId(self):
3516 Return the list of mesh nodes IDs
3519 the list of integer values
3522 return self.mesh.GetNodesId()
3524 # Get the information about mesh elements:
3525 # ------------------------------------
3527 def GetElementType(self, id, iselem=True):
3529 Return the type of mesh element or node
3532 the value from :class:`SMESH.ElementType` enumeration.
3533 Return SMESH.ALL if element or node with the given ID does not exist
3536 return self.mesh.GetElementType(id, iselem)
3538 def GetElementGeomType(self, id):
3540 Return the geometric type of mesh element
3543 the value from :class:`SMESH.EntityType` enumeration.
3546 return self.mesh.GetElementGeomType(id)
3548 def GetElementShape(self, id):
3550 Return the shape type of mesh element
3553 the value from :class:`SMESH.GeometryType` enumeration.
3556 return self.mesh.GetElementShape(id)
3558 def GetSubMeshElementsId(self, Shape):
3560 Return the list of sub-mesh elements IDs
3563 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3564 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3567 list of integer values
3570 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3571 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3574 return self.mesh.GetSubMeshElementsId(ShapeID)
3576 def GetSubMeshNodesId(self, Shape, all):
3578 Return the list of sub-mesh nodes IDs
3581 Shape: a geom object (sub-shape).
3582 *Shape* must be the sub-shape of a :meth:`GetShape`
3583 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3586 list of integer values
3589 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3590 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3593 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3595 def GetSubMeshElementType(self, Shape):
3597 Return type of elements on given shape
3600 Shape: a geom object (sub-shape).
3601 *Shape* must be a sub-shape of a ShapeToMesh()
3604 :class:`SMESH.ElementType`
3607 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3608 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3611 return self.mesh.GetSubMeshElementType(ShapeID)
3615 Get the mesh description
3621 return self.mesh.Dump()
3624 # Get the information about nodes and elements of a mesh by its IDs:
3625 # -----------------------------------------------------------
3627 def GetNodeXYZ(self, id):
3629 Get XYZ coordinates of a node.
3630 If there is no node for the given ID - return an empty list
3633 list of float values
3636 return self.mesh.GetNodeXYZ(id)
3638 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3640 Return list of IDs of inverse elements for the given node.
3641 If there is no node for the given ID - return an empty list
3645 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3648 list of integer values
3651 return self.mesh.GetNodeInverseElements(id,elemType)
3653 def GetNodePosition(self,NodeID):
3655 Return the position of a node on the shape
3658 :class:`SMESH.NodePosition`
3661 return self.mesh.GetNodePosition(NodeID)
3663 def GetElementPosition(self,ElemID):
3665 Return the position of an element on the shape
3668 :class:`SMESH.ElementPosition`
3671 return self.mesh.GetElementPosition(ElemID)
3673 def GetShapeID(self, id):
3675 Return the ID of the shape, on which the given node was generated.
3678 an integer value > 0 or -1 if there is no node for the given
3679 ID or the node is not assigned to any geometry
3682 return self.mesh.GetShapeID(id)
3684 def GetShapeIDForElem(self,id):
3686 Return the ID of the shape, on which the given element was generated.
3689 an integer value > 0 or -1 if there is no element for the given
3690 ID or the element is not assigned to any geometry
3693 return self.mesh.GetShapeIDForElem(id)
3695 def GetElemNbNodes(self, id):
3697 Return the number of nodes of the given element
3700 an integer value > 0 or -1 if there is no element for the given ID
3703 return self.mesh.GetElemNbNodes(id)
3705 def GetElemNode(self, id, index):
3707 Return the node ID the given (zero based) index for the given element.
3709 * If there is no element for the given ID - return -1.
3710 * If there is no node for the given index - return -2.
3713 id (int): element ID
3714 index (int): node index within the element
3717 an integer value (ID)
3720 :meth:`GetElemNodes`
3723 return self.mesh.GetElemNode(id, index)
3725 def GetElemNodes(self, id):
3727 Return the IDs of nodes of the given element
3730 a list of integer values
3733 return self.mesh.GetElemNodes(id)
3735 def IsMediumNode(self, elementID, nodeID):
3737 Return true if the given node is the medium node in the given quadratic element
3740 return self.mesh.IsMediumNode(elementID, nodeID)
3742 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3744 Return true if the given node is the medium node in one of quadratic elements
3747 nodeID: ID of the node
3748 elementType: the type of elements to check a state of the node, either of
3749 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3752 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3754 def ElemNbEdges(self, id):
3756 Return the number of edges for the given element
3759 return self.mesh.ElemNbEdges(id)
3761 def ElemNbFaces(self, id):
3763 Return the number of faces for the given element
3766 return self.mesh.ElemNbFaces(id)
3768 def GetElemFaceNodes(self,elemId, faceIndex):
3770 Return nodes of given face (counted from zero) for given volumic element.
3773 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3775 def GetFaceNormal(self, faceId, normalized=False):
3777 Return three components of normal of given mesh face
3778 (or an empty array in KO case)
3781 return self.mesh.GetFaceNormal(faceId,normalized)
3783 def FindElementByNodes(self, nodes):
3785 Return an element based on all given nodes.
3788 return self.mesh.FindElementByNodes(nodes)
3790 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3792 Return elements including all given nodes.
3795 return self.mesh.GetElementsByNodes( nodes, elemType )
3797 def IsPoly(self, id):
3799 Return true if the given element is a polygon
3802 return self.mesh.IsPoly(id)
3804 def IsQuadratic(self, id):
3806 Return true if the given element is quadratic
3809 return self.mesh.IsQuadratic(id)
3811 def GetBallDiameter(self, id):
3813 Return diameter of a ball discrete element or zero in case of an invalid *id*
3816 return self.mesh.GetBallDiameter(id)
3818 def BaryCenter(self, id):
3820 Return XYZ coordinates of the barycenter of the given element.
3821 If there is no element for the given ID - return an empty list
3824 a list of three double values
3827 :meth:`smeshBuilder.GetGravityCenter`
3830 return self.mesh.BaryCenter(id)
3832 def GetIdsFromFilter(self, filter, meshParts=[] ):
3834 Pass mesh elements through the given filter and return IDs of fitting elements
3837 filter: :class:`SMESH.Filter`
3838 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3844 :meth:`SMESH.Filter.GetIDs`
3845 :meth:`SMESH.Filter.GetElementsIdFromParts`
3848 filter.SetMesh( self.mesh )
3851 if isinstance( meshParts, Mesh ):
3852 filter.SetMesh( meshParts.GetMesh() )
3853 return theFilter.GetIDs()
3854 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3855 meshParts = [ meshParts ]
3856 return filter.GetElementsIdFromParts( meshParts )
3858 return filter.GetIDs()
3860 # Get mesh measurements information:
3861 # ------------------------------------
3863 def GetFreeBorders(self):
3865 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3866 Return a list of special structures (borders).
3869 a list of :class:`SMESH.FreeEdges.Border`
3872 aFilterMgr = self.smeshpyD.CreateFilterManager()
3873 aPredicate = aFilterMgr.CreateFreeEdges()
3874 aPredicate.SetMesh(self.mesh)
3875 aBorders = aPredicate.GetBorders()
3876 aFilterMgr.UnRegister()
3879 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3881 Get minimum distance between two nodes, elements or distance to the origin
3884 id1: first node/element id
3885 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3886 isElem1: *True* if *id1* is element id, *False* if it is node id
3887 isElem2: *True* if *id2* is element id, *False* if it is node id
3890 minimum distance value
3892 :meth:`GetMinDistance`
3895 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3896 return aMeasure.value
3898 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3900 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3903 id1: first node/element id
3904 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3905 isElem1: *True* if *id1* is element id, *False* if it is node id
3906 isElem2: *True* if *id2* is element id, *False* if it is node id
3909 :class:`SMESH.Measure` structure
3915 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3917 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3920 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3922 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3927 aMeasurements = self.smeshpyD.CreateMeasurements()
3928 aMeasure = aMeasurements.MinDistance(id1, id2)
3929 genObjUnRegister([aMeasurements,id1, id2])
3932 def BoundingBox(self, objects=None, isElem=False):
3934 Get bounding box of the specified object(s)
3937 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3938 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3939 *False* specifies that *objects* are nodes
3942 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3945 :meth:`GetBoundingBox()`
3948 result = self.GetBoundingBox(objects, isElem)
3952 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3955 def GetBoundingBox(self, objects=None, isElem=False):
3957 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3960 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3961 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3962 False means that *objects* are nodes
3965 :class:`SMESH.Measure` structure
3968 :meth:`BoundingBox()`
3972 objects = [self.mesh]
3973 elif isinstance(objects, tuple):
3974 objects = list(objects)
3975 if not isinstance(objects, list):
3977 if len(objects) > 0 and isinstance(objects[0], int):
3980 unRegister = genObjUnRegister()
3982 if isinstance(o, Mesh):
3983 srclist.append(o.mesh)
3984 elif hasattr(o, "_narrow"):
3985 src = o._narrow(SMESH.SMESH_IDSource)
3986 if src: srclist.append(src)
3988 elif isinstance(o, list):
3990 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3992 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3993 unRegister.set( srclist[-1] )
3996 aMeasurements = self.smeshpyD.CreateMeasurements()
3997 unRegister.set( aMeasurements )
3998 aMeasure = aMeasurements.BoundingBox(srclist)
4001 # Mesh edition (SMESH_MeshEditor functionality):
4002 # ---------------------------------------------
4004 def RemoveElements(self, IDsOfElements):
4006 Remove the elements from the mesh by ids
4009 IDsOfElements: is a list of ids of elements to remove
4015 This operation can create gaps in numeration of elements.
4016 Call :meth:`RenumberElements` to remove the gaps.
4019 return self.editor.RemoveElements(IDsOfElements)
4021 def RemoveNodes(self, IDsOfNodes):
4023 Remove nodes from mesh by ids
4026 IDsOfNodes: is a list of ids of nodes to remove
4032 This operation can create gaps in numeration of nodes.
4033 Call :meth:`RenumberElements` to remove the gaps.
4036 return self.editor.RemoveNodes(IDsOfNodes)
4038 def RemoveOrphanNodes(self):
4040 Remove all orphan (free) nodes from mesh
4043 number of the removed nodes
4046 This operation can create gaps in numeration of nodes.
4047 Call :meth:`RenumberElements` to remove the gaps.
4050 return self.editor.RemoveOrphanNodes()
4052 def AddNode(self, x, y, z):
4054 Add a node to the mesh by coordinates
4060 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4061 if hasVars: self.mesh.SetParameters(Parameters)
4062 return self.editor.AddNode( x, y, z)
4064 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4066 Create a 0D element on a node with given number.
4069 IDOfNode: the ID of node for creation of the element.
4070 DuplicateElements: to add one more 0D element to a node or not
4073 ID of the new 0D element
4076 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4078 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4080 Create 0D elements on all nodes of the given elements except those
4081 nodes on which a 0D element already exists.
4084 theObject: an object on whose nodes 0D elements will be created.
4085 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4086 theGroupName: optional name of a group to add 0D elements created
4087 and/or found on nodes of *theObject*.
4088 DuplicateElements: to add one more 0D element to a node or not
4091 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4092 IDs of new and/or found 0D elements. IDs of 0D elements
4093 can be retrieved from the returned object by
4094 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4097 unRegister = genObjUnRegister()
4098 if isinstance( theObject, Mesh ):
4099 theObject = theObject.GetMesh()
4100 elif isinstance( theObject, list ):
4101 theObject = self.GetIDSource( theObject, SMESH.ALL )
4102 unRegister.set( theObject )
4103 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4105 def AddBall(self, IDOfNode, diameter):
4107 Create a ball element on a node with given ID.
4110 IDOfNode: the ID of node for creation of the element.
4111 diameter: the bal diameter.
4114 ID of the new ball element
4117 return self.editor.AddBall( IDOfNode, diameter )
4119 def AddEdge(self, IDsOfNodes):
4121 Create a linear or quadratic edge (this is determined
4122 by the number of given nodes).
4125 IDsOfNodes: list of node IDs for creation of the element.
4126 The order of nodes in this list should correspond to
4127 the :ref:`connectivity convention <connectivity_page>`.
4133 return self.editor.AddEdge(IDsOfNodes)
4135 def AddFace(self, IDsOfNodes):
4137 Create a linear or quadratic face (this is determined
4138 by the number of given nodes).
4141 IDsOfNodes: list of node IDs for creation of the element.
4142 The order of nodes in this list should correspond to
4143 the :ref:`connectivity convention <connectivity_page>`.
4149 return self.editor.AddFace(IDsOfNodes)
4151 def AddPolygonalFace(self, IdsOfNodes):
4153 Add a polygonal face defined by a list of node IDs
4156 IdsOfNodes: the list of node IDs for creation of the element.
4162 return self.editor.AddPolygonalFace(IdsOfNodes)
4164 def AddQuadPolygonalFace(self, IdsOfNodes):
4166 Add a quadratic polygonal face defined by a list of node IDs
4169 IdsOfNodes: the list of node IDs for creation of the element;
4170 corner nodes follow first.
4176 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4178 def AddVolume(self, IDsOfNodes):
4180 Create both simple and quadratic volume (this is determined
4181 by the number of given nodes).
4184 IDsOfNodes: list of node IDs for creation of the element.
4185 The order of nodes in this list should correspond to
4186 the :ref:`connectivity convention <connectivity_page>`.
4189 ID of the new volumic element
4192 return self.editor.AddVolume(IDsOfNodes)
4194 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4196 Create a volume of many faces, giving nodes for each face.
4199 IdsOfNodes: list of node IDs for volume creation, face by face.
4200 Quantities: list of integer values, Quantities[i]
4201 gives the quantity of nodes in face number i.
4204 ID of the new volumic element
4207 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4209 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4211 Create a volume of many faces, giving the IDs of the existing faces.
4214 The created volume will refer only to the nodes
4215 of the given faces, not to the faces themselves.
4218 IdsOfFaces: the list of face IDs for volume creation.
4221 ID of the new volumic element
4224 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4227 def SetNodeOnVertex(self, NodeID, Vertex):
4229 Bind a node to a vertex
4233 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4236 True if succeed else raises an exception
4239 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4240 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4244 self.editor.SetNodeOnVertex(NodeID, VertexID)
4245 except SALOME.SALOME_Exception as inst:
4246 raise ValueError(inst.details.text)
4250 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4252 Store the node position on an edge
4256 Edge: an edge (GEOM.GEOM_Object) or edge ID
4257 paramOnEdge: a parameter on the edge where the node is located
4260 True if succeed else raises an exception
4263 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4264 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4268 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4269 except SALOME.SALOME_Exception as inst:
4270 raise ValueError(inst.details.text)
4273 def SetNodeOnFace(self, NodeID, Face, u, v):
4275 Store node position on a face
4279 Face: a face (GEOM.GEOM_Object) or face ID
4280 u: U parameter on the face where the node is located
4281 v: V parameter on the face where the node is located
4284 True if succeed else raises an exception
4287 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4288 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4292 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4293 except SALOME.SALOME_Exception as inst:
4294 raise ValueError(inst.details.text)
4297 def SetNodeInVolume(self, NodeID, Solid):
4299 Bind a node to a solid
4303 Solid: a solid (GEOM.GEOM_Object) or solid ID
4306 True if succeed else raises an exception
4309 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4310 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4314 self.editor.SetNodeInVolume(NodeID, SolidID)
4315 except SALOME.SALOME_Exception as inst:
4316 raise ValueError(inst.details.text)
4319 def SetMeshElementOnShape(self, ElementID, Shape):
4321 Bind an element to a shape
4324 ElementID: an element ID
4325 Shape: a shape (GEOM.GEOM_Object) or shape ID
4328 True if succeed else raises an exception
4331 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4332 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4336 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4337 except SALOME.SALOME_Exception as inst:
4338 raise ValueError(inst.details.text)
4342 def MoveNode(self, NodeID, x, y, z):
4344 Move the node with the given id
4347 NodeID: the id of the node
4348 x: a new X coordinate
4349 y: a new Y coordinate
4350 z: a new Z coordinate
4353 True if succeed else False
4356 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4357 if hasVars: self.mesh.SetParameters(Parameters)
4358 return self.editor.MoveNode(NodeID, x, y, z)
4360 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4362 Find the node closest to a point and moves it to a point location
4365 x: the X coordinate of a point
4366 y: the Y coordinate of a point
4367 z: the Z coordinate of a point
4368 NodeID: if specified (>0), the node with this ID is moved,
4369 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4372 the ID of a moved node
4375 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4376 if hasVars: self.mesh.SetParameters(Parameters)
4377 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4379 def FindNodeClosestTo(self, x, y, z):
4381 Find the node closest to a point
4384 x: the X coordinate of a point
4385 y: the Y coordinate of a point
4386 z: the Z coordinate of a point
4392 return self.editor.FindNodeClosestTo(x, y, z)
4394 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4396 Find the elements where a point lays IN or ON
4399 x,y,z (float): coordinates of the point
4400 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4401 means elements of any type excluding nodes, discrete and 0D elements.
4402 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4405 list of IDs of found elements
4408 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4410 return self.editor.FindElementsByPoint(x, y, z, elementType)
4412 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4414 Project a point to a mesh object.
4415 Return ID of an element of given type where the given point is projected
4416 and coordinates of the projection point.
4417 In the case if nothing found, return -1 and []
4419 if isinstance( meshObject, Mesh ):
4420 meshObject = meshObject.GetMesh()
4422 meshObject = self.GetMesh()
4423 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4425 def GetPointState(self, x, y, z):
4427 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4428 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4429 UNKNOWN state means that either mesh is wrong or the analysis fails.
4432 return self.editor.GetPointState(x, y, z)
4434 def IsManifold(self):
4436 Check if a 2D mesh is manifold
4439 return self.editor.IsManifold()
4441 def IsCoherentOrientation2D(self):
4443 Check if orientation of 2D elements is coherent
4446 return self.editor.IsCoherentOrientation2D()
4448 def Get1DBranches( self, edges, startNode = 0 ):
4450 Partition given 1D elements into groups of contiguous edges.
4451 A node where number of meeting edges != 2 is a group end.
4452 An optional startNode is used to orient groups it belongs to.
4455 A list of edge groups and a list of corresponding node groups,
4456 where the group is a list of IDs of edges or nodes, like follows
4457 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4458 If a group is closed, the first and last nodes of the group are same.
4460 if isinstance( edges, Mesh ):
4461 edges = edges.GetMesh()
4462 unRegister = genObjUnRegister()
4463 if isinstance( edges, list ):
4464 edges = self.GetIDSource( edges, SMESH.EDGE )
4465 unRegister.set( edges )
4466 return self.editor.Get1DBranches( edges, startNode )
4468 def FindSharpEdges( self, angle, addExisting=False ):
4470 Return sharp edges of faces and non-manifold ones.
4471 Optionally add existing edges.
4474 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4475 addExisting: to return existing edges (1D elements) as well
4478 list of FaceEdge structures
4480 angle = ParseParameters( angle )[0]
4481 return self.editor.FindSharpEdges( angle, addExisting )
4483 def MeshToPassThroughAPoint(self, x, y, z):
4485 Find the node closest to a point and moves it to a point location
4488 x: the X coordinate of a point
4489 y: the Y coordinate of a point
4490 z: the Z coordinate of a point
4493 the ID of a moved node
4496 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4498 def InverseDiag(self, NodeID1, NodeID2):
4500 Replace two neighbour triangles sharing Node1-Node2 link
4501 with the triangles built on the same 4 nodes but having other common link.
4504 NodeID1: the ID of the first node
4505 NodeID2: the ID of the second node
4508 False if proper faces were not found
4510 return self.editor.InverseDiag(NodeID1, NodeID2)
4512 def DeleteDiag(self, NodeID1, NodeID2):
4514 Replace two neighbour triangles sharing *Node1-Node2* link
4515 with a quadrangle built on the same 4 nodes.
4518 NodeID1: ID of the first node
4519 NodeID2: ID of the second node
4522 False if proper faces were not found
4525 This operation can create gaps in numeration of elements.
4526 Call :meth:`RenumberElements` to remove the gaps.
4529 return self.editor.DeleteDiag(NodeID1, NodeID2)
4531 def Reorient(self, IDsOfElements=None):
4533 Reorient elements by ids
4536 IDsOfElements: if undefined reorients all mesh elements
4539 True if succeed else False
4542 if IDsOfElements == None:
4543 IDsOfElements = self.GetElementsId()
4544 return self.editor.Reorient(IDsOfElements)
4546 def ReorientObject(self, theObject):
4548 Reorient all elements of the object
4551 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4554 True if succeed else False
4557 if ( isinstance( theObject, Mesh )):
4558 theObject = theObject.GetMesh()
4559 return self.editor.ReorientObject(theObject)
4561 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4563 Reorient faces contained in *the2DObject*.
4566 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4567 theDirection: a desired direction of normal of *theFace*.
4568 It can be either a GEOM vector or a list of coordinates [x,y,z].
4569 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4570 compared with theDirection. It can be either ID of face or a point
4571 by which the face will be found. The point can be given as either
4572 a GEOM vertex or a list of point coordinates.
4575 number of reoriented faces
4578 unRegister = genObjUnRegister()
4580 if isinstance( the2DObject, Mesh ):
4581 the2DObject = the2DObject.GetMesh()
4582 if isinstance( the2DObject, list ):
4583 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4584 unRegister.set( the2DObject )
4585 # check theDirection
4586 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4587 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4588 if isinstance( theDirection, list ):
4589 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4590 # prepare theFace and thePoint
4591 theFace = theFaceOrPoint
4592 thePoint = PointStruct(0,0,0)
4593 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4594 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4596 if isinstance( theFaceOrPoint, list ):
4597 thePoint = PointStruct( *theFaceOrPoint )
4599 if isinstance( theFaceOrPoint, PointStruct ):
4600 thePoint = theFaceOrPoint
4602 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4604 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4606 Reorient faces according to adjacent volumes.
4609 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4610 either IDs of faces or face groups.
4611 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4612 theOutsideNormal: to orient faces to have their normals
4613 pointing either *outside* or *inside* the adjacent volumes.
4616 number of reoriented faces.
4619 unRegister = genObjUnRegister()
4621 if not isinstance( the2DObject, list ):
4622 the2DObject = [ the2DObject ]
4623 elif the2DObject and isinstance( the2DObject[0], int ):
4624 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4625 unRegister.set( the2DObject )
4626 the2DObject = [ the2DObject ]
4627 for i,obj2D in enumerate( the2DObject ):
4628 if isinstance( obj2D, Mesh ):
4629 the2DObject[i] = obj2D.GetMesh()
4630 if isinstance( obj2D, list ):
4631 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4632 unRegister.set( the2DObject[i] )
4634 if isinstance( the3DObject, Mesh ):
4635 the3DObject = the3DObject.GetMesh()
4636 if isinstance( the3DObject, list ):
4637 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4638 unRegister.set( the3DObject )
4639 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4641 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4643 Fuse the neighbouring triangles into quadrangles.
4646 IDsOfElements: The triangles to be fused.
4647 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4648 applied to possible quadrangles to choose a neighbour to fuse with.
4649 Note that not all items of :class:`SMESH.FunctorType` corresponds
4650 to numerical functors.
4651 MaxAngle: is the maximum angle between element normals at which the fusion
4652 is still performed; theMaxAngle is measured in radians.
4653 Also it could be a name of variable which defines angle in degrees.
4656 True in case of success, False otherwise.
4659 This operation can create gaps in numeration of elements.
4660 Call :meth:`RenumberElements` to remove the gaps.
4663 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4664 self.mesh.SetParameters(Parameters)
4665 if not IDsOfElements:
4666 IDsOfElements = self.GetElementsId()
4667 Functor = self.smeshpyD.GetFunctor(theCriterion)
4668 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4670 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4672 Fuse the neighbouring triangles of the object into quadrangles
4675 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4676 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4677 applied to possible quadrangles to choose a neighbour to fuse with.
4678 Note that not all items of :class:`SMESH.FunctorType` corresponds
4679 to numerical functors.
4680 MaxAngle: a max angle between element normals at which the fusion
4681 is still performed; theMaxAngle is measured in radians.
4684 True in case of success, False otherwise.
4687 This operation can create gaps in numeration of elements.
4688 Call :meth:`RenumberElements` to remove the gaps.
4691 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4692 self.mesh.SetParameters(Parameters)
4693 if isinstance( theObject, Mesh ):
4694 theObject = theObject.GetMesh()
4695 Functor = self.smeshpyD.GetFunctor(theCriterion)
4696 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4698 def QuadToTri (self, IDsOfElements, theCriterion = None):
4700 Split quadrangles into triangles.
4703 IDsOfElements: the faces to be splitted.
4704 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4705 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4706 value, then quadrangles will be split by the smallest diagonal.
4707 Note that not all items of :class:`SMESH.FunctorType` corresponds
4708 to numerical functors.
4711 True in case of success, False otherwise.
4714 This operation can create gaps in numeration of elements.
4715 Call :meth:`RenumberElements` to remove the gaps.
4717 if IDsOfElements == []:
4718 IDsOfElements = self.GetElementsId()
4719 if theCriterion is None:
4720 theCriterion = FT_MaxElementLength2D
4721 Functor = self.smeshpyD.GetFunctor(theCriterion)
4722 return self.editor.QuadToTri(IDsOfElements, Functor)
4724 def QuadToTriObject (self, theObject, theCriterion = None):
4726 Split quadrangles into triangles.
4729 theObject: the object from which the list of elements is taken,
4730 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4731 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4732 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4733 value, then quadrangles will be split by the smallest diagonal.
4734 Note that not all items of :class:`SMESH.FunctorType` corresponds
4735 to numerical functors.
4738 True in case of success, False otherwise.
4741 This operation can create gaps in numeration of elements.
4742 Call :meth:`RenumberElements` to remove the gaps.
4744 if ( isinstance( theObject, Mesh )):
4745 theObject = theObject.GetMesh()
4746 if theCriterion is None:
4747 theCriterion = FT_MaxElementLength2D
4748 Functor = self.smeshpyD.GetFunctor(theCriterion)
4749 return self.editor.QuadToTriObject(theObject, Functor)
4751 def QuadTo4Tri (self, theElements=[]):
4753 Split each of given quadrangles into 4 triangles. A node is added at the center of
4757 theElements: the faces to be splitted. This can be either
4758 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4759 or a list of face IDs. By default all quadrangles are split
4762 This operation can create gaps in numeration of elements.
4763 Call :meth:`RenumberElements` to remove the gaps.
4765 unRegister = genObjUnRegister()
4766 if isinstance( theElements, Mesh ):
4767 theElements = theElements.mesh
4768 elif not theElements:
4769 theElements = self.mesh
4770 elif isinstance( theElements, list ):
4771 theElements = self.GetIDSource( theElements, SMESH.FACE )
4772 unRegister.set( theElements )
4773 return self.editor.QuadTo4Tri( theElements )
4775 def SplitQuad (self, IDsOfElements, Diag13):
4777 Split quadrangles into triangles.
4780 IDsOfElements: the faces to be splitted
4781 Diag13 (boolean): is used to choose a diagonal for splitting.
4784 True in case of success, False otherwise.
4787 This operation can create gaps in numeration of elements.
4788 Call :meth:`RenumberElements` to remove the gaps.
4790 if IDsOfElements == []:
4791 IDsOfElements = self.GetElementsId()
4792 return self.editor.SplitQuad(IDsOfElements, Diag13)
4794 def SplitQuadObject (self, theObject, Diag13):
4796 Split quadrangles into triangles.
4799 theObject: the object from which the list of elements is taken,
4800 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4801 Diag13 (boolean): is used to choose a diagonal for splitting.
4804 True in case of success, False otherwise.
4807 This operation can create gaps in numeration of elements.
4808 Call :meth:`RenumberElements` to remove the gaps.
4810 if ( isinstance( theObject, Mesh )):
4811 theObject = theObject.GetMesh()
4812 return self.editor.SplitQuadObject(theObject, Diag13)
4814 def BestSplit (self, IDOfQuad, theCriterion):
4816 Find a better splitting of the given quadrangle.
4819 IDOfQuad: the ID of the quadrangle to be splitted.
4820 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4821 choose a diagonal for splitting.
4822 Note that not all items of :class:`SMESH.FunctorType` corresponds
4823 to numerical functors.
4826 * 1 if 1-3 diagonal is better,
4827 * 2 if 2-4 diagonal is better,
4828 * 0 if error occurs.
4831 This operation can create gaps in numeration of elements.
4832 Call :meth:`RenumberElements` to remove the gaps.
4834 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4836 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4838 Split volumic elements into tetrahedrons
4841 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4842 method: flags passing splitting method:
4843 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4844 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4847 This operation can create gaps in numeration of elements.
4848 Call :meth:`RenumberElements` to remove the gaps.
4850 unRegister = genObjUnRegister()
4851 if isinstance( elems, Mesh ):
4852 elems = elems.GetMesh()
4853 if ( isinstance( elems, list )):
4854 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4855 unRegister.set( elems )
4856 self.editor.SplitVolumesIntoTetra(elems, method)
4859 def SplitBiQuadraticIntoLinear(self, elems=None):
4861 Split bi-quadratic elements into linear ones without creation of additional nodes:
4863 - bi-quadratic triangle will be split into 3 linear quadrangles;
4864 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4865 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4867 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4868 will be split in order to keep the mesh conformal.
4871 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4872 if None (default), all bi-quadratic elements will be split
4875 This operation can create gaps in numeration of elements.
4876 Call :meth:`RenumberElements` to remove the gaps.
4878 unRegister = genObjUnRegister()
4879 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4880 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4881 unRegister.set( elems )
4883 elems = [ self.GetMesh() ]
4884 if isinstance( elems, Mesh ):
4885 elems = [ elems.GetMesh() ]
4886 if not isinstance( elems, list ):
4888 self.editor.SplitBiQuadraticIntoLinear( elems )
4890 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4891 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4893 Split hexahedra into prisms
4896 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4897 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4898 gives a normal vector defining facets to split into triangles.
4899 *startHexPoint* can be either a triple of coordinates or a vertex.
4900 facetNormal: a normal to a facet to split into triangles of a
4901 hexahedron found by *startHexPoint*.
4902 *facetNormal* can be either a triple of coordinates or an edge.
4903 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4904 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4905 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4906 to *startHexPoint* are split, else *startHexPoint*
4907 is used to find the facet to split in all domains present in *elems*.
4910 This operation can create gaps in numeration of elements.
4911 Call :meth:`RenumberElements` to remove the gaps.
4914 unRegister = genObjUnRegister()
4915 if isinstance( elems, Mesh ):
4916 elems = elems.GetMesh()
4917 if ( isinstance( elems, list )):
4918 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4919 unRegister.set( elems )
4922 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4923 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4924 elif isinstance( startHexPoint, list ):
4925 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4928 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4929 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4930 elif isinstance( facetNormal, list ):
4931 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4934 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4936 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4938 def SplitQuadsNearTriangularFacets(self):
4940 Split quadrangle faces near triangular facets of volumes
4943 This operation can create gaps in numeration of elements.
4944 Call :meth:`RenumberElements` to remove the gaps.
4946 faces_array = self.GetElementsByType(SMESH.FACE)
4947 for face_id in faces_array:
4948 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4949 quad_nodes = self.mesh.GetElemNodes(face_id)
4950 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4951 isVolumeFound = False
4952 for node1_elem in node1_elems:
4953 if not isVolumeFound:
4954 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4955 nb_nodes = self.GetElemNbNodes(node1_elem)
4956 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4957 volume_elem = node1_elem
4958 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4959 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4960 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4961 isVolumeFound = True
4962 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4963 self.SplitQuad([face_id], False) # diagonal 2-4
4964 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4965 isVolumeFound = True
4966 self.SplitQuad([face_id], True) # diagonal 1-3
4967 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4968 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4969 isVolumeFound = True
4970 self.SplitQuad([face_id], True) # diagonal 1-3
4972 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4974 Split hexahedrons into tetrahedrons.
4976 This operation uses :doc:`pattern_mapping` functionality for splitting.
4979 theObject: the object from which the list of hexahedrons is taken;
4980 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4981 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4982 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4983 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4984 key-point will be mapped into *theNode001*-th node of each volume.
4985 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4988 True in case of success, False otherwise.
4991 This operation can create gaps in numeration of elements.
4992 Call :meth:`RenumberElements` to remove the gaps.
5000 # (0,0,1) 4.---------.7 * |
5007 # (0,0,0) 0.---------.3
5008 pattern_tetra = "!!! Nb of points: \n 8 \n\
5018 !!! Indices of points of 6 tetras: \n\
5026 pattern = self.smeshpyD.GetPattern()
5027 isDone = pattern.LoadFromFile(pattern_tetra)
5029 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5032 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5033 isDone = pattern.MakeMesh(self.mesh, False, False)
5034 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5036 # split quafrangle faces near triangular facets of volumes
5037 self.SplitQuadsNearTriangularFacets()
5041 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5043 Split hexahedrons into prisms.
5045 Uses the :doc:`pattern_mapping` functionality for splitting.
5048 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5049 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5050 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5051 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5052 will be mapped into the *theNode001* -th node of each volume.
5053 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5056 True in case of success, False otherwise.
5059 This operation can create gaps in numeration of elements.
5060 Call :meth:`RenumberElements` to remove the gaps.
5062 # Pattern: 5.---------.6
5067 # (0,0,1) 4.---------.7 |
5074 # (0,0,0) 0.---------.3
5075 pattern_prism = "!!! Nb of points: \n 8 \n\
5085 !!! Indices of points of 2 prisms: \n\
5089 pattern = self.smeshpyD.GetPattern()
5090 isDone = pattern.LoadFromFile(pattern_prism)
5092 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5095 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5096 isDone = pattern.MakeMesh(self.mesh, False, False)
5097 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5099 # Split quafrangle faces near triangular facets of volumes
5100 self.SplitQuadsNearTriangularFacets()
5104 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5105 MaxNbOfIterations, MaxAspectRatio, Method):
5110 IDsOfElements: the list if ids of elements to smooth
5111 IDsOfFixedNodes: the list of ids of fixed nodes.
5112 Note that nodes built on edges and boundary nodes are always fixed.
5113 MaxNbOfIterations: the maximum number of iterations
5114 MaxAspectRatio: varies in range [1.0, inf]
5115 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5116 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5119 True in case of success, False otherwise.
5122 if IDsOfElements == []:
5123 IDsOfElements = self.GetElementsId()
5124 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5125 self.mesh.SetParameters(Parameters)
5126 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5127 MaxNbOfIterations, MaxAspectRatio, Method)
5129 def SmoothObject(self, theObject, IDsOfFixedNodes,
5130 MaxNbOfIterations, MaxAspectRatio, Method):
5132 Smooth elements which belong to the given object
5135 theObject: the object to smooth
5136 IDsOfFixedNodes: the list of ids of fixed nodes.
5137 Note that nodes built on edges and boundary nodes are always fixed.
5138 MaxNbOfIterations: the maximum number of iterations
5139 MaxAspectRatio: varies in range [1.0, inf]
5140 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5141 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5144 True in case of success, False otherwise.
5147 if ( isinstance( theObject, Mesh )):
5148 theObject = theObject.GetMesh()
5149 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5150 MaxNbOfIterations, MaxAspectRatio, Method)
5152 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5153 MaxNbOfIterations, MaxAspectRatio, Method):
5155 Parametrically smooth the given elements
5158 IDsOfElements: the list if ids of elements to smooth
5159 IDsOfFixedNodes: the list of ids of fixed nodes.
5160 Note that nodes built on edges and boundary nodes are always fixed.
5161 MaxNbOfIterations: the maximum number of iterations
5162 MaxAspectRatio: varies in range [1.0, inf]
5163 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5164 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5167 True in case of success, False otherwise.
5170 if IDsOfElements == []:
5171 IDsOfElements = self.GetElementsId()
5172 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5173 self.mesh.SetParameters(Parameters)
5174 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5175 MaxNbOfIterations, MaxAspectRatio, Method)
5177 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5178 MaxNbOfIterations, MaxAspectRatio, Method):
5180 Parametrically smooth the elements which belong to the given object
5183 theObject: the object to smooth
5184 IDsOfFixedNodes: the list of ids of fixed nodes.
5185 Note that nodes built on edges and boundary nodes are always fixed.
5186 MaxNbOfIterations: the maximum number of iterations
5187 MaxAspectRatio: varies in range [1.0, inf]
5188 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5189 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5192 True in case of success, False otherwise.
5195 if ( isinstance( theObject, Mesh )):
5196 theObject = theObject.GetMesh()
5197 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5198 MaxNbOfIterations, MaxAspectRatio, Method)
5200 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5202 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5203 them with quadratic with the same id.
5206 theForce3d: method of new node creation:
5208 * False - the medium node lies at the geometrical entity from which the mesh element is built
5209 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5210 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5211 theToBiQuad: If True, converts the mesh to bi-quadratic
5214 :class:`SMESH.ComputeError` which can hold a warning
5217 If *theSubMesh* is provided, the mesh can become non-conformal
5220 This operation can create gaps in numeration of nodes or elements.
5221 Call :meth:`RenumberElements` to remove the gaps.
5224 if isinstance( theSubMesh, Mesh ):
5225 theSubMesh = theSubMesh.mesh
5227 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5230 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5232 self.editor.ConvertToQuadratic(theForce3d)
5233 error = self.editor.GetLastError()
5234 if error and error.comment:
5235 print(error.comment)
5238 def ConvertFromQuadratic(self, theSubMesh=None):
5240 Convert the mesh from quadratic to ordinary,
5241 deletes old quadratic elements,
5242 replacing them with ordinary mesh elements with the same id.
5245 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5248 If *theSubMesh* is provided, the mesh can become non-conformal
5251 This operation can create gaps in numeration of nodes or elements.
5252 Call :meth:`RenumberElements` to remove the gaps.
5256 self.editor.ConvertFromQuadraticObject(theSubMesh)
5258 return self.editor.ConvertFromQuadratic()
5260 def Make2DMeshFrom3D(self):
5262 Create 2D mesh as skin on boundary faces of a 3D mesh
5265 True if operation has been completed successfully, False otherwise
5268 return self.editor.Make2DMeshFrom3D()
5270 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5271 toCopyElements=False, toCopyExistingBondary=False):
5273 Create missing boundary elements
5276 elements: elements whose boundary is to be checked:
5277 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5278 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5279 dimension: defines type of boundary elements to create, either of
5280 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5281 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5282 groupName: a name of group to store created boundary elements in,
5283 "" means not to create the group
5284 meshName: a name of new mesh to store created boundary elements in,
5285 "" means not to create the new mesh
5286 toCopyElements: if True, the checked elements will be copied into
5287 the new mesh else only boundary elements will be copied into the new mesh
5288 toCopyExistingBondary: if True, not only new but also pre-existing
5289 boundary elements will be copied into the new mesh
5292 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5295 unRegister = genObjUnRegister()
5296 if isinstance( elements, Mesh ):
5297 elements = elements.GetMesh()
5298 if ( isinstance( elements, list )):
5299 elemType = SMESH.ALL
5300 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5301 elements = self.editor.MakeIDSource(elements, elemType)
5302 unRegister.set( elements )
5303 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5304 toCopyElements,toCopyExistingBondary)
5305 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5308 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5309 toCopyAll=False, groups=[]):
5311 Create missing boundary elements around either the whole mesh or
5315 dimension: defines type of boundary elements to create, either of
5316 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5317 groupName: a name of group to store all boundary elements in,
5318 "" means not to create the group
5319 meshName: a name of a new mesh, which is a copy of the initial
5320 mesh + created boundary elements; "" means not to create the new mesh
5321 toCopyAll: if True, the whole initial mesh will be copied into
5322 the new mesh else only boundary elements will be copied into the new mesh
5323 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5326 tuple( long, mesh, group )
5327 - long - number of added boundary elements
5328 - mesh - the :class:`Mesh` where elements were added to
5329 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5332 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5334 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5335 return nb, mesh, group
5337 def RenumberNodes(self):
5339 Renumber mesh nodes to remove unused node IDs
5341 self.editor.RenumberNodes()
5343 def RenumberElements(self):
5345 Renumber mesh elements to remove unused element IDs
5347 self.editor.RenumberElements()
5349 def _getIdSourceList(self, arg, idType, unRegister):
5351 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5353 if arg and isinstance( arg, list ):
5354 if isinstance( arg[0], int ):
5355 arg = self.GetIDSource( arg, idType )
5356 unRegister.set( arg )
5357 elif isinstance( arg[0], Mesh ):
5358 arg[0] = arg[0].GetMesh()
5359 elif isinstance( arg, Mesh ):
5361 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5365 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5366 MakeGroups=False, TotalAngle=False):
5368 Generate new elements by rotation of the given elements and nodes around the axis
5371 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5372 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5373 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5374 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5375 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5376 which defines angle in degrees
5377 NbOfSteps: the number of steps
5378 Tolerance: tolerance
5379 MakeGroups: forces the generation of new groups from existing ones
5380 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5381 of all steps, else - size of each step
5384 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5387 unRegister = genObjUnRegister()
5388 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5389 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5390 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5392 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5393 Axis = self.smeshpyD.GetAxisStruct( Axis )
5394 if isinstance( Axis, list ):
5395 Axis = SMESH.AxisStruct( *Axis )
5397 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5398 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5399 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5400 self.mesh.SetParameters(Parameters)
5401 if TotalAngle and NbOfSteps:
5402 AngleInRadians /= NbOfSteps
5403 return self.editor.RotationSweepObjects( nodes, edges, faces,
5404 Axis, AngleInRadians,
5405 NbOfSteps, Tolerance, MakeGroups)
5407 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5408 MakeGroups=False, TotalAngle=False):
5410 Generate new elements by rotation of the elements around the axis
5413 IDsOfElements: the list of ids of elements to sweep
5414 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5415 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5416 NbOfSteps: the number of steps
5417 Tolerance: tolerance
5418 MakeGroups: forces the generation of new groups from existing ones
5419 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5420 of all steps, else - size of each step
5423 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5426 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5427 AngleInRadians, NbOfSteps, Tolerance,
5428 MakeGroups, TotalAngle)
5430 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5431 MakeGroups=False, TotalAngle=False):
5433 Generate new elements by rotation of the elements of object around the axis
5434 theObject object which elements should be sweeped.
5435 It can be a mesh, a sub mesh or a group.
5438 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5439 AngleInRadians: the angle of Rotation
5440 NbOfSteps: number of steps
5441 Tolerance: tolerance
5442 MakeGroups: forces the generation of new groups from existing ones
5443 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5444 of all steps, else - size of each step
5447 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5450 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5451 AngleInRadians, NbOfSteps, Tolerance,
5452 MakeGroups, TotalAngle )
5454 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5455 MakeGroups=False, TotalAngle=False):
5457 Generate new elements by rotation of the elements of object around the axis
5458 theObject object which elements should be sweeped.
5459 It can be a mesh, a sub mesh or a group.
5462 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5463 AngleInRadians: the angle of Rotation
5464 NbOfSteps: number of steps
5465 Tolerance: tolerance
5466 MakeGroups: forces the generation of new groups from existing ones
5467 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5468 of all steps, else - size of each step
5471 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5472 empty list otherwise
5475 return self.RotationSweepObjects([],theObject,[], Axis,
5476 AngleInRadians, NbOfSteps, Tolerance,
5477 MakeGroups, TotalAngle)
5479 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5480 MakeGroups=False, TotalAngle=False):
5482 Generate new elements by rotation of the elements of object around the axis
5483 theObject object which elements should be sweeped.
5484 It can be a mesh, a sub mesh or a group.
5487 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5488 AngleInRadians: the angle of Rotation
5489 NbOfSteps: number of steps
5490 Tolerance: tolerance
5491 MakeGroups: forces the generation of new groups from existing ones
5492 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5493 of all steps, else - size of each step
5496 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5499 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5500 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5502 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5503 scaleFactors=[], linearVariation=False, basePoint=[],
5504 angles=[], anglesVariation=False):
5506 Generate new elements by extrusion of the given elements and nodes
5509 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5510 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5511 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5512 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5513 the direction and value of extrusion for one step (the total extrusion
5514 length will be NbOfSteps * ||StepVector||)
5515 NbOfSteps: the number of steps
5516 MakeGroups: forces the generation of new groups from existing ones
5517 scaleFactors: optional scale factors to apply during extrusion
5518 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5519 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5520 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5521 nodes and elements being extruded is used as the scaling center.
5524 - a list of tree components of the point or
5527 angles: list of angles in radians. Nodes at each extrusion step are rotated
5528 around *basePoint*, additionally to previous steps.
5529 anglesVariation: forces the computation of rotation angles as linear
5530 variation of the given *angles* along path steps
5532 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5534 Example: :ref:`tui_extrusion`
5536 unRegister = genObjUnRegister()
5537 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5538 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5539 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5541 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5542 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5543 if isinstance( StepVector, list ):
5544 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5546 if isinstance( basePoint, int):
5547 xyz = self.GetNodeXYZ( basePoint )
5549 raise RuntimeError("Invalid node ID: %s" % basePoint)
5551 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5552 basePoint = self.geompyD.PointCoordinates( basePoint )
5554 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5555 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5556 angles,angleParameters,hasVars = ParseAngles(angles)
5557 Parameters = StepVector.PS.parameters + var_separator + \
5558 Parameters + var_separator + \
5559 scaleParameters + var_separator + angleParameters
5560 self.mesh.SetParameters(Parameters)
5562 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5563 StepVector, NbOfSteps, MakeGroups,
5564 scaleFactors, linearVariation, basePoint,
5565 angles, anglesVariation )
5568 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5570 Generate new elements by extrusion of the elements with given ids
5573 IDsOfElements: the list of ids of elements or nodes for extrusion
5574 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5575 the direction and value of extrusion for one step (the total extrusion
5576 length will be NbOfSteps * ||StepVector||)
5577 NbOfSteps: the number of steps
5578 MakeGroups: forces the generation of new groups from existing ones
5579 IsNodes: is True if elements with given ids are nodes
5582 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5584 Example: :ref:`tui_extrusion`
5587 if IsNodes: n = IDsOfElements
5588 else : e,f, = IDsOfElements,IDsOfElements
5589 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5591 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5592 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5594 Generate new elements by extrusion along the normal to a discretized surface or wire
5597 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5598 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5599 StepSize: length of one extrusion step (the total extrusion
5600 length will be *NbOfSteps* *StepSize*).
5601 NbOfSteps: number of extrusion steps.
5602 ByAverageNormal: if True each node is translated by *StepSize*
5603 along the average of the normal vectors to the faces sharing the node;
5604 else each node is translated along the same average normal till
5605 intersection with the plane got by translation of the face sharing
5606 the node along its own normal by *StepSize*.
5607 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5608 for every node of *Elements*.
5609 MakeGroups: forces generation of new groups from existing ones.
5610 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5611 is not yet implemented. This parameter is used if *Elements* contains
5612 both faces and edges, i.e. *Elements* is a Mesh.
5615 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5616 empty list otherwise.
5617 Example: :ref:`tui_extrusion`
5620 unRegister = genObjUnRegister()
5621 if isinstance( Elements, Mesh ):
5622 Elements = [ Elements.GetMesh() ]
5623 if isinstance( Elements, list ):
5625 raise RuntimeError("Elements empty!")
5626 if isinstance( Elements[0], Mesh ):
5627 Elements = [ Elements[0].GetMesh() ]
5628 if isinstance( Elements[0], int ):
5629 Elements = self.GetIDSource( Elements, SMESH.ALL )
5630 unRegister.set( Elements )
5631 if not isinstance( Elements, list ):
5632 Elements = [ Elements ]
5633 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5634 self.mesh.SetParameters(Parameters)
5635 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5636 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5638 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5640 Generate new elements by extrusion of the elements or nodes which belong to the object
5643 theObject: the object whose elements or nodes should be processed.
5644 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5645 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5646 the direction and value of extrusion for one step (the total extrusion
5647 length will be NbOfSteps * ||StepVector||)
5648 NbOfSteps: the number of steps
5649 MakeGroups: forces the generation of new groups from existing ones
5650 IsNodes: is True if elements to extrude are nodes
5653 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5654 Example: :ref:`tui_extrusion`
5658 if IsNodes: n = theObject
5659 else : e,f, = theObject,theObject
5660 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5662 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5664 Generate new elements by extrusion of edges which belong to the object
5667 theObject: object whose 1D elements should be processed.
5668 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5669 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5670 the direction and value of extrusion for one step (the total extrusion
5671 length will be NbOfSteps * ||StepVector||)
5672 NbOfSteps: the number of steps
5673 MakeGroups: to generate new groups from existing ones
5676 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5677 Example: :ref:`tui_extrusion`
5680 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5682 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5684 Generate new elements by extrusion of faces which belong to the object
5687 theObject: object whose 2D elements should be processed.
5688 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5689 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5690 the direction and value of extrusion for one step (the total extrusion
5691 length will be NbOfSteps * ||StepVector||)
5692 NbOfSteps: the number of steps
5693 MakeGroups: forces the generation of new groups from existing ones
5696 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5697 Example: :ref:`tui_extrusion`
5700 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5702 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5703 ExtrFlags, SewTolerance, MakeGroups=False):
5705 Generate new elements by extrusion of the elements with given ids
5708 IDsOfElements: is ids of elements
5709 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5710 the direction and value of extrusion for one step (the total extrusion
5711 length will be NbOfSteps * ||StepVector||)
5712 NbOfSteps: the number of steps
5713 ExtrFlags: sets flags for extrusion
5714 SewTolerance: uses for comparing locations of nodes if flag
5715 EXTRUSION_FLAG_SEW is set
5716 MakeGroups: forces the generation of new groups from existing ones
5719 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5722 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5723 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5724 if isinstance( StepVector, list ):
5725 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5726 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5727 ExtrFlags, SewTolerance, MakeGroups)
5729 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5730 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5731 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5732 ScaleFactors=[], ScalesVariation=False):
5734 Generate new elements by extrusion of the given elements and nodes along the path.
5735 The path of extrusion must be a meshed edge.
5738 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5739 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5740 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5741 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5742 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
5743 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5744 HasAngles: not used obsolete
5745 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5746 around *basePoint*, additionally to previous steps.
5747 LinearVariation: forces the computation of rotation angles as linear
5748 variation of the given Angles along path steps
5749 HasRefPoint: allows using the reference point
5750 RefPoint: optional scaling and rotation center (mass center of the extruded
5751 elements by default). The User can specify any point as the Reference Point.
5752 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5753 MakeGroups: forces the generation of new groups from existing ones
5754 ScaleFactors: optional scale factors to apply during extrusion
5755 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5756 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5759 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5760 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5761 Example: :ref:`tui_extrusion_along_path`
5764 unRegister = genObjUnRegister()
5765 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5766 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5767 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5769 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5770 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5771 if isinstance( RefPoint, list ):
5772 if not RefPoint: RefPoint = [0,0,0]
5773 RefPoint = SMESH.PointStruct( *RefPoint )
5774 if isinstance( PathObject, Mesh ):
5775 PathObject = PathObject.GetMesh()
5776 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5777 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5778 Parameters = AnglesParameters + var_separator + \
5779 RefPoint.parameters + var_separator + ScalesParameters
5780 self.mesh.SetParameters(Parameters)
5781 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5782 PathObject, PathShape, NodeStart,
5783 HasAngles, Angles, LinearVariation,
5784 HasRefPoint, RefPoint, MakeGroups,
5785 ScaleFactors, ScalesVariation)
5787 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5788 HasAngles=False, Angles=[], LinearVariation=False,
5789 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5790 ElemType=SMESH.FACE):
5792 Generate new elements by extrusion of the given elements.
5793 The path of extrusion must be a meshed edge.
5796 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5797 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5798 NodeStart: the start node from Path. Defines the direction of extrusion
5799 HasAngles: not used obsolete
5800 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5801 around *basePoint*, additionally to previous steps.
5802 LinearVariation: forces the computation of rotation angles as linear
5803 variation of the given Angles along path steps
5804 HasRefPoint: allows using the reference point
5805 RefPoint: the reference point around which the elements are rotated (the mass
5806 center of the elements by default).
5807 The User can specify any point as the Reference Point.
5808 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5809 MakeGroups: forces the generation of new groups from existing ones
5810 ElemType: type of elements for extrusion (if param Base is a mesh)
5813 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5814 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5815 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5817 Example: :ref:`tui_extrusion_along_path`
5821 if ElemType == SMESH.NODE: n = Base
5822 if ElemType == SMESH.EDGE: e = Base
5823 if ElemType == SMESH.FACE: f = Base
5824 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5825 HasAngles, Angles, LinearVariation,
5826 HasRefPoint, RefPoint, MakeGroups)
5827 if MakeGroups: return gr,er
5830 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5831 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5832 MakeGroups=False, LinearVariation=False):
5834 Generate new elements by extrusion of the given elements.
5835 The path of extrusion must be a meshed edge.
5838 IDsOfElements: ids of elements
5839 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5840 PathShape: shape (edge) defines the sub-mesh for the path
5841 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5842 HasAngles: not used obsolete
5843 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5844 around *basePoint*, additionally to previous steps.
5845 HasRefPoint: allows using the reference point
5846 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5847 The User can specify any point as the Reference Point.
5848 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5849 MakeGroups: forces the generation of new groups from existing ones
5850 LinearVariation: forces the computation of rotation angles as linear
5851 variation of the given Angles along path steps
5854 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5855 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5856 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5857 Example: :ref:`tui_extrusion_along_path`
5860 if not IDsOfElements:
5861 IDsOfElements = [ self.GetMesh() ]
5862 n,e,f = [],IDsOfElements,IDsOfElements
5863 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5864 NodeStart, HasAngles, Angles,
5866 HasRefPoint, RefPoint, MakeGroups)
5867 if MakeGroups: return gr,er
5870 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5871 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5872 MakeGroups=False, LinearVariation=False):
5874 Generate new elements by extrusion of the elements which belong to the object.
5875 The path of extrusion must be a meshed edge.
5878 theObject: the object whose elements should be processed.
5879 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5880 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5881 PathShape: shape (edge) defines the sub-mesh for the path
5882 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5883 HasAngles: not used obsolete
5884 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5885 around *basePoint*, additionally to previous steps.
5886 HasRefPoint: allows using the reference point
5887 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5888 The User can specify any point as the Reference Point.
5889 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5890 MakeGroups: forces the generation of new groups from existing ones
5891 LinearVariation: forces the computation of rotation angles as linear
5892 variation of the given Angles along path steps
5895 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5896 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5897 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5898 Example: :ref:`tui_extrusion_along_path`
5901 n,e,f = [],theObject,theObject
5902 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5903 HasAngles, Angles, LinearVariation,
5904 HasRefPoint, RefPoint, MakeGroups)
5905 if MakeGroups: return gr,er
5908 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5909 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5910 MakeGroups=False, LinearVariation=False):
5912 Generate new elements by extrusion of mesh segments which belong to the object.
5913 The path of extrusion must be a meshed edge.
5916 theObject: the object whose 1D elements should be processed.
5917 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5918 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5919 PathShape: shape (edge) defines the sub-mesh for the path
5920 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5921 HasAngles: not used obsolete
5922 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5923 around *basePoint*, additionally to previous steps.
5924 HasRefPoint: allows using the reference point
5925 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5926 The User can specify any point as the Reference Point.
5927 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5928 MakeGroups: forces the generation of new groups from existing ones
5929 LinearVariation: forces the computation of rotation angles as linear
5930 variation of the given Angles along path steps
5933 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5934 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5935 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5936 Example: :ref:`tui_extrusion_along_path`
5939 n,e,f = [],theObject,[]
5940 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5941 HasAngles, Angles, LinearVariation,
5942 HasRefPoint, RefPoint, MakeGroups)
5943 if MakeGroups: return gr,er
5946 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5947 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5948 MakeGroups=False, LinearVariation=False):
5950 Generate new elements by extrusion of faces which belong to the object.
5951 The path of extrusion must be a meshed edge.
5954 theObject: the object whose 2D elements should be processed.
5955 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5956 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5957 PathShape: shape (edge) defines the sub-mesh for the path
5958 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5959 HasAngles: not used obsolete
5960 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5961 around *basePoint*, additionally to previous steps.
5962 HasRefPoint: allows using the reference point
5963 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5964 The User can specify any point as the Reference Point.
5965 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5966 MakeGroups: forces the generation of new groups from existing ones
5967 LinearVariation: forces the computation of rotation angles as linear
5968 variation of the given Angles along path steps
5971 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5972 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5973 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5974 Example: :ref:`tui_extrusion_along_path`
5977 n,e,f = [],[],theObject
5978 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5979 HasAngles, Angles, LinearVariation,
5980 HasRefPoint, RefPoint, MakeGroups)
5981 if MakeGroups: return gr,er
5984 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5986 Create a symmetrical copy of mesh elements
5989 IDsOfElements: list of elements ids
5990 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5991 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5992 If the *Mirror* is a geom object this parameter is unnecessary
5993 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5994 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5997 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6000 if IDsOfElements == []:
6001 IDsOfElements = self.GetElementsId()
6002 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6003 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6004 theMirrorType = Mirror._mirrorType
6006 self.mesh.SetParameters(Mirror.parameters)
6007 if Copy and MakeGroups:
6008 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6009 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6012 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6014 Create a new mesh by a symmetrical copy of mesh elements
6017 IDsOfElements: the list of elements ids
6018 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6019 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6020 If the *Mirror* is a geom object this parameter is unnecessary
6021 MakeGroups: to generate new groups from existing ones
6022 NewMeshName: a name of the new mesh to create
6025 instance of class :class:`Mesh`
6028 if IDsOfElements == []:
6029 IDsOfElements = self.GetElementsId()
6030 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6031 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6032 theMirrorType = Mirror._mirrorType
6034 self.mesh.SetParameters(Mirror.parameters)
6035 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6036 MakeGroups, NewMeshName)
6037 return Mesh(self.smeshpyD,self.geompyD,mesh)
6039 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6041 Create a symmetrical copy of the object
6044 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6045 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6046 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6047 If the *Mirror* is a geom object this parameter is unnecessary
6048 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6049 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6052 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6055 if ( isinstance( theObject, Mesh )):
6056 theObject = theObject.GetMesh()
6057 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6058 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6059 theMirrorType = Mirror._mirrorType
6061 self.mesh.SetParameters(Mirror.parameters)
6062 if Copy and MakeGroups:
6063 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6064 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6067 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6069 Create a new mesh by a symmetrical copy of the object
6072 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6073 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6074 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6075 If the *Mirror* is a geom object this parameter is unnecessary
6076 MakeGroups: forces the generation of new groups from existing ones
6077 NewMeshName: the name of the new mesh to create
6080 instance of class :class:`Mesh`
6083 if ( isinstance( theObject, Mesh )):
6084 theObject = theObject.GetMesh()
6085 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6086 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6087 theMirrorType = Mirror._mirrorType
6089 self.mesh.SetParameters(Mirror.parameters)
6090 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6091 MakeGroups, NewMeshName)
6092 return Mesh( self.smeshpyD,self.geompyD,mesh )
6094 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6096 Translate the elements
6099 IDsOfElements: list of elements ids
6100 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6101 Copy: allows copying the translated elements
6102 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6105 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6108 if IDsOfElements == []:
6109 IDsOfElements = self.GetElementsId()
6110 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6111 Vector = self.smeshpyD.GetDirStruct(Vector)
6112 if isinstance( Vector, list ):
6113 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6114 self.mesh.SetParameters(Vector.PS.parameters)
6115 if Copy and MakeGroups:
6116 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6117 self.editor.Translate(IDsOfElements, Vector, Copy)
6120 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6122 Create a new mesh of translated elements
6125 IDsOfElements: list of elements ids
6126 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6127 MakeGroups: forces the generation of new groups from existing ones
6128 NewMeshName: the name of the newly created mesh
6131 instance of class :class:`Mesh`
6134 if IDsOfElements == []:
6135 IDsOfElements = self.GetElementsId()
6136 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6137 Vector = self.smeshpyD.GetDirStruct(Vector)
6138 if isinstance( Vector, list ):
6139 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6140 self.mesh.SetParameters(Vector.PS.parameters)
6141 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6142 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6144 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6146 Translate the object
6149 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6150 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6151 Copy: allows copying the translated elements
6152 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6155 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6158 if ( isinstance( theObject, Mesh )):
6159 theObject = theObject.GetMesh()
6160 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6161 Vector = self.smeshpyD.GetDirStruct(Vector)
6162 if isinstance( Vector, list ):
6163 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6164 self.mesh.SetParameters(Vector.PS.parameters)
6165 if Copy and MakeGroups:
6166 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6167 self.editor.TranslateObject(theObject, Vector, Copy)
6170 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6172 Create a new mesh from the translated object
6175 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6176 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6177 MakeGroups: forces the generation of new groups from existing ones
6178 NewMeshName: the name of the newly created mesh
6181 instance of class :class:`Mesh`
6184 if isinstance( theObject, Mesh ):
6185 theObject = theObject.GetMesh()
6186 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6187 Vector = self.smeshpyD.GetDirStruct(Vector)
6188 if isinstance( Vector, list ):
6189 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6190 self.mesh.SetParameters(Vector.PS.parameters)
6191 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6192 return Mesh( self.smeshpyD, self.geompyD, mesh )
6196 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6201 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6202 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6203 theScaleFact: list of 1-3 scale factors for axises
6204 Copy: allows copying the translated elements
6205 MakeGroups: forces the generation of new groups from existing
6209 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6210 empty list otherwise
6212 unRegister = genObjUnRegister()
6213 if ( isinstance( theObject, Mesh )):
6214 theObject = theObject.GetMesh()
6215 if ( isinstance( theObject, list )):
6216 theObject = self.GetIDSource(theObject, SMESH.ALL)
6217 unRegister.set( theObject )
6218 if ( isinstance( thePoint, list )):
6219 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6220 if ( isinstance( theScaleFact, float )):
6221 theScaleFact = [theScaleFact]
6222 if ( isinstance( theScaleFact, int )):
6223 theScaleFact = [ float(theScaleFact)]
6225 self.mesh.SetParameters(thePoint.parameters)
6227 if Copy and MakeGroups:
6228 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6229 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6232 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6234 Create a new mesh from the translated object
6237 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6238 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6239 theScaleFact: list of 1-3 scale factors for axises
6240 MakeGroups: forces the generation of new groups from existing ones
6241 NewMeshName: the name of the newly created mesh
6244 instance of class :class:`Mesh`
6246 unRegister = genObjUnRegister()
6247 if (isinstance(theObject, Mesh)):
6248 theObject = theObject.GetMesh()
6249 if ( isinstance( theObject, list )):
6250 theObject = self.GetIDSource(theObject,SMESH.ALL)
6251 unRegister.set( theObject )
6252 if ( isinstance( thePoint, list )):
6253 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6254 if ( isinstance( theScaleFact, float )):
6255 theScaleFact = [theScaleFact]
6256 if ( isinstance( theScaleFact, int )):
6257 theScaleFact = [ float(theScaleFact)]
6259 self.mesh.SetParameters(thePoint.parameters)
6260 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6261 MakeGroups, NewMeshName)
6262 return Mesh( self.smeshpyD, self.geompyD, mesh )
6266 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6271 IDsOfElements: list of elements ids
6272 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6273 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6274 Copy: allows copying the rotated elements
6275 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6278 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6282 if IDsOfElements == []:
6283 IDsOfElements = self.GetElementsId()
6284 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6285 Axis = self.smeshpyD.GetAxisStruct(Axis)
6286 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6287 Parameters = Axis.parameters + var_separator + Parameters
6288 self.mesh.SetParameters(Parameters)
6289 if Copy and MakeGroups:
6290 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6291 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6294 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6296 Create a new mesh of rotated elements
6299 IDsOfElements: list of element ids
6300 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6301 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6302 MakeGroups: forces the generation of new groups from existing ones
6303 NewMeshName: the name of the newly created mesh
6306 instance of class :class:`Mesh`
6309 if IDsOfElements == []:
6310 IDsOfElements = self.GetElementsId()
6311 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6312 Axis = self.smeshpyD.GetAxisStruct(Axis)
6313 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6314 Parameters = Axis.parameters + var_separator + Parameters
6315 self.mesh.SetParameters(Parameters)
6316 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6317 MakeGroups, NewMeshName)
6318 return Mesh( self.smeshpyD, self.geompyD, mesh )
6320 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6325 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6326 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6327 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6328 Copy: allows copying the rotated elements
6329 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6332 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6335 if (isinstance(theObject, Mesh)):
6336 theObject = theObject.GetMesh()
6337 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6338 Axis = self.smeshpyD.GetAxisStruct(Axis)
6339 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6340 Parameters = Axis.parameters + ":" + Parameters
6341 self.mesh.SetParameters(Parameters)
6342 if Copy and MakeGroups:
6343 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6344 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6347 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6349 Create a new mesh from the rotated object
6352 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6353 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6354 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6355 MakeGroups: forces the generation of new groups from existing ones
6356 NewMeshName: the name of the newly created mesh
6359 instance of class :class:`Mesh`
6362 if (isinstance( theObject, Mesh )):
6363 theObject = theObject.GetMesh()
6364 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6365 Axis = self.smeshpyD.GetAxisStruct(Axis)
6366 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6367 Parameters = Axis.parameters + ":" + Parameters
6368 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6369 MakeGroups, NewMeshName)
6370 self.mesh.SetParameters(Parameters)
6371 return Mesh( self.smeshpyD, self.geompyD, mesh )
6373 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6375 Create an offset mesh from the given 2D object
6378 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6379 theValue (float): signed offset size
6380 MakeGroups (boolean): forces the generation of new groups from existing ones
6381 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6382 False means to remove original elements.
6383 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6386 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6389 if isinstance( theObject, Mesh ):
6390 theObject = theObject.GetMesh()
6391 theValue,Parameters,hasVars = ParseParameters(Value)
6392 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6393 self.mesh.SetParameters(Parameters)
6395 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6398 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6400 Find groups of adjacent nodes within Tolerance.
6403 Tolerance (float): the value of tolerance
6404 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6405 corner and medium nodes in separate groups thus preventing
6406 their further merge.
6409 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6412 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6414 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6415 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6417 Find groups of adjacent nodes within Tolerance.
6420 Tolerance: the value of tolerance
6421 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6422 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6423 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6424 corner and medium nodes in separate groups thus preventing
6425 their further merge.
6428 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6431 unRegister = genObjUnRegister()
6432 if not isinstance( SubMeshOrGroup, list ):
6433 SubMeshOrGroup = [ SubMeshOrGroup ]
6434 for i,obj in enumerate( SubMeshOrGroup ):
6435 if isinstance( obj, Mesh ):
6436 SubMeshOrGroup = [ obj.GetMesh() ]
6438 if isinstance( obj, int ):
6439 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6440 unRegister.set( SubMeshOrGroup )
6443 if not isinstance( exceptNodes, list ):
6444 exceptNodes = [ exceptNodes ]
6445 if exceptNodes and isinstance( exceptNodes[0], int ):
6446 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6447 unRegister.set( exceptNodes )
6449 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6450 exceptNodes, SeparateCornerAndMediumNodes)
6452 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6457 GroupsOfNodes: a list of groups of nodes IDs for merging.
6458 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6459 in all elements and mesh groups by nodes 1 and 25 correspondingly
6460 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6461 If *NodesToKeep* does not include a node to keep for some group to merge,
6462 then the first node in the group is kept.
6463 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6467 This operation can create gaps in numeration of nodes or elements.
6468 Call :meth:`RenumberElements` to remove the gaps.
6470 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6472 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6474 Find the elements built on the same nodes.
6477 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6478 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6482 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6485 unRegister = genObjUnRegister()
6486 if MeshOrSubMeshOrGroup is None:
6487 MeshOrSubMeshOrGroup = [ self.mesh ]
6488 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6489 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6490 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6491 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6492 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6493 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6494 unRegister.set( MeshOrSubMeshOrGroup )
6495 for item in MeshOrSubMeshOrGroup:
6496 if isinstance( item, Mesh ):
6497 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6499 if not isinstance( exceptElements, list ):
6500 exceptElements = [ exceptElements ]
6501 if exceptElements and isinstance( exceptElements[0], int ):
6502 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6503 unRegister.set( exceptElements )
6505 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6507 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6509 Merge elements in each given group.
6512 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6513 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6514 replaced in all mesh groups by elements 1 and 25)
6515 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6516 If *ElementsToKeep* does not include an element to keep for some group to merge,
6517 then the first element in the group is kept.
6520 This operation can create gaps in numeration of elements.
6521 Call :meth:`RenumberElements` to remove the gaps.
6524 unRegister = genObjUnRegister()
6526 if not isinstance( ElementsToKeep, list ):
6527 ElementsToKeep = [ ElementsToKeep ]
6528 if isinstance( ElementsToKeep[0], int ):
6529 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6530 unRegister.set( ElementsToKeep )
6532 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6534 def MergeEqualElements(self):
6536 Leave one element and remove all other elements built on the same nodes.
6539 This operation can create gaps in numeration of elements.
6540 Call :meth:`RenumberElements` to remove the gaps.
6543 self.editor.MergeEqualElements()
6545 def FindFreeBorders(self, ClosedOnly=True):
6547 Returns all or only closed free borders
6550 list of SMESH.FreeBorder's
6553 return self.editor.FindFreeBorders( ClosedOnly )
6555 def FillHole(self, holeNodes, groupName=""):
6557 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6560 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6561 must describe all sequential nodes of the hole border. The first and the last
6562 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6563 groupName (string): name of a group to add new faces
6565 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6569 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6570 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6571 if not isinstance( holeNodes, SMESH.FreeBorder ):
6572 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6573 return self.editor.FillHole( holeNodes, groupName )
6575 def FindCoincidentFreeBorders (self, tolerance=0.):
6577 Return groups of FreeBorder's coincident within the given tolerance.
6580 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6581 size of elements adjacent to free borders being compared is used.
6584 SMESH.CoincidentFreeBorders structure
6587 return self.editor.FindCoincidentFreeBorders( tolerance )
6589 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6591 Sew FreeBorder's of each group
6594 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6595 where each enclosed list contains node IDs of a group of coincident free
6596 borders such that each consequent triple of IDs within a group describes
6597 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6598 last node of a border.
6599 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6600 groups of coincident free borders, each group including two borders.
6601 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6602 polygons if a node of opposite border falls on a face edge, else such
6603 faces are split into several ones.
6604 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6605 polyhedra if a node of opposite border falls on a volume edge, else such
6606 volumes, if any, remain intact and the mesh becomes non-conformal.
6609 a number of successfully sewed groups
6612 This operation can create gaps in numeration of nodes or elements.
6613 Call :meth:`RenumberElements` to remove the gaps.
6616 if freeBorders and isinstance( freeBorders, list ):
6617 # construct SMESH.CoincidentFreeBorders
6618 if isinstance( freeBorders[0], int ):
6619 freeBorders = [freeBorders]
6621 coincidentGroups = []
6622 for nodeList in freeBorders:
6623 if not nodeList or len( nodeList ) % 3:
6624 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6627 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6628 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6629 nodeList = nodeList[3:]
6631 coincidentGroups.append( group )
6633 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6635 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6637 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6638 FirstNodeID2, SecondNodeID2, LastNodeID2,
6639 CreatePolygons, CreatePolyedrs):
6644 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6647 This operation can create gaps in numeration of nodes or elements.
6648 Call :meth:`RenumberElements` to remove the gaps.
6651 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6652 FirstNodeID2, SecondNodeID2, LastNodeID2,
6653 CreatePolygons, CreatePolyedrs)
6655 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6656 FirstNodeID2, SecondNodeID2):
6658 Sew conform free borders
6661 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6664 This operation can create gaps in numeration of elements.
6665 Call :meth:`RenumberElements` to remove the gaps.
6668 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6669 FirstNodeID2, SecondNodeID2)
6671 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6672 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6677 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6680 This operation can create gaps in numeration of elements.
6681 Call :meth:`RenumberElements` to remove the gaps.
6684 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6685 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6687 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6688 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6689 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6691 Sew two sides of a mesh. The nodes belonging to Side1 are
6692 merged with the nodes of elements of Side2.
6693 The number of elements in theSide1 and in theSide2 must be
6694 equal and they should have similar nodal connectivity.
6695 The nodes to merge should belong to side borders and
6696 the first node should be linked to the second.
6699 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6702 This operation can create gaps in numeration of nodes.
6703 Call :meth:`RenumberElements` to remove the gaps.
6706 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6707 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6708 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6710 def ChangeElemNodes(self, ide, newIDs):
6712 Set new nodes for the given element. Number of nodes should be kept.
6719 False if the number of nodes does not correspond to the type of element
6722 return self.editor.ChangeElemNodes(ide, newIDs)
6724 def GetLastCreatedNodes(self):
6726 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6727 created, this method return the list of their IDs.
6728 If new nodes were not created - return empty list
6731 the list of integer values (can be empty)
6734 return self.editor.GetLastCreatedNodes()
6736 def GetLastCreatedElems(self):
6738 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6739 created this method return the list of their IDs.
6740 If new elements were not created - return empty list
6743 the list of integer values (can be empty)
6746 return self.editor.GetLastCreatedElems()
6748 def ClearLastCreated(self):
6750 Forget what nodes and elements were created by the last mesh edition operation
6753 self.editor.ClearLastCreated()
6755 def DoubleElements(self, theElements, theGroupName=""):
6757 Create duplicates of given elements, i.e. create new elements based on the
6758 same nodes as the given ones.
6761 theElements: container of elements to duplicate. It can be a
6762 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6763 or a list of element IDs. If *theElements* is
6764 a :class:`Mesh`, elements of highest dimension are duplicated
6765 theGroupName: a name of group to contain the generated elements.
6766 If a group with such a name already exists, the new elements
6767 are added to the existing group, else a new group is created.
6768 If *theGroupName* is empty, new elements are not added
6772 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6773 None if *theGroupName* == "".
6776 unRegister = genObjUnRegister()
6777 if isinstance( theElements, Mesh ):
6778 theElements = theElements.mesh
6779 elif isinstance( theElements, list ):
6780 theElements = self.GetIDSource( theElements, SMESH.ALL )
6781 unRegister.set( theElements )
6782 return self.editor.DoubleElements(theElements, theGroupName)
6784 def DoubleNodes(self, theNodes, theModifiedElems):
6786 Create a hole in a mesh by doubling the nodes of some particular elements
6789 theNodes: IDs of nodes to be doubled
6790 theModifiedElems: IDs of elements to be updated by the new (doubled)
6791 nodes. If list of element identifiers is empty then nodes are doubled but
6792 they not assigned to elements
6795 True if operation has been completed successfully, False otherwise
6798 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6800 def DoubleNode(self, theNodeId, theModifiedElems):
6802 Create a hole in a mesh by doubling the nodes of some particular elements.
6803 This method provided for convenience works as :meth:`DoubleNodes`.
6806 theNodeId: IDs of node to double
6807 theModifiedElems: IDs of elements to update
6810 True if operation has been completed successfully, False otherwise
6813 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6815 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6817 Create a hole in a mesh by doubling the nodes of some particular elements.
6818 This method provided for convenience works as :meth:`DoubleNodes`.
6821 theNodes: group of nodes to double.
6822 theModifiedElems: group of elements to update.
6823 theMakeGroup: forces the generation of a group containing new nodes.
6826 True or a created group if operation has been completed successfully,
6827 False or None otherwise
6831 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6832 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6834 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6836 Create a hole in a mesh by doubling the nodes of some particular elements.
6837 This method provided for convenience works as :meth:`DoubleNodes`.
6840 theNodes: list of groups of nodes to double.
6841 theModifiedElems: list of groups of elements to update.
6842 theMakeGroup: forces the generation of a group containing new nodes.
6845 True if operation has been completed successfully, False otherwise
6849 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6850 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6852 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6854 Create a hole in a mesh by doubling the nodes of some particular elements
6857 theElems: the list of elements (edges or faces) to replicate.
6858 The nodes for duplication could be found from these elements
6859 theNodesNot: list of nodes NOT to replicate
6860 theAffectedElems: the list of elements (cells and edges) to which the
6861 replicated nodes should be associated to
6864 True if operation has been completed successfully, False otherwise
6867 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6869 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6871 Create a hole in a mesh by doubling the nodes of some particular elements
6874 theElems: the list of elements (edges or faces) to replicate.
6875 The nodes for duplication could be found from these elements
6876 theNodesNot: list of nodes NOT to replicate
6877 theShape: shape to detect affected elements (element which geometric center
6878 located on or inside shape).
6879 The replicated nodes should be associated to affected elements.
6882 True if operation has been completed successfully, False otherwise
6885 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6887 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6888 theMakeGroup=False, theMakeNodeGroup=False):
6890 Create a hole in a mesh by doubling the nodes of some particular elements.
6891 This method provided for convenience works as :meth:`DoubleNodes`.
6894 theElems: group of of elements (edges or faces) to replicate.
6895 theNodesNot: group of nodes NOT to replicate.
6896 theAffectedElems: group of elements to which the replicated nodes
6897 should be associated to.
6898 theMakeGroup: forces the generation of a group containing new elements.
6899 theMakeNodeGroup: forces the generation of a group containing new nodes.
6902 True or created groups (one or two) if operation has been completed successfully,
6903 False or None otherwise
6906 if theMakeGroup or theMakeNodeGroup:
6907 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6909 theMakeGroup, theMakeNodeGroup)
6910 if theMakeGroup and theMakeNodeGroup:
6913 return twoGroups[ int(theMakeNodeGroup) ]
6914 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6916 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6918 Create a hole in a mesh by doubling the nodes of some particular elements.
6919 This method provided for convenience works as :meth:`DoubleNodes`.
6922 theElems: group of of elements (edges or faces) to replicate
6923 theNodesNot: group of nodes not to replicate
6924 theShape: shape to detect affected elements (element which geometric center
6925 located on or inside shape).
6926 The replicated nodes should be associated to affected elements
6929 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6931 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6932 theMakeGroup=False, theMakeNodeGroup=False):
6934 Create a hole in a mesh by doubling the nodes of some particular elements.
6935 This method provided for convenience works as :meth:`DoubleNodes`.
6938 theElems: list of groups of elements (edges or faces) to replicate
6939 theNodesNot: list of groups of nodes NOT to replicate
6940 theAffectedElems: group of elements to which the replicated nodes
6941 should be associated to
6942 theMakeGroup: forces generation of a group containing new elements.
6943 theMakeNodeGroup: forces generation of a group containing new nodes
6946 True or created groups (one or two) if operation has been completed successfully,
6947 False or None otherwise
6950 if theMakeGroup or theMakeNodeGroup:
6951 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6953 theMakeGroup, theMakeNodeGroup)
6954 if theMakeGroup and theMakeNodeGroup:
6957 return twoGroups[ int(theMakeNodeGroup) ]
6958 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6960 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6962 Create a hole in a mesh by doubling the nodes of some particular elements.
6963 This method provided for convenience works as :meth:`DoubleNodes`.
6966 theElems: list of groups of elements (edges or faces) to replicate
6967 theNodesNot: list of groups of nodes NOT to replicate
6968 theShape: shape to detect affected elements (element which geometric center
6969 located on or inside shape).
6970 The replicated nodes should be associated to affected elements
6973 True if operation has been completed successfully, False otherwise
6976 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6978 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6980 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6981 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6984 theElems: list of groups of nodes or elements (edges or faces) to replicate
6985 theNodesNot: list of groups of nodes NOT to replicate
6986 theShape: shape to detect affected elements (element which geometric center
6987 located on or inside shape).
6988 The replicated nodes should be associated to affected elements
6991 groups of affected elements in order: volumes, faces, edges
6994 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6996 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6999 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7000 The list of groups must describe a partition of the mesh volumes.
7001 The nodes of the internal faces at the boundaries of the groups are doubled.
7002 In option, the internal faces are replaced by flat elements.
7003 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7006 theDomains: list of groups of volumes
7007 createJointElems: if True, create the elements
7008 onAllBoundaries: if True, the nodes and elements are also created on
7009 the boundary between *theDomains* and the rest mesh
7012 True if operation has been completed successfully, False otherwise
7015 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7017 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7019 Double nodes on some external faces and create flat elements.
7020 Flat elements are mainly used by some types of mechanic calculations.
7022 Each group of the list must be constituted of faces.
7023 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7026 theGroupsOfFaces: list of groups of faces
7029 True if operation has been completed successfully, False otherwise
7032 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7034 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7036 Identify all the elements around a geom shape, get the faces delimiting the hole
7038 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7040 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7042 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7043 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7044 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7045 If there are several paths connecting a pair of points, the shortest path is
7046 selected by the module. Position of the cutting plane is defined by the two
7047 points and an optional vector lying on the plane specified by a PolySegment.
7048 By default the vector is defined by Mesh module as following. A middle point
7049 of the two given points is computed. The middle point is projected to the mesh.
7050 The vector goes from the middle point to the projection point. In case of planar
7051 mesh, the vector is normal to the mesh.
7053 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7056 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7057 groupName: optional name of a group where created mesh segments will be added.
7060 editor = self.editor
7062 editor = self.mesh.GetMeshEditPreviewer()
7063 segmentsRes = editor.MakePolyLine( segments, groupName )
7064 for i, seg in enumerate( segmentsRes ):
7065 segments[i].vector = seg.vector
7067 return editor.GetPreviewData()
7070 def MakeSlot(self, segmentGroup, width ):
7072 Create a slot of given width around given 1D elements lying on a triangle mesh.
7073 The slot is constructed by cutting faces by cylindrical surfaces made
7074 around each segment. Segments are expected to be created by MakePolyLine().
7077 FaceEdge's located at the slot boundary
7079 return self.editor.MakeSlot( segmentGroup, width )
7081 def GetFunctor(self, funcType ):
7083 Return a cached numerical functor by its type.
7086 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7087 Note that not all items correspond to numerical functors.
7090 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7093 fn = self.functors[ funcType._v ]
7095 fn = self.smeshpyD.GetFunctor(funcType)
7096 fn.SetMesh(self.mesh)
7097 self.functors[ funcType._v ] = fn
7100 def FunctorValue(self, funcType, elemId, isElem=True):
7102 Return value of a functor for a given element
7105 funcType: an item of :class:`SMESH.FunctorType` enum.
7106 elemId: element or node ID
7107 isElem: *elemId* is ID of element or node
7110 the functor value or zero in case of invalid arguments
7113 fn = self.GetFunctor( funcType )
7114 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7115 val = fn.GetValue(elemId)
7120 def GetLength(self, elemId=None):
7122 Get length of given 1D elements or of all 1D mesh elements
7125 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.
7128 Sum of lengths of given elements
7133 length = self.smeshpyD.GetLength(self)
7134 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7135 length = self.smeshpyD.GetLength(elemId)
7138 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7140 length += self.smeshpyD.GetLength(obj)
7141 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7142 unRegister = genObjUnRegister()
7143 obj = self.GetIDSource( elemId )
7144 unRegister.set( obj )
7145 length = self.smeshpyD.GetLength( obj )
7147 length = self.FunctorValue(SMESH.FT_Length, elemId)
7150 def GetArea(self, elemId=None):
7152 Get area of given 2D elements or of all 2D mesh elements
7155 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.
7158 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7163 area = self.smeshpyD.GetArea(self)
7164 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7165 area = self.smeshpyD.GetArea(elemId)
7168 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7170 area += self.smeshpyD.GetArea(obj)
7171 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7172 unRegister = genObjUnRegister()
7173 obj = self.GetIDSource( elemId )
7174 unRegister.set( obj )
7175 area = self.smeshpyD.GetArea( obj )
7177 area = self.FunctorValue(SMESH.FT_Area, elemId)
7180 def GetVolume(self, elemId=None):
7182 Get volume of given 3D elements or of all 3D mesh elements
7185 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.
7188 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7193 volume= self.smeshpyD.GetVolume(self)
7194 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7195 volume= self.smeshpyD.GetVolume(elemId)
7198 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7200 volume+= self.smeshpyD.GetVolume(obj)
7201 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7202 unRegister = genObjUnRegister()
7203 obj = self.GetIDSource( elemId )
7204 unRegister.set( obj )
7205 volume= self.smeshpyD.GetVolume( obj )
7207 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7210 def GetAngle(self, node1, node2, node3 ):
7212 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7215 node1,node2,node3: IDs of the three nodes
7218 Angle in radians [0,PI]. -1 if failure case.
7220 p1 = self.GetNodeXYZ( node1 )
7221 p2 = self.GetNodeXYZ( node2 )
7222 p3 = self.GetNodeXYZ( node3 )
7223 if p1 and p2 and p3:
7224 return self.smeshpyD.GetAngle( p1,p2,p3 )
7228 def GetMaxElementLength(self, elemId):
7230 Get maximum element length.
7233 elemId: mesh element ID
7236 element's maximum length value
7239 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7240 ftype = SMESH.FT_MaxElementLength3D
7242 ftype = SMESH.FT_MaxElementLength2D
7243 return self.FunctorValue(ftype, elemId)
7245 def GetAspectRatio(self, elemId):
7247 Get aspect ratio of 2D or 3D element.
7250 elemId: mesh element ID
7253 element's aspect ratio value
7256 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7257 ftype = SMESH.FT_AspectRatio3D
7259 ftype = SMESH.FT_AspectRatio
7260 return self.FunctorValue(ftype, elemId)
7262 def GetWarping(self, elemId):
7264 Get warping angle of 2D element.
7267 elemId: mesh element ID
7270 element's warping angle value
7273 return self.FunctorValue(SMESH.FT_Warping, elemId)
7275 def GetMinimumAngle(self, elemId):
7277 Get minimum angle of 2D element.
7280 elemId: mesh element ID
7283 element's minimum angle value
7286 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7288 def GetTaper(self, elemId):
7290 Get taper of 2D element.
7293 elemId: mesh element ID
7296 element's taper value
7299 return self.FunctorValue(SMESH.FT_Taper, elemId)
7301 def GetSkew(self, elemId):
7303 Get skew of 2D element.
7306 elemId: mesh element ID
7309 element's skew value
7312 return self.FunctorValue(SMESH.FT_Skew, elemId)
7314 def GetMinMax(self, funType, meshPart=None):
7316 Return minimal and maximal value of a given functor.
7319 funType (SMESH.FunctorType): a functor type.
7320 Note that not all items of :class:`SMESH.FunctorType` corresponds
7321 to numerical functors.
7322 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7328 unRegister = genObjUnRegister()
7329 if isinstance( meshPart, list ):
7330 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7331 unRegister.set( meshPart )
7332 if isinstance( meshPart, Mesh ):
7333 meshPart = meshPart.mesh
7334 fun = self.GetFunctor( funType )
7337 if hasattr( meshPart, "SetMesh" ):
7338 meshPart.SetMesh( self.mesh ) # set mesh to filter
7339 hist = fun.GetLocalHistogram( 1, False, meshPart )
7341 hist = fun.GetHistogram( 1, False )
7343 return hist[0].min, hist[0].max
7346 pass # end of Mesh class
7349 class meshProxy(SMESH._objref_SMESH_Mesh):
7351 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7352 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7354 def __init__(self,*args):
7355 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7356 def __deepcopy__(self, memo=None):
7357 new = self.__class__(self)
7359 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7360 if len( args ) == 3:
7361 args += SMESH.ALL_NODES, True
7362 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7363 def ExportToMEDX(self, *args): # function removed
7364 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7365 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7366 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7367 def ExportToMED(self, *args): # function removed
7368 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7369 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7371 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7373 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7374 def ExportPartToMED(self, *args): # 'version' parameter removed
7375 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7376 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7377 def ExportMED(self, *args): # signature of method changed
7378 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7380 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7382 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7384 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7387 class submeshProxy(SMESH._objref_SMESH_subMesh):
7390 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7392 def __init__(self,*args):
7393 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7395 def __deepcopy__(self, memo=None):
7396 new = self.__class__(self)
7399 def Compute(self,refresh=False):
7401 Compute the sub-mesh and return the status of the computation
7404 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7409 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7410 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7414 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7416 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7418 if salome.sg.hasDesktop():
7419 if refresh: salome.sg.updateObjBrowser()
7424 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7427 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7429 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7430 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7433 def __init__(self,*args):
7434 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7436 def __getattr__(self, name ): # method called if an attribute not found
7437 if not self.mesh: # look for name() method in Mesh class
7438 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7439 if hasattr( self.mesh, name ):
7440 return getattr( self.mesh, name )
7441 if name == "ExtrusionAlongPathObjX":
7442 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7443 print("meshEditor: attribute '%s' NOT FOUND" % name)
7445 def __deepcopy__(self, memo=None):
7446 new = self.__class__(self)
7448 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7449 if len( args ) == 1: args += False,
7450 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7451 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7452 if len( args ) == 2: args += False,
7453 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7454 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7455 if len( args ) == 1:
7456 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7457 NodesToKeep = args[1]
7458 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7459 unRegister = genObjUnRegister()
7461 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7462 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7463 if not isinstance( NodesToKeep, list ):
7464 NodesToKeep = [ NodesToKeep ]
7465 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7467 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7469 class Pattern(SMESH._objref_SMESH_Pattern):
7471 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7472 variables in some methods
7475 def LoadFromFile(self, patternTextOrFile ):
7476 text = patternTextOrFile
7477 if os.path.exists( text ):
7478 text = open( patternTextOrFile ).read()
7480 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7482 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7483 decrFun = lambda i: i-1
7484 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7485 theMesh.SetParameters(Parameters)
7486 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7488 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7489 decrFun = lambda i: i-1
7490 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7491 theMesh.SetParameters(Parameters)
7492 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7494 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7495 if isinstance( mesh, Mesh ):
7496 mesh = mesh.GetMesh()
7497 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7499 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7501 Registering the new proxy for Pattern
7506 Private class used to bind methods creating algorithms to the class Mesh
7509 def __init__(self, method):
7511 self.defaultAlgoType = ""
7512 self.algoTypeToClass = {}
7513 self.method = method
7515 def add(self, algoClass):
7517 Store a python class of algorithm
7519 if inspect.isclass(algoClass) and \
7520 hasattr( algoClass, "algoType"):
7521 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7522 if not self.defaultAlgoType and \
7523 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7524 self.defaultAlgoType = algoClass.algoType
7525 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7527 def copy(self, mesh):
7529 Create a copy of self and assign mesh to the copy
7532 other = algoCreator( self.method )
7533 other.defaultAlgoType = self.defaultAlgoType
7534 other.algoTypeToClass = self.algoTypeToClass
7538 def __call__(self,algo="",geom=0,*args):
7540 Create an instance of algorithm
7544 if isinstance( algo, str ):
7546 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7547 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7552 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7554 elif not algoType and isinstance( geom, str ):
7559 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7561 elif isinstance( arg, str ) and not algoType:
7564 import traceback, sys
7565 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7566 sys.stderr.write( msg + '\n' )
7567 tb = traceback.extract_stack(None,2)
7568 traceback.print_list( [tb[0]] )
7570 algoType = self.defaultAlgoType
7571 if not algoType and self.algoTypeToClass:
7572 algoType = sorted( self.algoTypeToClass.keys() )[0]
7573 if algoType in self.algoTypeToClass:
7574 #print("Create algo",algoType)
7575 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7576 raise RuntimeError( "No class found for algo type %s" % algoType)
7579 class hypMethodWrapper:
7581 Private class used to substitute and store variable parameters of hypotheses.
7584 def __init__(self, hyp, method):
7586 self.method = method
7587 #print("REBIND:", method.__name__)
7590 def __call__(self,*args):
7592 call a method of hypothesis with calling SetVarParameter() before
7596 return self.method( self.hyp, *args ) # hypothesis method with no args
7598 #print("MethWrapper.__call__", self.method.__name__, args)
7600 parsed = ParseParameters(*args) # replace variables with their values
7601 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7602 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7603 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7604 # maybe there is a replaced string arg which is not variable
7605 result = self.method( self.hyp, *args )
7606 except ValueError as detail: # raised by ParseParameters()
7608 result = self.method( self.hyp, *args )
7609 except omniORB.CORBA.BAD_PARAM:
7610 raise ValueError(detail) # wrong variable name
7615 class genObjUnRegister:
7617 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7620 def __init__(self, genObj=None):
7621 self.genObjList = []
7625 def set(self, genObj):
7626 "Store one or a list of of SALOME.GenericObj'es"
7627 if isinstance( genObj, list ):
7628 self.genObjList.extend( genObj )
7630 self.genObjList.append( genObj )
7634 for genObj in self.genObjList:
7635 if genObj and hasattr( genObj, "UnRegister" ):
7638 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7640 Bind methods creating mesher plug-ins to the Mesh class
7643 # print("pluginName: ", pluginName)
7644 pluginBuilderName = pluginName + "Builder"
7646 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7647 except Exception as e:
7648 from salome_utils import verbose
7649 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7651 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7652 plugin = eval( pluginBuilderName )
7653 # print(" plugin:" , str(plugin))
7655 # add methods creating algorithms to Mesh
7656 for k in dir( plugin ):
7657 if k[0] == '_': continue
7658 algo = getattr( plugin, k )
7659 #print(" algo:", str(algo))
7660 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7661 #print(" meshMethod:" , str(algo.meshMethod))
7662 if not hasattr( Mesh, algo.meshMethod ):
7663 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7665 _mmethod = getattr( Mesh, algo.meshMethod )
7666 if hasattr( _mmethod, "add" ):