1 # Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 # File : smeshBuilder.py
20 # Author : Francis KLOSS, OCC
24 from salome.geom import geomBuilder
26 import SMESH # This is necessary for back compatibility
27 import omniORB # back compatibility
28 SMESH.MED_V2_1 = 11 #omniORB.EnumItem("MED_V2_1", 11) # back compatibility: use number > MED minor version
29 SMESH.MED_V2_2 = 12 #omniORB.EnumItem("MED_V2_2", 12) # back compatibility: latest minor will be used
30 SMESH.MED_MINOR_0 = 20 # back compatibility
31 SMESH.MED_MINOR_1 = 21 # back compatibility
32 SMESH.MED_MINOR_2 = 22 # back compatibility
33 SMESH.MED_MINOR_3 = 23 # back compatibility
34 SMESH.MED_MINOR_4 = 24 # back compatibility
35 SMESH.MED_MINOR_5 = 25 # back compatibility
36 SMESH.MED_MINOR_6 = 26 # back compatibility
37 SMESH.MED_MINOR_7 = 27 # back compatibility
38 SMESH.MED_MINOR_8 = 28 # back compatibility
39 SMESH.MED_MINOR_9 = 29 # back compatibility
42 from salome.smesh.smesh_algorithm import Mesh_Algorithm
43 from StdMeshers import BlockCS
50 # In case the omniORBpy EnumItem class does not fully support Python 3
51 # (for instance in version 4.2.1-2), the comparison ordering methods must be
55 SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
57 def enumitem_eq(self, other):
59 if isinstance(other, omniORB.EnumItem):
60 if other._parent_id == self._parent_id:
61 return self._v == other._v
63 return self._parent_id == other._parent_id
65 return id(self) == id(other)
67 return id(self) == id(other)
69 def enumitem_lt(self, other):
71 if isinstance(other, omniORB.EnumItem):
72 if other._parent_id == self._parent_id:
73 return self._v < other._v
75 return self._parent_id < other._parent_id
77 return id(self) < id(other)
79 return id(self) < id(other)
81 def enumitem_le(self, other):
83 if isinstance(other, omniORB.EnumItem):
84 if other._parent_id == self._parent_id:
85 return self._v <= other._v
87 return self._parent_id <= other._parent_id
89 return id(self) <= id(other)
91 return id(self) <= id(other)
93 def enumitem_gt(self, other):
95 if isinstance(other, omniORB.EnumItem):
96 if other._parent_id == self._parent_id:
97 return self._v > other._v
99 return self._parent_id > other._parent_id
101 return id(self) > id(other)
103 return id(self) > id(other)
105 def enumitem_ge(self, other):
107 if isinstance(other, omniORB.EnumItem):
108 if other._parent_id == self._parent_id:
109 return self._v >= other._v
111 return self._parent_id >= other._parent_id
113 return id(self) >= id(other)
115 return id(self) >= id(other)
117 omniORB.EnumItem.__eq__ = enumitem_eq
118 omniORB.EnumItem.__lt__ = enumitem_lt
119 omniORB.EnumItem.__le__ = enumitem_le
120 omniORB.EnumItem.__gt__ = enumitem_gt
121 omniORB.EnumItem.__ge__ = enumitem_ge
124 class MeshMeta(type):
125 """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
127 def __instancecheck__(cls, inst):
128 """Implement isinstance(inst, cls)."""
129 return any(cls.__subclasscheck__(c)
130 for c in {type(inst), inst.__class__})
132 def __subclasscheck__(cls, sub):
133 """Implement issubclass(sub, cls)."""
134 return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
136 def DegreesToRadians(AngleInDegrees):
137 """Convert an angle from degrees to radians
140 return AngleInDegrees * pi / 180.0
142 import salome_notebook
143 notebook = salome_notebook.notebook
144 # Salome notebook variable separator
147 def ParseParameters(*args):
149 Return list of variable values from salome notebook.
150 The last argument, if is callable, is used to modify values got from notebook
156 if args and callable(args[-1]):
157 args, varModifFun = args[:-1], args[-1]
158 for parameter in args:
160 Parameters += str(parameter) + var_separator
162 if isinstance(parameter,str):
163 # check if there is an inexistent variable name
164 if not notebook.isVariable(parameter):
165 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
166 parameter = notebook.get(parameter)
169 parameter = varModifFun(parameter)
172 Result.append(parameter)
175 Parameters = Parameters[:-1]
176 Result.append( Parameters )
177 Result.append( hasVariables )
180 def ParseAngles(*args):
182 Parse parameters while converting variables to radians
184 return ParseParameters( *( args + (DegreesToRadians, )))
186 def __initPointStruct(point,*args):
188 Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
189 Parameters are stored in PointStruct.parameters attribute
191 point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
193 SMESH.PointStruct.__init__ = __initPointStruct
195 def __initAxisStruct(ax,*args):
197 Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
198 Parameters are stored in AxisStruct.parameters attribute
201 raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
202 ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
204 SMESH.AxisStruct.__init__ = __initAxisStruct
206 smeshPrecisionConfusion = 1.e-07
207 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
208 """Compare real values using smeshPrecisionConfusion as tolerance
210 if abs(val1 - val2) < tol:
218 Return a name of an object
225 if isinstance(obj, SALOMEDS._objref_SObject):
229 ior = salome.orb.object_to_string(obj)
233 sobj = salome.myStudy.FindObjectIOR(ior)
235 return sobj.GetName()
236 if hasattr(obj, "GetName"):
237 # unknown CORBA object, having GetName() method
240 # unknown CORBA object, no GetName() method
243 if hasattr(obj, "GetName"):
244 # unknown non-CORBA object, having GetName() method
247 raise RuntimeError("Null or invalid object")
249 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
251 Print error message if a hypothesis was not assigned.
254 hypType = "algorithm"
256 hypType = "hypothesis"
259 if hasattr( status, "__getitem__" ):
260 status, reason = status[0], status[1]
261 if status == HYP_UNKNOWN_FATAL:
262 reason = "for unknown reason"
263 elif status == HYP_INCOMPATIBLE:
264 reason = "this hypothesis mismatches the algorithm"
265 elif status == HYP_NOTCONFORM:
266 reason = "a non-conform mesh would be built"
267 elif status == HYP_ALREADY_EXIST:
268 if isAlgo: return # it does not influence anything
269 reason = hypType + " of the same dimension is already assigned to this shape"
270 elif status == HYP_BAD_DIM:
271 reason = hypType + " mismatches the shape"
272 elif status == HYP_CONCURRENT :
273 reason = "there are concurrent hypotheses on sub-shapes"
274 elif status == HYP_BAD_SUBSHAPE:
275 reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
276 elif status == HYP_BAD_GEOMETRY:
277 reason = "the algorithm is not applicable to this geometry"
278 elif status == HYP_HIDDEN_ALGO:
279 reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
280 elif status == HYP_HIDING_ALGO:
281 reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
282 elif status == HYP_NEED_SHAPE:
283 reason = "algorithm can't work without shape"
284 elif status == HYP_INCOMPAT_HYPS:
290 where = '"%s"' % geomName
292 meshName = GetName( mesh )
293 if meshName and meshName != NO_NAME:
294 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
295 if status < HYP_UNKNOWN_FATAL and where:
296 print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
298 print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
300 print('"%s" was not assigned : %s' %( hypName, reason ))
303 def AssureGeomPublished(mesh, geom, name=''):
305 Private method. Add geom (sub-shape of the main shape) into the study if not yet there
307 if not mesh.smeshpyD.IsEnablePublish():
309 if not hasattr( geom, "GetShapeType" ):
311 if not geom.GetStudyEntry():
313 if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
314 # for all groups SubShapeName() return "Compound_-1"
315 name = mesh.geompyD.SubShapeName(geom, mesh.geom)
317 name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
319 mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
322 # def FirstVertexOnCurve(mesh, edge):
325 # the first vertex of a geometrical edge by ignoring orientation
327 # return mesh.geompyD.GetVertexByIndex( edge, 0, False )
333 smeshInst is a singleton
339 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
341 This class allows to create, load or manipulate meshes.
342 It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
343 It also has methods to get infos and measure meshes.
346 # MirrorType enumeration
347 POINT = SMESH_MeshEditor.POINT
348 AXIS = SMESH_MeshEditor.AXIS
349 PLANE = SMESH_MeshEditor.PLANE
351 # Smooth_Method enumeration
352 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
353 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
355 PrecisionConfusion = smeshPrecisionConfusion
357 # TopAbs_State enumeration
358 [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
360 # Methods of splitting a hexahedron into tetrahedra
361 Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
363 def __new__(cls, *args):
367 #print("==== __new__", engine, smeshInst, doLcc)
369 if smeshInst is None:
370 # smesh engine is either retrieved from engine, or created
372 # Following test avoids a recursive loop
374 if smeshInst is not None:
375 # smesh engine not created: existing engine found
379 # FindOrLoadComponent called:
380 # 1. CORBA resolution of server
381 # 2. the __new__ method is called again
382 #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
383 smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
385 # FindOrLoadComponent not called
386 if smeshInst is None:
387 # smeshBuilder instance is created from lcc.FindOrLoadComponent
388 #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
389 smeshInst = super(smeshBuilder,cls).__new__(cls)
391 # smesh engine not created: existing engine found
392 #print("==== existing ", engine, smeshInst, doLcc)
394 #print("====1 ", smeshInst)
397 #print("====2 ", smeshInst)
400 def __init__(self, *args):
402 #print("--------------- smeshbuilder __init__ ---", created)
405 SMESH._objref_SMESH_Gen.__init__(self, *args)
408 def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
410 Dump component to the Python script.
411 This method overrides IDL function to allow default values for the parameters.
414 return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
416 def SetDumpPythonHistorical(self, isHistorical):
418 Set mode of DumpPython(), *historical* or *snapshot*.
419 In the *historical* mode, the Python Dump script includes all commands
420 performed by SMESH engine. In the *snapshot* mode, commands
421 relating to objects removed from the Study are excluded from the script
422 as well as commands not influencing the current state of meshes
425 if isHistorical: val = "true"
427 SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
429 def init_smesh(self,geompyD = None):
431 Set Geometry component
434 self.UpdateStudy(geompyD)
435 notebook.myStudy = salome.myStudy
437 def Mesh(self, obj=0, name=0):
439 Create a mesh. This mesh can be either
441 * an empty mesh not bound to geometry, if *obj* == 0
442 * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
443 * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
448 1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
451 salome.myStudy.FindObjectID("0:1:2:3").GetObject()
453 2. a geometrical object for meshing
455 name: the name for the new mesh.
458 an instance of class :class:`Mesh`.
461 if isinstance(obj,str):
463 return Mesh(self, self.geompyD, obj, name)
465 def RemoveMesh( self, mesh ):
469 if isinstance( mesh, Mesh ):
470 mesh = mesh.GetMesh()
472 if not isinstance( mesh, SMESH._objref_SMESH_Mesh ):
473 raise TypeError("%s is not a mesh" % mesh )
474 so = salome.ObjectToSObject( mesh )
476 sb = salome.myStudy.NewBuilder()
477 sb.RemoveObjectWithChildren( so )
483 def EnumToLong(self,theItem):
485 Return a long value from enumeration
490 def ColorToString(self,c):
492 Convert SALOMEDS.Color to string.
493 To be used with filters.
496 c: color value (SALOMEDS.Color)
499 a string representation of the color.
503 if isinstance(c, SALOMEDS.Color):
504 val = "%s;%s;%s" % (c.R, c.G, c.B)
505 elif isinstance(c, str):
508 raise ValueError("Color value should be of string or SALOMEDS.Color type")
511 def GetPointStruct(self,theVertex):
513 Get :class:`SMESH.PointStruct` from vertex
516 theVertex (GEOM.GEOM_Object): vertex
519 :class:`SMESH.PointStruct`
521 geompyD = theVertex.GetGen()
522 [x, y, z] = geompyD.PointCoordinates(theVertex)
523 return PointStruct(x,y,z)
525 def GetDirStruct(self,theVector):
527 Get :class:`SMESH.DirStruct` from vector
530 theVector (GEOM.GEOM_Object): vector
533 :class:`SMESH.DirStruct`
535 geompyD = theVector.GetGen()
536 vertices = geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
537 if(len(vertices) != 2):
538 print("Error: vector object is incorrect.")
540 p1 = geompyD.PointCoordinates(vertices[0])
541 p2 = geompyD.PointCoordinates(vertices[1])
542 pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
543 dirst = DirStruct(pnt)
546 def MakeDirStruct(self,x,y,z):
548 Make :class:`SMESH.DirStruct` from a triplet of floats
551 x,y,z (float): vector components
554 :class:`SMESH.DirStruct`
557 pnt = PointStruct(x,y,z)
558 return DirStruct(pnt)
560 def GetAxisStruct(self,theObj):
562 Get :class:`SMESH.AxisStruct` from a geometrical object
565 theObj (GEOM.GEOM_Object): line or plane
568 :class:`SMESH.AxisStruct`
571 geompyD = theObj.GetGen()
572 edges = geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
575 vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
576 vertex3, vertex4 = geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
577 vertex1 = geompyD.PointCoordinates(vertex1)
578 vertex2 = geompyD.PointCoordinates(vertex2)
579 vertex3 = geompyD.PointCoordinates(vertex3)
580 vertex4 = geompyD.PointCoordinates(vertex4)
581 v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
582 v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
583 normal = [ v1[1]*v2[2]-v2[1]*v1[2], v1[2]*v2[0]-v2[2]*v1[0], v1[0]*v2[1]-v2[0]*v1[1] ]
584 axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
585 axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
586 elif len(edges) == 1:
587 vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
588 p1 = geompyD.PointCoordinates( vertex1 )
589 p2 = geompyD.PointCoordinates( vertex2 )
590 axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
591 axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
592 elif theObj.GetShapeType() == GEOM.VERTEX:
593 x,y,z = geompyD.PointCoordinates( theObj )
594 axis = AxisStruct( x,y,z, 1,0,0,)
595 axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
598 # From SMESH_Gen interface:
599 # ------------------------
601 def SetName(self, obj, name):
603 Set the given name to an object
606 obj: the object to rename
607 name: a new object name
610 if isinstance( obj, Mesh ):
612 elif isinstance( obj, Mesh_Algorithm ):
613 obj = obj.GetAlgorithm()
614 ior = salome.orb.object_to_string(obj)
615 SMESH._objref_SMESH_Gen.SetName(self, ior, name)
617 def SetEmbeddedMode( self,theMode ):
622 SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
624 def IsEmbeddedMode(self):
629 return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
631 def UpdateStudy( self, geompyD = None ):
633 Update the current study. Calling UpdateStudy() allows to
634 update meshes at switching GEOM->SMESH
638 from salome.geom import geomBuilder
639 geompyD = geomBuilder.geom
641 geompyD = geomBuilder.New()
644 self.SetGeomEngine(geompyD)
645 SMESH._objref_SMESH_Gen.UpdateStudy(self)
646 sb = salome.myStudy.NewBuilder()
647 sc = salome.myStudy.FindComponent("SMESH")
649 sb.LoadWith(sc, self)
652 def SetEnablePublish( self, theIsEnablePublish ):
654 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
655 switch **off** publishing in the Study of mesh objects.
657 #self.SetEnablePublish(theIsEnablePublish)
658 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
660 notebook = salome_notebook.NoteBook( theIsEnablePublish )
663 def CreateMeshesFromUNV( self,theFileName ):
665 Create a Mesh object importing data from the given UNV file
668 an instance of class :class:`Mesh`
671 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
672 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
675 def CreateMeshesFromMED( self,theFileName ):
677 Create a Mesh object(s) importing data from the given MED file
680 a tuple ( list of class :class:`Mesh` instances,
681 :class:`SMESH.DriverMED_ReadStatus` )
684 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
685 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
686 return aMeshes, aStatus
688 def CreateMeshesFromSAUV( self,theFileName ):
690 Create a Mesh object(s) importing data from the given SAUV file
693 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
696 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
697 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
698 return aMeshes, aStatus
700 def CreateMeshesFromSTL( self, theFileName ):
702 Create a Mesh object importing data from the given STL file
705 an instance of class :class:`Mesh`
708 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
709 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
712 def CreateMeshesFromCGNS( self, theFileName ):
714 Create Mesh objects importing data from the given CGNS file
717 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
720 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
721 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
722 return aMeshes, aStatus
724 def CreateMeshesFromGMF( self, theFileName ):
726 Create a Mesh object importing data from the given GMF file.
727 GMF files must have .mesh extension for the ASCII format and .meshb for
731 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
734 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
737 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
738 return Mesh(self, self.geompyD, aSmeshMesh), error
740 def Concatenate( self, meshes, uniteIdenticalGroups,
741 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
742 name = "", meshToAppendTo = None):
744 Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
745 All groups of input meshes will be present in the new mesh.
748 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
749 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
750 mergeNodesAndElements: if True, equal nodes and elements are merged
751 mergeTolerance: tolerance for merging nodes
752 allGroups: forces creation of groups corresponding to every input mesh
753 name: name of a new mesh
754 meshToAppendTo: a mesh to append all given meshes
757 an instance of class :class:`Mesh`
763 if not meshes: return None
764 if not isinstance( meshes, list ):
766 for i,m in enumerate( meshes ):
767 if isinstance( m, Mesh ):
768 meshes[i] = m.GetMesh()
769 mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
770 if hasattr(meshes[0], "SetParameters"):
771 meshes[0].SetParameters( Parameters )
773 meshes[0].GetMesh().SetParameters( Parameters )
774 if isinstance( meshToAppendTo, Mesh ):
775 meshToAppendTo = meshToAppendTo.GetMesh()
777 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
778 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
779 mergeTolerance,meshToAppendTo )
781 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
782 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
783 mergeTolerance,meshToAppendTo )
785 aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
788 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
790 Create a mesh by copying a part of another mesh.
793 meshPart: a part of mesh to copy, either
794 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
795 To copy nodes or elements not forming any mesh object,
796 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
797 meshName: a name of the new mesh
798 toCopyGroups: to create in the new mesh groups the copied elements belongs to
799 toKeepIDs: to preserve order of the copied elements or not
802 an instance of class :class:`Mesh`
805 if isinstance( meshPart, Mesh ):
806 meshPart = meshPart.GetMesh()
807 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
808 return Mesh(self, self.geompyD, mesh)
810 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
811 toReuseHypotheses=True, toCopyElements=True):
813 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
814 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
815 To facilitate and speed up the operation, consider using
816 "Set presentation parameters and sub-shapes from arguments" option in
817 a dialog of geometrical operation used to create the new geometry.
820 sourceMesh: the mesh to copy definition of.
821 newGeom: the new geometry.
822 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
823 toCopyGroups: to create groups in the new mesh.
824 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
825 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
828 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
829 *invalidEntries* are study entries of objects whose
830 counterparts are not found in the *newGeom*, followed by entries
831 of mesh sub-objects that are invalid because they depend on a not found
834 if isinstance( sourceMesh, Mesh ):
835 sourceMesh = sourceMesh.GetMesh()
837 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
838 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
842 return ( ok, Mesh(self, self.geompyD, newMesh),
843 newGroups, newSubMeshes, newHypotheses, invalidEntries )
845 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
847 Return IDs of sub-shapes
850 theMainObject (GEOM.GEOM_Object): a shape
851 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
853 the list of integer values
856 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
858 def GetPattern(self):
860 Create a pattern mapper.
863 an instance of :class:`SMESH.SMESH_Pattern`
865 :ref:`Example of Patterns usage <tui_pattern_mapping>`
868 return SMESH._objref_SMESH_Gen.GetPattern(self)
870 def SetBoundaryBoxSegmentation(self, nbSegments):
872 Set number of segments per diagonal of boundary box of geometry, by which
873 default segment length of appropriate 1D hypotheses is defined in GUI.
877 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
879 # Filtering. Auxiliary functions:
880 # ------------------------------
882 def GetEmptyCriterion(self):
884 Create an empty criterion
887 :class:`SMESH.Filter.Criterion`
890 Type = self.EnumToLong(FT_Undefined)
891 Compare = self.EnumToLong(FT_Undefined)
895 UnaryOp = self.EnumToLong(FT_Undefined)
896 BinaryOp = self.EnumToLong(FT_Undefined)
899 Precision = -1 ##@1e-07
900 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
901 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
903 def GetCriterion(self,elementType,
905 Compare = FT_EqualTo,
907 UnaryOp=FT_Undefined,
908 BinaryOp=FT_Undefined,
911 Create a criterion by the given parameters
912 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
915 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
916 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
917 Note that the items starting from FT_LessThan are not suitable for *CritType*.
918 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
919 Threshold: the threshold value (range of ids as string, shape, numeric)
920 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
921 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
923 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
924 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
927 :class:`SMESH.Filter.Criterion`
929 Example: :ref:`combining_filters`
932 if not CritType in SMESH.FunctorType._items:
933 raise TypeError("CritType should be of SMESH.FunctorType")
934 aCriterion = self.GetEmptyCriterion()
935 aCriterion.TypeOfElement = elementType
936 aCriterion.Type = self.EnumToLong(CritType)
937 aCriterion.Tolerance = Tolerance
939 aThreshold = Threshold
941 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
942 aCriterion.Compare = self.EnumToLong(Compare)
943 elif Compare == "=" or Compare == "==":
944 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
946 aCriterion.Compare = self.EnumToLong(FT_LessThan)
948 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
949 elif Compare != FT_Undefined:
950 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
953 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
954 FT_BelongToCylinder, FT_LyingOnGeom]:
955 # Check that Threshold is GEOM object
956 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
957 aCriterion.ThresholdStr = GetName(aThreshold)
958 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
959 if not aCriterion.ThresholdID:
960 name = aCriterion.ThresholdStr
962 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
963 geompyD = aThreshold.GetGen()
964 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
965 # or a name of GEOM object
966 elif isinstance( aThreshold, str ):
967 aCriterion.ThresholdStr = aThreshold
969 raise TypeError("The Threshold should be a shape.")
970 if isinstance(UnaryOp,float):
971 aCriterion.Tolerance = UnaryOp
972 UnaryOp = FT_Undefined
974 elif CritType == FT_BelongToMeshGroup:
975 # Check that Threshold is a group
976 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
977 if aThreshold.GetType() != elementType:
978 raise ValueError("Group type mismatches Element type")
979 aCriterion.ThresholdStr = aThreshold.GetName()
980 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
981 study = salome.myStudy
983 so = study.FindObjectIOR( aCriterion.ThresholdID )
987 aCriterion.ThresholdID = entry
989 raise TypeError("The Threshold should be a Mesh Group")
990 elif CritType == FT_RangeOfIds:
991 # Check that Threshold is string
992 if isinstance(aThreshold, str):
993 aCriterion.ThresholdStr = aThreshold
995 raise TypeError("The Threshold should be a string.")
996 elif CritType == FT_CoplanarFaces:
997 # Check the Threshold
998 if isinstance(aThreshold, int):
999 aCriterion.ThresholdID = str(aThreshold)
1000 elif isinstance(aThreshold, str):
1001 ID = int(aThreshold)
1003 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
1004 aCriterion.ThresholdID = aThreshold
1006 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1007 elif CritType == FT_ConnectedElements:
1008 # Check the Threshold
1009 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1010 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1011 if not aCriterion.ThresholdID:
1012 name = aThreshold.GetName()
1014 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1015 geompyD = aThreshold.GetGen()
1016 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
1017 elif isinstance(aThreshold, int): # node id
1018 aCriterion.Threshold = aThreshold
1019 elif isinstance(aThreshold, list): # 3 point coordinates
1020 if len( aThreshold ) < 3:
1021 raise ValueError("too few point coordinates, must be 3")
1022 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1023 elif isinstance(aThreshold, str):
1024 if aThreshold.isdigit():
1025 aCriterion.Threshold = aThreshold # node id
1027 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1029 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1030 "or a list of point coordinates and not '%s'"%aThreshold)
1031 elif CritType == FT_ElemGeomType:
1032 # Check the Threshold
1034 aCriterion.Threshold = self.EnumToLong(aThreshold)
1035 assert( aThreshold in SMESH.GeometryType._items )
1037 if isinstance(aThreshold, int):
1038 aCriterion.Threshold = aThreshold
1040 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1043 elif CritType == FT_EntityType:
1044 # Check the Threshold
1046 aCriterion.Threshold = self.EnumToLong(aThreshold)
1047 assert( aThreshold in SMESH.EntityType._items )
1049 if isinstance(aThreshold, int):
1050 aCriterion.Threshold = aThreshold
1052 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1056 elif CritType == FT_GroupColor:
1057 # Check the Threshold
1059 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1061 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1063 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1064 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1065 FT_BareBorderFace, FT_BareBorderVolume,
1066 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1067 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1068 # At this point the Threshold is unnecessary
1069 if aThreshold == FT_LogicalNOT:
1070 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1071 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1072 aCriterion.BinaryOp = aThreshold
1076 aThreshold = float(aThreshold)
1077 aCriterion.Threshold = aThreshold
1079 raise TypeError("The Threshold should be a number.")
1082 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1083 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1085 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1086 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1088 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1089 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1091 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1092 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1096 def GetFilter(self,elementType,
1097 CritType=FT_Undefined,
1100 UnaryOp=FT_Undefined,
1104 Create a filter with the given parameters
1107 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1108 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1109 Note that the items starting from FT_LessThan are not suitable for CritType.
1110 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1111 Threshold: the threshold value (range of ids as string, shape, numeric)
1112 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1113 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1114 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1115 mesh: the mesh to initialize the filter with
1118 :class:`SMESH.Filter`
1121 See :doc:`Filters usage examples <tui_filters>`
1124 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1125 aFilterMgr = self.CreateFilterManager()
1126 aFilter = aFilterMgr.CreateFilter()
1128 aCriteria.append(aCriterion)
1129 aFilter.SetCriteria(aCriteria)
1131 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1132 else : aFilter.SetMesh( mesh )
1133 aFilterMgr.UnRegister()
1136 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1138 Create a filter from criteria
1141 criteria: a list of :class:`SMESH.Filter.Criterion`
1142 binOp: binary operator used when binary operator of criteria is undefined
1145 :class:`SMESH.Filter`
1148 See :doc:`Filters usage examples <tui_filters>`
1151 for i in range( len( criteria ) - 1 ):
1152 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1153 criteria[i].BinaryOp = self.EnumToLong( binOp )
1154 aFilterMgr = self.CreateFilterManager()
1155 aFilter = aFilterMgr.CreateFilter()
1156 aFilter.SetCriteria(criteria)
1157 aFilterMgr.UnRegister()
1160 def GetFunctor(self,theCriterion):
1162 Create a numerical functor by its type
1165 theCriterion (SMESH.FunctorType): functor type.
1166 Note that not all items correspond to numerical functors.
1169 :class:`SMESH.NumericalFunctor`
1172 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1174 aFilterMgr = self.CreateFilterManager()
1176 if theCriterion == FT_AspectRatio:
1177 functor = aFilterMgr.CreateAspectRatio()
1178 elif theCriterion == FT_AspectRatio3D:
1179 functor = aFilterMgr.CreateAspectRatio3D()
1180 elif theCriterion == FT_Warping:
1181 functor = aFilterMgr.CreateWarping()
1182 elif theCriterion == FT_MinimumAngle:
1183 functor = aFilterMgr.CreateMinimumAngle()
1184 elif theCriterion == FT_Taper:
1185 functor = aFilterMgr.CreateTaper()
1186 elif theCriterion == FT_Skew:
1187 functor = aFilterMgr.CreateSkew()
1188 elif theCriterion == FT_Area:
1189 functor = aFilterMgr.CreateArea()
1190 elif theCriterion == FT_Volume3D:
1191 functor = aFilterMgr.CreateVolume3D()
1192 elif theCriterion == FT_MaxElementLength2D:
1193 functor = aFilterMgr.CreateMaxElementLength2D()
1194 elif theCriterion == FT_MaxElementLength3D:
1195 functor = aFilterMgr.CreateMaxElementLength3D()
1196 elif theCriterion == FT_MultiConnection:
1197 functor = aFilterMgr.CreateMultiConnection()
1198 elif theCriterion == FT_MultiConnection2D:
1199 functor = aFilterMgr.CreateMultiConnection2D()
1200 elif theCriterion == FT_Length:
1201 functor = aFilterMgr.CreateLength()
1202 elif theCriterion == FT_Length2D:
1203 functor = aFilterMgr.CreateLength2D()
1204 elif theCriterion == FT_Length3D:
1205 functor = aFilterMgr.CreateLength3D()
1206 elif theCriterion == FT_Deflection2D:
1207 functor = aFilterMgr.CreateDeflection2D()
1208 elif theCriterion == FT_NodeConnectivityNumber:
1209 functor = aFilterMgr.CreateNodeConnectivityNumber()
1210 elif theCriterion == FT_BallDiameter:
1211 functor = aFilterMgr.CreateBallDiameter()
1213 print("Error: given parameter is not numerical functor type.")
1214 aFilterMgr.UnRegister()
1217 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1222 theHType (string): mesh hypothesis type
1223 theLibName (string): mesh plug-in library name
1226 created hypothesis instance
1228 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1230 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1233 # wrap hypothesis methods
1234 for meth_name in dir( hyp.__class__ ):
1235 if not meth_name.startswith("Get") and \
1236 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1237 method = getattr ( hyp.__class__, meth_name )
1238 if callable(method):
1239 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1243 def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1245 Create hypothesis initialized according to parameters
1248 hypType (string): hypothesis type
1249 libName (string): plug-in library name
1250 mesh: optional mesh by which a hypotheses can initialize self
1251 shape: optional geometry by size of which a hypotheses can initialize self
1252 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1255 created hypothesis instance
1257 if isinstance( mesh, Mesh ):
1258 mesh = mesh.GetMesh()
1259 if isinstance( initParams, (bool,int)):
1260 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1261 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1262 mesh, shape, initParams )
1264 def GetMeshInfo(self, obj):
1266 Get the mesh statistic.
1269 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1272 if isinstance( obj, Mesh ):
1275 if hasattr(obj, "GetMeshInfo"):
1276 values = obj.GetMeshInfo()
1277 for i in range(SMESH.Entity_Last._v):
1278 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1282 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1284 Get minimum distance between two objects
1286 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1287 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1290 src1 (SMESH.SMESH_IDSource): first source object
1291 src2 (SMESH.SMESH_IDSource): second source object
1292 id1 (int): node/element id from the first source
1293 id2 (int): node/element id from the second (or first) source
1294 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1295 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1298 minimum distance value
1301 :meth:`GetMinDistance`
1304 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1308 result = result.value
1311 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1313 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1315 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1316 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1319 src1 (SMESH.SMESH_IDSource): first source object
1320 src2 (SMESH.SMESH_IDSource): second source object
1321 id1 (int): node/element id from the first source
1322 id2 (int): node/element id from the second (or first) source
1323 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1324 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1327 :class:`SMESH.Measure` structure or None if input data is invalid
1332 if isinstance(src1, Mesh): src1 = src1.mesh
1333 if isinstance(src2, Mesh): src2 = src2.mesh
1334 if src2 is None and id2 != 0: src2 = src1
1335 if not hasattr(src1, "_narrow"): return None
1336 src1 = src1._narrow(SMESH.SMESH_IDSource)
1337 if not src1: return None
1338 unRegister = genObjUnRegister()
1341 e = m.GetMeshEditor()
1343 src1 = e.MakeIDSource([id1], SMESH.FACE)
1345 src1 = e.MakeIDSource([id1], SMESH.NODE)
1346 unRegister.set( src1 )
1348 if hasattr(src2, "_narrow"):
1349 src2 = src2._narrow(SMESH.SMESH_IDSource)
1350 if src2 and id2 != 0:
1352 e = m.GetMeshEditor()
1354 src2 = e.MakeIDSource([id2], SMESH.FACE)
1356 src2 = e.MakeIDSource([id2], SMESH.NODE)
1357 unRegister.set( src2 )
1360 aMeasurements = self.CreateMeasurements()
1361 unRegister.set( aMeasurements )
1362 result = aMeasurements.MinDistance(src1, src2)
1365 def BoundingBox(self, objects):
1367 Get bounding box of the specified object(s)
1370 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1373 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1376 :meth:`GetBoundingBox`
1379 result = self.GetBoundingBox(objects)
1383 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1386 def GetBoundingBox(self, objects):
1388 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1391 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1394 :class:`SMESH.Measure` structure
1400 if isinstance(objects, tuple):
1401 objects = list(objects)
1402 if not isinstance(objects, list):
1406 if isinstance(o, Mesh):
1407 srclist.append(o.mesh)
1408 elif hasattr(o, "_narrow"):
1409 src = o._narrow(SMESH.SMESH_IDSource)
1410 if src: srclist.append(src)
1413 aMeasurements = self.CreateMeasurements()
1414 result = aMeasurements.BoundingBox(srclist)
1415 aMeasurements.UnRegister()
1418 def GetLength(self, obj):
1420 Get sum of lengths of all 1D elements in the mesh object.
1423 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1426 sum of lengths of all 1D elements
1429 if isinstance(obj, Mesh): obj = obj.mesh
1430 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1431 aMeasurements = self.CreateMeasurements()
1432 value = aMeasurements.Length(obj)
1433 aMeasurements.UnRegister()
1436 def GetArea(self, obj):
1438 Get sum of areas of all 2D elements in the mesh object.
1441 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1444 sum of areas of all 2D elements
1447 if isinstance(obj, Mesh): obj = obj.mesh
1448 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1449 aMeasurements = self.CreateMeasurements()
1450 value = aMeasurements.Area(obj)
1451 aMeasurements.UnRegister()
1454 def GetVolume(self, obj):
1456 Get sum of volumes of all 3D elements in the mesh object.
1459 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1462 sum of volumes of all 3D elements
1465 if isinstance(obj, Mesh): obj = obj.mesh
1466 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1467 aMeasurements = self.CreateMeasurements()
1468 value = aMeasurements.Volume(obj)
1469 aMeasurements.UnRegister()
1472 def GetGravityCenter(self, obj):
1474 Get gravity center of all nodes of a mesh object.
1477 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1480 Three components of the gravity center (x,y,z)
1483 :meth:`Mesh.BaryCenter`
1485 if isinstance(obj, Mesh): obj = obj.mesh
1486 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1487 aMeasurements = self.CreateMeasurements()
1488 pointStruct = aMeasurements.GravityCenter(obj)
1489 aMeasurements.UnRegister()
1490 return pointStruct.x, pointStruct.y, pointStruct.z
1492 def GetAngle(self, p1, p2, p3 ):
1494 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1497 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1503 if isinstance( p1, list ): p1 = PointStruct(*p1)
1504 if isinstance( p2, list ): p2 = PointStruct(*p2)
1505 if isinstance( p3, list ): p3 = PointStruct(*p3)
1507 aMeasurements = self.CreateMeasurements()
1508 angle = aMeasurements.Angle(p1,p2,p3)
1509 aMeasurements.UnRegister()
1514 pass # end of class smeshBuilder
1517 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1518 """Registering the new proxy for SMESH.SMESH_Gen"""
1521 def New( instance=None, instanceGeom=None):
1523 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1524 interface to create or load meshes.
1529 salome.salome_init()
1530 from salome.smesh import smeshBuilder
1531 smesh = smeshBuilder.New()
1534 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1535 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1537 :class:`smeshBuilder` instance
1542 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1544 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1549 smeshInst = smeshBuilder()
1550 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1551 smeshInst.init_smesh(instanceGeom)
1555 # Public class: Mesh
1556 # ==================
1559 class Mesh(metaclass = MeshMeta):
1561 This class allows defining and managing a mesh.
1562 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1563 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1564 new nodes and elements and by changing the existing entities), to get information
1565 about a mesh and to export a mesh in different formats.
1572 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1577 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1578 sets the GUI name of this mesh to *name*.
1581 smeshpyD: an instance of smeshBuilder class
1582 geompyD: an instance of geomBuilder class
1583 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1584 name: Study name of the mesh
1587 self.smeshpyD = smeshpyD
1588 self.geompyD = geompyD
1593 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1596 # publish geom of mesh (issue 0021122)
1597 if not self.geom.GetStudyEntry():
1601 geo_name = name + " shape"
1603 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1604 geompyD.addToStudy( self.geom, geo_name )
1605 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1607 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1610 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1612 self.smeshpyD.SetName(self.mesh, name)
1614 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1617 self.geom = self.mesh.GetShapeToMesh()
1619 self.editor = self.mesh.GetMeshEditor()
1620 self.functors = [None] * SMESH.FT_Undefined._v
1622 # set self to algoCreator's
1623 for attrName in dir(self):
1624 attr = getattr( self, attrName )
1625 if isinstance( attr, algoCreator ):
1626 setattr( self, attrName, attr.copy( self ))
1633 Destructor. Clean-up resources
1636 #self.mesh.UnRegister()
1640 def SetMesh(self, theMesh):
1642 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1645 theMesh: a :class:`SMESH.SMESH_Mesh` object
1647 # do not call Register() as this prevents mesh servant deletion at closing study
1648 #if self.mesh: self.mesh.UnRegister()
1651 #self.mesh.Register()
1652 self.geom = self.mesh.GetShapeToMesh()
1656 if salome.sg.hasDesktop():
1657 so = salome.ObjectToSObject( self.geom )
1658 comp = so.GetFatherComponent()
1659 if comp.ComponentDataType() == "SHAPERSTUDY":
1660 import shaperBuilder
1661 self.geompyD = shaperBuilder.New()
1664 if not self.geompyD:
1665 self.geompyD = self.geom.GetGen()
1670 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1673 a :class:`SMESH.SMESH_Mesh` object
1678 def GetEngine(self):
1680 Return a smeshBuilder instance created this mesh
1682 return self.smeshpyD
1684 def GetGeomEngine(self):
1686 Return a geomBuilder instance
1692 Get the name of the mesh
1695 the name of the mesh as a string
1698 name = GetName(self.GetMesh())
1701 def SetName(self, name):
1703 Set a name to the mesh
1706 name: a new name of the mesh
1709 self.smeshpyD.SetName(self.GetMesh(), name)
1711 def GetSubMesh(self, geom, name):
1713 Get a sub-mesh object associated to a *geom* geometrical object.
1716 geom: a geometrical object (shape)
1717 name: a name for the sub-mesh in the Object Browser
1720 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1721 which lies on the given shape
1724 A sub-mesh is implicitly created when a sub-shape is specified at
1725 creating an algorithm, for example::
1727 algo1D = mesh.Segment(geom=Edge_1)
1729 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1730 The created sub-mesh can be retrieved from the algorithm::
1732 submesh = algo1D.GetSubMesh()
1735 AssureGeomPublished( self, geom, name )
1736 submesh = self.mesh.GetSubMesh( geom, name )
1741 Return the shape associated to the mesh
1749 def SetShape(self, geom):
1751 Associate the given shape to the mesh (entails the recreation of the mesh)
1754 geom: the shape to be meshed (GEOM_Object)
1757 self.mesh = self.smeshpyD.CreateMesh(geom)
1759 def HasShapeToMesh(self):
1761 Return ``True`` if this mesh is based on geometry
1763 return self.mesh.HasShapeToMesh()
1767 Load mesh from the study after opening the study
1771 def IsReadyToCompute(self, theSubObject):
1773 Return true if the hypotheses are defined well
1776 theSubObject: a sub-shape of a mesh shape
1782 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1784 def GetAlgoState(self, theSubObject):
1786 Return errors of hypotheses definition.
1787 The list of errors is empty if everything is OK.
1790 theSubObject: a sub-shape of a mesh shape
1796 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1798 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1800 Return a geometrical object on which the given element was built.
1801 The returned geometrical object, if not nil, is either found in the
1802 study or published by this method with the given name
1805 theElementID: the id of the mesh element
1806 theGeomName: the user-defined name of the geometrical object
1809 GEOM.GEOM_Object instance
1812 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1814 def MeshDimension(self):
1816 Return the mesh dimension depending on the dimension of the underlying shape
1817 or, if the mesh is not based on any shape, basing on deimension of elements
1820 mesh dimension as an integer value [0,3]
1823 if self.mesh.HasShapeToMesh():
1824 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1825 if len( shells ) > 0 :
1827 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1829 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1834 if self.NbVolumes() > 0: return 3
1835 if self.NbFaces() > 0: return 2
1836 if self.NbEdges() > 0: return 1
1839 def Evaluate(self, geom=0):
1841 Evaluate size of prospective mesh on a shape
1844 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1845 To know predicted number of e.g. edges, inquire it this way::
1847 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1850 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1852 geom = self.mesh.GetShapeToMesh()
1855 return self.smeshpyD.Evaluate(self.mesh, geom)
1858 def Compute(self, geom=0, discardModifs=False, refresh=False):
1860 Compute the mesh and return the status of the computation
1863 geom: geomtrical shape on which mesh data should be computed
1864 discardModifs: if True and the mesh has been edited since
1865 a last total re-compute and that may prevent successful partial re-compute,
1866 then the mesh is cleaned before Compute()
1867 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1873 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1874 geom = self.mesh.GetShapeToMesh()
1877 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1879 ok = self.smeshpyD.Compute(self.mesh, geom)
1880 except SALOME.SALOME_Exception as ex:
1881 print("Mesh computation failed, exception caught:")
1882 print(" ", ex.details.text)
1885 print("Mesh computation failed, exception caught:")
1886 traceback.print_exc()
1890 # Treat compute errors
1891 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1893 for err in computeErrors:
1894 if self.mesh.HasShapeToMesh():
1895 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1897 stdErrors = ["OK", #COMPERR_OK
1898 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1899 "std::exception", #COMPERR_STD_EXCEPTION
1900 "OCC exception", #COMPERR_OCC_EXCEPTION
1901 "..", #COMPERR_SLM_EXCEPTION
1902 "Unknown exception", #COMPERR_EXCEPTION
1903 "Memory allocation problem", #COMPERR_MEMORY_PB
1904 "Algorithm failed", #COMPERR_ALGO_FAILED
1905 "Unexpected geometry", #COMPERR_BAD_SHAPE
1906 "Warning", #COMPERR_WARNING
1907 "Computation cancelled",#COMPERR_CANCELED
1908 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1910 if err.code < len(stdErrors): errText = stdErrors[err.code]
1912 errText = "code %s" % -err.code
1913 if errText: errText += ". "
1914 errText += err.comment
1915 if allReasons: allReasons += "\n"
1917 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1919 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1923 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1925 if err.isGlobalAlgo:
1933 reason = '%s %sD algorithm is missing' % (glob, dim)
1934 elif err.state == HYP_MISSING:
1935 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1936 % (glob, dim, name, dim))
1937 elif err.state == HYP_NOTCONFORM:
1938 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1939 elif err.state == HYP_BAD_PARAMETER:
1940 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1941 % ( glob, dim, name ))
1942 elif err.state == HYP_BAD_GEOMETRY:
1943 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1944 'geometry' % ( glob, dim, name ))
1945 elif err.state == HYP_HIDDEN_ALGO:
1946 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1947 'algorithm of upper dimension generating %sD mesh'
1948 % ( glob, dim, name, glob, dim ))
1950 reason = ("For unknown reason. "
1951 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1953 if allReasons: allReasons += "\n"
1954 allReasons += "- " + reason
1956 if not ok or allReasons != "":
1957 msg = '"' + GetName(self.mesh) + '"'
1958 if ok: msg += " has been computed with warnings"
1959 else: msg += " has not been computed"
1960 if allReasons != "": msg += ":"
1966 if salome.sg.hasDesktop():
1967 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1968 if refresh: salome.sg.updateObjBrowser()
1972 def GetComputeErrors(self, shape=0 ):
1974 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1978 shape = self.mesh.GetShapeToMesh()
1979 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1981 def GetSubShapeName(self, subShapeID ):
1983 Return a name of a sub-shape by its ID.
1984 Possible variants (for *subShapeID* == 3):
1986 - **"Face_12"** - published sub-shape
1987 - **FACE #3** - not published sub-shape
1988 - **sub-shape #3** - invalid sub-shape ID
1989 - **#3** - error in this function
1992 subShapeID: a unique ID of a sub-shape
1995 a string describing the sub-shape
1999 if not self.mesh.HasShapeToMesh():
2003 mainIOR = salome.orb.object_to_string( self.GetShape() )
2005 mainSO = s.FindObjectIOR(mainIOR)
2008 shapeText = '"%s"' % mainSO.GetName()
2009 subIt = s.NewChildIterator(mainSO)
2011 subSO = subIt.Value()
2013 obj = subSO.GetObject()
2014 if not obj: continue
2015 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2018 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2021 if ids == subShapeID:
2022 shapeText = '"%s"' % subSO.GetName()
2025 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2027 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2029 shapeText = 'sub-shape #%s' % (subShapeID)
2031 shapeText = "#%s" % (subShapeID)
2034 def GetFailedShapes(self, publish=False):
2036 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2037 error of an algorithm
2040 publish: if *True*, the returned groups will be published in the study
2043 a list of GEOM groups each named after a failed algorithm
2048 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2049 for err in computeErrors:
2050 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2051 if not shape: continue
2052 if err.algoName in algo2shapes:
2053 algo2shapes[ err.algoName ].append( shape )
2055 algo2shapes[ err.algoName ] = [ shape ]
2059 for algoName, shapes in list(algo2shapes.items()):
2061 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2062 otherTypeShapes = []
2064 group = self.geompyD.CreateGroup( self.geom, groupType )
2065 for shape in shapes:
2066 if shape.GetShapeType() == shapes[0].GetShapeType():
2067 sameTypeShapes.append( shape )
2069 otherTypeShapes.append( shape )
2070 self.geompyD.UnionList( group, sameTypeShapes )
2072 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2074 group.SetName( algoName )
2075 groups.append( group )
2076 shapes = otherTypeShapes
2079 for group in groups:
2080 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2083 def GetMeshOrder(self):
2085 Return sub-mesh objects list in meshing order
2088 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2091 return self.mesh.GetMeshOrder()
2093 def SetMeshOrder(self, submeshes):
2095 Set priority of sub-meshes. It works in two ways:
2097 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2098 *several dimensions*, it sets the order in which the sub-meshes are computed.
2099 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2100 when looking for meshing parameters to apply to a sub-shape. To impose the
2101 order in which sub-meshes with uni-dimensional algorithms are computed,
2102 call **submesh.Compute()** in a desired order.
2105 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2107 Warning: the method is for setting the order for all sub-meshes at once:
2108 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2111 return self.mesh.SetMeshOrder(submeshes)
2113 def Clear(self, refresh=False):
2115 Remove all nodes and elements generated on geometry. Imported elements remain.
2118 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2122 if ( salome.sg.hasDesktop() ):
2123 if refresh: salome.sg.updateObjBrowser()
2125 def ClearSubMesh(self, geomId, refresh=False):
2127 Remove all nodes and elements of indicated shape
2130 geomId: the ID of a sub-shape to remove elements on
2131 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2134 self.mesh.ClearSubMesh(geomId)
2135 if salome.sg.hasDesktop():
2136 if refresh: salome.sg.updateObjBrowser()
2138 def AutomaticTetrahedralization(self, fineness=0):
2140 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2143 fineness: [0.0,1.0] defines mesh fineness
2149 dim = self.MeshDimension()
2151 self.RemoveGlobalHypotheses()
2152 self.Segment().AutomaticLength(fineness)
2154 self.Triangle().LengthFromEdges()
2159 return self.Compute()
2161 def AutomaticHexahedralization(self, fineness=0):
2163 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2166 fineness: [0.0, 1.0] defines mesh fineness
2172 dim = self.MeshDimension()
2173 # assign the hypotheses
2174 self.RemoveGlobalHypotheses()
2175 self.Segment().AutomaticLength(fineness)
2182 return self.Compute()
2184 def AddHypothesis(self, hyp, geom=0):
2189 hyp: a hypothesis to assign
2190 geom: a subhape of mesh geometry
2193 :class:`SMESH.Hypothesis_Status`
2196 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2197 hyp, geom = geom, hyp
2198 if isinstance( hyp, Mesh_Algorithm ):
2199 hyp = hyp.GetAlgorithm()
2204 geom = self.mesh.GetShapeToMesh()
2207 if self.mesh.HasShapeToMesh():
2208 hyp_type = hyp.GetName()
2209 lib_name = hyp.GetLibName()
2210 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2211 # if checkAll and geom:
2212 # checkAll = geom.GetType() == 37
2214 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2216 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2217 status = self.mesh.AddHypothesis(geom, hyp)
2219 status = HYP_BAD_GEOMETRY, ""
2220 hyp_name = GetName( hyp )
2223 geom_name = geom.GetName()
2224 isAlgo = hyp._narrow( SMESH_Algo )
2225 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2228 def IsUsedHypothesis(self, hyp, geom):
2230 Return True if an algorithm or hypothesis is assigned to a given shape
2233 hyp: an algorithm or hypothesis to check
2234 geom: a subhape of mesh geometry
2240 if not hyp: # or not geom
2242 if isinstance( hyp, Mesh_Algorithm ):
2243 hyp = hyp.GetAlgorithm()
2245 hyps = self.GetHypothesisList(geom)
2247 if h.GetId() == hyp.GetId():
2251 def RemoveHypothesis(self, hyp, geom=0):
2253 Unassign a hypothesis
2256 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2257 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2260 :class:`SMESH.Hypothesis_Status`
2265 if isinstance( hyp, Mesh_Algorithm ):
2266 hyp = hyp.GetAlgorithm()
2272 if self.IsUsedHypothesis( hyp, shape ):
2273 return self.mesh.RemoveHypothesis( shape, hyp )
2274 hypName = GetName( hyp )
2275 geoName = GetName( shape )
2276 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2279 def GetHypothesisList(self, geom):
2281 Get the list of hypotheses added on a geometry
2284 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2287 the sequence of :class:`SMESH.SMESH_Hypothesis`
2290 return self.mesh.GetHypothesisList( geom )
2292 def RemoveGlobalHypotheses(self):
2294 Remove all global hypotheses
2297 current_hyps = self.mesh.GetHypothesisList( self.geom )
2298 for hyp in current_hyps:
2299 self.mesh.RemoveHypothesis( self.geom, hyp )
2303 def ExportMEDCoupling(self, *args, **kwargs):
2305 Export the mesh in a memory representation.
2308 auto_groups (boolean): parameter for creating/not creating
2309 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2310 the typical use is auto_groups=False.
2311 overwrite (boolean): parameter for overwriting/not overwriting the file
2312 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2313 to export instead of the mesh
2314 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2316 - 1D if all mesh nodes lie on OX coordinate axis, or
2317 - 2D if all mesh nodes lie on XOY coordinate plane, or
2318 - 3D in the rest cases.
2320 If *autoDimension* is *False*, the space dimension is always 3.
2321 fields: list of GEOM fields defined on the shape to mesh.
2322 geomAssocFields: each character of this string means a need to export a
2323 corresponding field; correspondence between fields and characters
2326 - 'v' stands for "_vertices_" field;
2327 - 'e' stands for "_edges_" field;
2328 - 'f' stands for "_faces_" field;
2329 - 's' stands for "_solids_" field.
2331 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2332 close to zero within a given tolerance, the coordinate is set to zero.
2333 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2334 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2336 auto_groups = args[0] if len(args) > 0 else False
2337 meshPart = args[1] if len(args) > 1 else None
2338 autoDimension = args[2] if len(args) > 2 else True
2339 fields = args[3] if len(args) > 3 else []
2340 geomAssocFields = args[4] if len(args) > 4 else ''
2341 z_tolerance = args[5] if len(args) > 5 else -1.
2342 saveNumbers = args[6] if len(args) > 6 else True
2343 # process keywords arguments
2344 auto_groups = kwargs.get("auto_groups", auto_groups)
2345 meshPart = kwargs.get("meshPart", meshPart)
2346 autoDimension = kwargs.get("autoDimension", autoDimension)
2347 fields = kwargs.get("fields", fields)
2348 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2349 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2350 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2352 # invoke engine's function
2353 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2354 unRegister = genObjUnRegister()
2355 if isinstance( meshPart, list ):
2356 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2357 unRegister.set( meshPart )
2359 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2360 self.mesh.SetParameters(Parameters)
2362 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2363 fields, geomAssocFields, z_tolerance,
2366 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2367 return medcoupling.MEDFileData.New(dab)
2369 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2371 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2372 return medcoupling.MEDFileMesh.New(dab)
2374 def ExportMED(self, *args, **kwargs):
2376 Export the mesh in a file in MED format
2377 allowing to overwrite the file if it exists or add the exported data to its contents
2380 fileName: is the file name
2381 auto_groups (boolean): parameter for creating/not creating
2382 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2383 the typical use is auto_groups=False.
2384 version (int): define the version (xy, where version is x.y.z) of MED file format.
2385 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2386 The rules of compatibility to write a mesh in an older version than
2387 the current version depend on the current version. For instance,
2388 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2389 or 3.2.1 or 3.3.1 formats.
2390 If the version is equal to -1, the version is not changed (default).
2391 overwrite (boolean): parameter for overwriting/not overwriting the file
2392 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2393 to export instead of the mesh
2394 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2396 - 1D if all mesh nodes lie on OX coordinate axis, or
2397 - 2D if all mesh nodes lie on XOY coordinate plane, or
2398 - 3D in the rest cases.
2400 If *autoDimension* is *False*, the space dimension is always 3.
2401 fields: list of GEOM fields defined on the shape to mesh.
2402 geomAssocFields: each character of this string means a need to export a
2403 corresponding field; correspondence between fields and characters
2406 - 'v' stands for "_vertices_" field;
2407 - 'e' stands for "_edges_" field;
2408 - 'f' stands for "_faces_" field;
2409 - 's' stands for "_solids_" field.
2411 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2412 close to zero within a given tolerance, the coordinate is set to zero.
2413 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2414 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2416 # process positional arguments
2417 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2419 auto_groups = args[1] if len(args) > 1 else False
2420 version = args[2] if len(args) > 2 else -1
2421 overwrite = args[3] if len(args) > 3 else True
2422 meshPart = args[4] if len(args) > 4 else None
2423 autoDimension = args[5] if len(args) > 5 else True
2424 fields = args[6] if len(args) > 6 else []
2425 geomAssocFields = args[7] if len(args) > 7 else ''
2426 z_tolerance = args[8] if len(args) > 8 else -1.
2427 saveNumbers = args[9] if len(args) > 9 else True
2428 # process keywords arguments
2429 auto_groups = kwargs.get("auto_groups", auto_groups)
2430 version = kwargs.get("version", version)
2431 version = kwargs.get("minor", version)
2432 overwrite = kwargs.get("overwrite", overwrite)
2433 meshPart = kwargs.get("meshPart", meshPart)
2434 autoDimension = kwargs.get("autoDimension", autoDimension)
2435 fields = kwargs.get("fields", fields)
2436 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2437 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2438 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2440 if isinstance( meshPart, Mesh):
2441 meshPart = meshPart.GetMesh()
2443 # invoke engine's function
2444 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2445 unRegister = genObjUnRegister()
2446 if isinstance( meshPart, list ):
2447 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2448 unRegister.set( meshPart )
2450 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2451 self.mesh.SetParameters(Parameters)
2453 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2454 version, overwrite, autoDimension,
2455 fields, geomAssocFields, z_tolerance, saveNumbers )
2457 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2459 def ExportSAUV(self, f, auto_groups=0):
2461 Export the mesh in a file in SAUV format
2466 auto_groups: boolean parameter for creating/not creating
2467 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2468 the typical use is auto_groups=False.
2471 self.mesh.ExportSAUV(f, auto_groups)
2473 def ExportDAT(self, f, meshPart=None, renumber=True):
2475 Export the mesh in a file in DAT format
2479 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2480 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2483 if meshPart or not renumber:
2484 unRegister = genObjUnRegister()
2485 if isinstance( meshPart, list ):
2486 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2487 unRegister.set( meshPart )
2488 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2490 self.mesh.ExportDAT( f, renumber )
2492 def ExportUNV(self, f, meshPart=None, renumber=True):
2494 Export the mesh in a file in UNV format
2498 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2499 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2502 if meshPart or not renumber:
2503 unRegister = genObjUnRegister()
2504 if isinstance( meshPart, list ):
2505 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2506 unRegister.set( meshPart )
2507 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2509 self.mesh.ExportUNV( f, renumber )
2511 def ExportSTL(self, f, ascii=1, meshPart=None):
2513 Export the mesh in a file in STL format
2517 ascii: defines the file encoding
2518 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2522 unRegister = genObjUnRegister()
2523 if isinstance( meshPart, list ):
2524 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2525 unRegister.set( meshPart )
2526 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2528 self.mesh.ExportSTL(f, ascii)
2530 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2532 Export the mesh in a file in CGNS format
2536 overwrite: boolean parameter for overwriting/not overwriting the file
2537 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2538 groupElemsByType: if True all elements of same entity type are exported at ones,
2539 else elements are exported in order of their IDs which can cause creation
2540 of multiple cgns sections
2543 unRegister = genObjUnRegister()
2544 if isinstance( meshPart, list ):
2545 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2546 unRegister.set( meshPart )
2547 if isinstance( meshPart, Mesh ):
2548 meshPart = meshPart.mesh
2550 meshPart = self.mesh
2551 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2553 def ExportGMF(self, f, meshPart=None):
2555 Export the mesh in a file in GMF format.
2556 GMF files must have .mesh extension for the ASCII format and .meshb for
2557 the bynary format. Other extensions are not allowed.
2561 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2564 unRegister = genObjUnRegister()
2565 if isinstance( meshPart, list ):
2566 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2567 unRegister.set( meshPart )
2568 if isinstance( meshPart, Mesh ):
2569 meshPart = meshPart.mesh
2571 meshPart = self.mesh
2572 self.mesh.ExportGMF(meshPart, f, True)
2574 def ExportToMED(self, *args, **kwargs):
2576 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2577 Export the mesh in a file in MED format
2578 allowing to overwrite the file if it exists or add the exported data to its contents
2581 fileName: the file name
2582 opt (boolean): parameter for creating/not creating
2583 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2584 overwrite: boolean parameter for overwriting/not overwriting the file
2585 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2587 - 1D if all mesh nodes lie on OX coordinate axis, or
2588 - 2D if all mesh nodes lie on XOY coordinate plane, or
2589 - 3D in the rest cases.
2591 If **autoDimension** is *False*, the space dimension is always 3.
2594 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2595 # process positional arguments
2596 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2598 auto_groups = args[1] if len(args) > 1 else False
2599 overwrite = args[2] if len(args) > 2 else True
2600 autoDimension = args[3] if len(args) > 3 else True
2601 # process keywords arguments
2602 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2603 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2604 overwrite = kwargs.get("overwrite", overwrite)
2605 autoDimension = kwargs.get("autoDimension", autoDimension)
2607 # invoke engine's function
2608 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2610 def ExportToMEDX(self, *args, **kwargs):
2612 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2613 Export the mesh in a file in MED format
2616 fileName: the file name
2617 opt (boolean): parameter for creating/not creating
2618 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2619 overwrite: boolean parameter for overwriting/not overwriting the file
2620 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2622 - 1D if all mesh nodes lie on OX coordinate axis, or
2623 - 2D if all mesh nodes lie on XOY coordinate plane, or
2624 - 3D in the rest cases.
2626 If **autoDimension** is *False*, the space dimension is always 3.
2629 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2630 # process positional arguments
2631 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2633 auto_groups = args[1] if len(args) > 1 else False
2634 overwrite = args[2] if len(args) > 2 else True
2635 autoDimension = args[3] if len(args) > 3 else True
2636 # process keywords arguments
2637 auto_groups = kwargs.get("auto_groups", auto_groups)
2638 overwrite = kwargs.get("overwrite", overwrite)
2639 autoDimension = kwargs.get("autoDimension", autoDimension)
2641 # invoke engine's function
2642 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2646 def Append(self, meshes, uniteIdenticalGroups = True,
2647 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2649 Append given meshes into this mesh.
2650 All groups of input meshes will be created in this mesh.
2653 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2654 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2655 mergeNodesAndElements: if True, equal nodes and elements are merged
2656 mergeTolerance: tolerance for merging nodes
2657 allGroups: forces creation of groups corresponding to every input mesh
2659 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2660 mergeNodesAndElements, mergeTolerance, allGroups,
2661 meshToAppendTo = self.GetMesh() )
2663 # Operations with groups:
2664 # ----------------------
2665 def CreateEmptyGroup(self, elementType, name):
2667 Create an empty standalone mesh group
2670 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2671 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2672 name: the name of the mesh group
2675 :class:`SMESH.SMESH_Group`
2678 return self.mesh.CreateGroup(elementType, name)
2680 def Group(self, grp, name=""):
2682 Create a mesh group based on the geometric object *grp*
2683 and give it a *name*.
2684 If *name* is not defined the name of the geometric group is used
2687 Works like :meth:`GroupOnGeom`.
2690 grp: a geometric group, a vertex, an edge, a face or a solid
2691 name: the name of the mesh group
2694 :class:`SMESH.SMESH_GroupOnGeom`
2697 return self.GroupOnGeom(grp, name)
2699 def GroupOnGeom(self, grp, name="", typ=None):
2701 Create a mesh group based on the geometrical object *grp*
2702 and give it a *name*.
2703 if *name* is not defined the name of the geometric group is used
2706 grp: a geometrical group, a vertex, an edge, a face or a solid
2707 name: the name of the mesh group
2708 typ: the type of elements in the group; either of
2709 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2710 automatically detected by the type of the geometry
2713 :class:`SMESH.SMESH_GroupOnGeom`
2716 AssureGeomPublished( self, grp, name )
2718 name = grp.GetName()
2720 typ = self._groupTypeFromShape( grp )
2721 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2723 def _groupTypeFromShape( self, shape ):
2725 Pivate method to get a type of group on geometry
2727 tgeo = str(shape.GetShapeType())
2728 if tgeo == "VERTEX":
2730 elif tgeo == "EDGE" or tgeo == "WIRE":
2732 elif tgeo == "FACE" or tgeo == "SHELL":
2734 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2736 elif tgeo == "COMPOUND":
2738 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2740 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2741 # simplification of access in geomBuilder: omniORB.registerObjref
2742 from SHAPERSTUDY_utils import getEngine
2745 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2747 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2748 return self._groupTypeFromShape( sub[0] )
2750 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2753 def GroupOnFilter(self, typ, name, filter):
2755 Create a mesh group with given *name* based on the *filter*.
2756 It is a special type of group dynamically updating it's contents during
2760 typ: the type of elements in the group; either of
2761 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2762 name: the name of the mesh group
2763 filter (SMESH.Filter): the filter defining group contents
2766 :class:`SMESH.SMESH_GroupOnFilter`
2769 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2771 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2773 Create a mesh group by the given ids of elements
2776 groupName: the name of the mesh group
2777 elementType: the type of elements in the group; either of
2778 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2779 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2782 :class:`SMESH.SMESH_Group`
2785 group = self.mesh.CreateGroup(elementType, groupName)
2786 if isinstance( elemIDs, Mesh ):
2787 elemIDs = elemIDs.GetMesh()
2788 if hasattr( elemIDs, "GetIDs" ):
2789 if hasattr( elemIDs, "SetMesh" ):
2790 elemIDs.SetMesh( self.GetMesh() )
2791 group.AddFrom( elemIDs )
2799 CritType=FT_Undefined,
2802 UnaryOp=FT_Undefined,
2805 Create a mesh group by the given conditions
2808 groupName: the name of the mesh group
2809 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2810 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2811 Note that the items starting from FT_LessThan are not suitable for CritType.
2812 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2813 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2814 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2815 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2816 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2819 :class:`SMESH.SMESH_GroupOnFilter`
2822 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2823 group = self.MakeGroupByCriterion(groupName, aCriterion)
2826 def MakeGroupByCriterion(self, groupName, Criterion):
2828 Create a mesh group by the given criterion
2831 groupName: the name of the mesh group
2832 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2835 :class:`SMESH.SMESH_GroupOnFilter`
2838 :meth:`smeshBuilder.GetCriterion`
2841 return self.MakeGroupByCriteria( groupName, [Criterion] )
2843 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2845 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2848 groupName: the name of the mesh group
2849 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2850 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2853 :class:`SMESH.SMESH_GroupOnFilter`
2856 :meth:`smeshBuilder.GetCriterion`
2859 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2860 group = self.MakeGroupByFilter(groupName, aFilter)
2863 def MakeGroupByFilter(self, groupName, theFilter):
2865 Create a mesh group by the given filter
2868 groupName (string): the name of the mesh group
2869 theFilter (SMESH.Filter): the filter
2872 :class:`SMESH.SMESH_GroupOnFilter`
2875 :meth:`smeshBuilder.GetFilter`
2878 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2879 #theFilter.SetMesh( self.mesh )
2880 #group.AddFrom( theFilter )
2881 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2884 def RemoveGroup(self, group):
2889 group (SMESH.SMESH_GroupBase): group to remove
2892 self.mesh.RemoveGroup(group)
2894 def RemoveGroupWithContents(self, group):
2896 Remove a group with its contents
2899 group (SMESH.SMESH_GroupBase): group to remove
2902 This operation can create gaps in numeration of nodes or elements.
2903 Call :meth:`RenumberElements` to remove the gaps.
2906 self.mesh.RemoveGroupWithContents(group)
2908 def GetGroups(self, elemType = SMESH.ALL):
2910 Get the list of groups existing in the mesh in the order of creation
2911 (starting from the oldest one)
2914 elemType (SMESH.ElementType): type of elements the groups contain;
2915 by default groups of elements of all types are returned
2918 a list of :class:`SMESH.SMESH_GroupBase`
2921 groups = self.mesh.GetGroups()
2922 if elemType == SMESH.ALL:
2926 if g.GetType() == elemType:
2927 typedGroups.append( g )
2934 Get the number of groups existing in the mesh
2937 the quantity of groups as an integer value
2940 return self.mesh.NbGroups()
2942 def GetGroupNames(self):
2944 Get the list of names of groups existing in the mesh
2950 groups = self.GetGroups()
2952 for group in groups:
2953 names.append(group.GetName())
2956 def GetGroupByName(self, name, elemType = None):
2958 Find groups by name and type
2961 name (string): name of the group of interest
2962 elemType (SMESH.ElementType): type of elements the groups contain;
2963 by default one group of any type is returned;
2964 if elemType == SMESH.ALL then all groups of any type are returned
2967 a list of :class:`SMESH.SMESH_GroupBase`
2971 for group in self.GetGroups():
2972 if group.GetName() == name:
2973 if elemType is None:
2975 if ( elemType == SMESH.ALL or
2976 group.GetType() == elemType ):
2977 groups.append( group )
2980 def UnionGroups(self, group1, group2, name):
2982 Produce a union of two groups.
2983 A new group is created. All mesh elements that are
2984 present in the initial groups are added to the new one
2987 group1 (SMESH.SMESH_GroupBase): a group
2988 group2 (SMESH.SMESH_GroupBase): another group
2991 instance of :class:`SMESH.SMESH_Group`
2994 return self.mesh.UnionGroups(group1, group2, name)
2996 def UnionListOfGroups(self, groups, name):
2998 Produce a union list of groups.
2999 New group is created. All mesh elements that are present in
3000 initial groups are added to the new one
3003 groups: list of :class:`SMESH.SMESH_GroupBase`
3006 instance of :class:`SMESH.SMESH_Group`
3008 return self.mesh.UnionListOfGroups(groups, name)
3010 def IntersectGroups(self, group1, group2, name):
3012 Prodice an intersection of two groups.
3013 A new group is created. All mesh elements that are common
3014 for the two initial groups are added to the new one.
3017 group1 (SMESH.SMESH_GroupBase): a group
3018 group2 (SMESH.SMESH_GroupBase): another group
3021 instance of :class:`SMESH.SMESH_Group`
3024 return self.mesh.IntersectGroups(group1, group2, name)
3026 def IntersectListOfGroups(self, groups, name):
3028 Produce an intersection of groups.
3029 New group is created. All mesh elements that are present in all
3030 initial groups simultaneously are added to the new one
3033 groups: a list of :class:`SMESH.SMESH_GroupBase`
3036 instance of :class:`SMESH.SMESH_Group`
3038 return self.mesh.IntersectListOfGroups(groups, name)
3040 def CutGroups(self, main_group, tool_group, name):
3042 Produce a cut of two groups.
3043 A new group is created. All mesh elements that are present in
3044 the main group but are not present in the tool group are added to the new one
3047 main_group (SMESH.SMESH_GroupBase): a group to cut from
3048 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3051 an instance of :class:`SMESH.SMESH_Group`
3054 return self.mesh.CutGroups(main_group, tool_group, name)
3056 def CutListOfGroups(self, main_groups, tool_groups, name):
3058 Produce a cut of groups.
3059 A new group is created. All mesh elements that are present in main groups
3060 but do not present in tool groups are added to the new one
3063 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3064 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3067 an instance of :class:`SMESH.SMESH_Group`
3070 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3072 def CreateDimGroup(self, groups, elemType, name,
3073 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3075 Create a standalone group of entities basing on nodes of other groups.
3078 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3079 elemType: a type of elements to include to the new group; either of
3080 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3081 name: a name of the new group.
3082 nbCommonNodes: a criterion of inclusion of an element to the new group
3083 basing on number of element nodes common with reference *groups*.
3084 Meaning of possible values are:
3086 - SMESH.ALL_NODES - include if all nodes are common,
3087 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3088 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3089 - SMEHS.MAJORITY - include if half of nodes or more are common.
3090 underlyingOnly: if *True* (default), an element is included to the
3091 new group provided that it is based on nodes of an element of *groups*;
3092 in this case the reference *groups* are supposed to be of higher dimension
3093 than *elemType*, which can be useful for example to get all faces lying on
3094 volumes of the reference *groups*.
3097 an instance of :class:`SMESH.SMESH_Group`
3100 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3102 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3104 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3106 Distribute all faces of the mesh among groups using sharp edges and optionally
3107 existing 1D elements as group boundaries.
3110 sharpAngle: edge is considered sharp if an angle between normals of
3111 adjacent faces is more than \a sharpAngle in degrees.
3112 createEdges (boolean): to create 1D elements for detected sharp edges.
3113 useExistingEdges (boolean): to use existing edges as group boundaries
3115 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3117 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3118 self.mesh.SetParameters(Parameters)
3119 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3121 def ConvertToStandalone(self, group):
3123 Convert group on geom into standalone group
3126 return self.mesh.ConvertToStandalone(group)
3128 # Get some info about mesh:
3129 # ------------------------
3131 def GetLog(self, clearAfterGet):
3133 Return the log of nodes and elements added or removed
3134 since the previous clear of the log.
3137 clearAfterGet: log is emptied after Get (safe if concurrents access)
3140 list of SMESH.log_block structures { commandType, number, coords, indexes }
3143 return self.mesh.GetLog(clearAfterGet)
3147 Clear the log of nodes and elements added or removed since the previous
3148 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3151 self.mesh.ClearLog()
3153 def SetAutoColor(self, theAutoColor):
3155 Toggle auto color mode on the object.
3156 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3159 theAutoColor (boolean): the flag which toggles auto color mode.
3162 self.mesh.SetAutoColor(theAutoColor)
3164 def GetAutoColor(self):
3166 Get flag of object auto color mode.
3172 return self.mesh.GetAutoColor()
3179 integer value, which is the internal Id of the mesh
3182 return self.mesh.GetId()
3184 def HasDuplicatedGroupNamesMED(self):
3186 Check the group names for duplications.
3187 Consider the maximum group name length stored in MED file.
3193 return self.mesh.HasDuplicatedGroupNamesMED()
3195 def GetMeshEditor(self):
3197 Obtain the mesh editor tool
3200 an instance of :class:`SMESH.SMESH_MeshEditor`
3205 def GetIDSource(self, ids, elemType = SMESH.ALL):
3207 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3208 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3212 elemType: type of elements; this parameter is used to distinguish
3213 IDs of nodes from IDs of elements; by default ids are treated as
3214 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3217 an instance of :class:`SMESH.SMESH_IDSource`
3220 call UnRegister() for the returned object as soon as it is no more useful::
3222 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3223 mesh.DoSomething( idSrc )
3227 if isinstance( ids, int ):
3229 return self.editor.MakeIDSource(ids, elemType)
3232 # Get information about mesh contents:
3233 # ------------------------------------
3235 def GetMeshInfo(self, obj = None):
3237 Get the mesh statistic.
3240 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3243 if not obj: obj = self.mesh
3244 return self.smeshpyD.GetMeshInfo(obj)
3248 Return the number of nodes in the mesh
3254 return self.mesh.NbNodes()
3256 def NbElements(self):
3258 Return the number of elements in the mesh
3264 return self.mesh.NbElements()
3266 def Nb0DElements(self):
3268 Return the number of 0d elements in the mesh
3274 return self.mesh.Nb0DElements()
3278 Return the number of ball discrete elements in the mesh
3284 return self.mesh.NbBalls()
3288 Return the number of edges in the mesh
3294 return self.mesh.NbEdges()
3296 def NbEdgesOfOrder(self, elementOrder):
3298 Return the number of edges with the given order in the mesh
3301 elementOrder: the order of elements
3302 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3308 return self.mesh.NbEdgesOfOrder(elementOrder)
3312 Return the number of faces in the mesh
3318 return self.mesh.NbFaces()
3320 def NbFacesOfOrder(self, elementOrder):
3322 Return the number of faces with the given order in the mesh
3325 elementOrder: the order of elements
3326 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3332 return self.mesh.NbFacesOfOrder(elementOrder)
3334 def NbTriangles(self):
3336 Return the number of triangles in the mesh
3342 return self.mesh.NbTriangles()
3344 def NbTrianglesOfOrder(self, elementOrder):
3346 Return the number of triangles with the given order in the mesh
3349 elementOrder: is the order of elements
3350 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3356 return self.mesh.NbTrianglesOfOrder(elementOrder)
3358 def NbBiQuadTriangles(self):
3360 Return the number of biquadratic triangles in the mesh
3366 return self.mesh.NbBiQuadTriangles()
3368 def NbQuadrangles(self):
3370 Return the number of quadrangles in the mesh
3376 return self.mesh.NbQuadrangles()
3378 def NbQuadranglesOfOrder(self, elementOrder):
3380 Return the number of quadrangles with the given order in the mesh
3383 elementOrder: the order of elements
3384 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3390 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3392 def NbBiQuadQuadrangles(self):
3394 Return the number of biquadratic quadrangles in the mesh
3400 return self.mesh.NbBiQuadQuadrangles()
3402 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3404 Return the number of polygons of given order in the mesh
3407 elementOrder: the order of elements
3408 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3414 return self.mesh.NbPolygonsOfOrder(elementOrder)
3416 def NbVolumes(self):
3418 Return the number of volumes in the mesh
3424 return self.mesh.NbVolumes()
3427 def NbVolumesOfOrder(self, elementOrder):
3429 Return the number of volumes with the given order in the mesh
3432 elementOrder: the order of elements
3433 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3439 return self.mesh.NbVolumesOfOrder(elementOrder)
3443 Return the number of tetrahedrons in the mesh
3449 return self.mesh.NbTetras()
3451 def NbTetrasOfOrder(self, elementOrder):
3453 Return the number of tetrahedrons with the given order in the mesh
3456 elementOrder: the order of elements
3457 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3463 return self.mesh.NbTetrasOfOrder(elementOrder)
3467 Return the number of hexahedrons in the mesh
3473 return self.mesh.NbHexas()
3475 def NbHexasOfOrder(self, elementOrder):
3477 Return the number of hexahedrons with the given order in the mesh
3480 elementOrder: the order of elements
3481 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3487 return self.mesh.NbHexasOfOrder(elementOrder)
3489 def NbTriQuadraticHexas(self):
3491 Return the number of triquadratic hexahedrons in the mesh
3497 return self.mesh.NbTriQuadraticHexas()
3499 def NbPyramids(self):
3501 Return the number of pyramids in the mesh
3507 return self.mesh.NbPyramids()
3509 def NbPyramidsOfOrder(self, elementOrder):
3511 Return the number of pyramids with the given order in the mesh
3514 elementOrder: the order of elements
3515 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3521 return self.mesh.NbPyramidsOfOrder(elementOrder)
3525 Return the number of prisms in the mesh
3531 return self.mesh.NbPrisms()
3533 def NbPrismsOfOrder(self, elementOrder):
3535 Return the number of prisms with the given order in the mesh
3538 elementOrder: the order of elements
3539 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3545 return self.mesh.NbPrismsOfOrder(elementOrder)
3547 def NbHexagonalPrisms(self):
3549 Return the number of hexagonal prisms in the mesh
3555 return self.mesh.NbHexagonalPrisms()
3557 def NbPolyhedrons(self):
3559 Return the number of polyhedrons in the mesh
3565 return self.mesh.NbPolyhedrons()
3567 def NbSubMesh(self):
3569 Return the number of submeshes in the mesh
3575 return self.mesh.NbSubMesh()
3577 def GetElementsId(self):
3579 Return the list of all mesh elements IDs
3582 the list of integer values
3585 :meth:`GetElementsByType`
3588 return self.mesh.GetElementsId()
3590 def GetElementsByType(self, elementType):
3592 Return the list of IDs of mesh elements with the given type
3595 elementType (SMESH.ElementType): the required type of elements
3598 list of integer values
3601 return self.mesh.GetElementsByType(elementType)
3603 def GetNodesId(self):
3605 Return the list of mesh nodes IDs
3608 the list of integer values
3611 return self.mesh.GetNodesId()
3613 # Get the information about mesh elements:
3614 # ------------------------------------
3616 def GetElementType(self, id, iselem=True):
3618 Return the type of mesh element or node
3621 the value from :class:`SMESH.ElementType` enumeration.
3622 Return SMESH.ALL if element or node with the given ID does not exist
3625 return self.mesh.GetElementType(id, iselem)
3627 def GetElementGeomType(self, id):
3629 Return the geometric type of mesh element
3632 the value from :class:`SMESH.EntityType` enumeration.
3635 return self.mesh.GetElementGeomType(id)
3637 def GetElementShape(self, id):
3639 Return the shape type of mesh element
3642 the value from :class:`SMESH.GeometryType` enumeration.
3645 return self.mesh.GetElementShape(id)
3647 def GetSubMeshElementsId(self, Shape):
3649 Return the list of sub-mesh elements IDs
3652 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3653 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3656 list of integer values
3659 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3660 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3663 return self.mesh.GetSubMeshElementsId(ShapeID)
3665 def GetSubMeshNodesId(self, Shape, all):
3667 Return the list of sub-mesh nodes IDs
3670 Shape: a geom object (sub-shape).
3671 *Shape* must be the sub-shape of a :meth:`GetShape`
3672 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3675 list of integer values
3678 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3679 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3682 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3684 def GetSubMeshElementType(self, Shape):
3686 Return type of elements on given shape
3689 Shape: a geom object (sub-shape).
3690 *Shape* must be a sub-shape of a ShapeToMesh()
3693 :class:`SMESH.ElementType`
3696 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3697 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3700 return self.mesh.GetSubMeshElementType(ShapeID)
3704 Get the mesh description
3710 return self.mesh.Dump()
3713 # Get the information about nodes and elements of a mesh by its IDs:
3714 # -----------------------------------------------------------
3716 def GetNodeXYZ(self, id):
3718 Get XYZ coordinates of a node.
3719 If there is no node for the given ID - return an empty list
3722 list of float values
3725 return self.mesh.GetNodeXYZ(id)
3727 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3729 Return list of IDs of inverse elements for the given node.
3730 If there is no node for the given ID - return an empty list
3734 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3737 list of integer values
3740 return self.mesh.GetNodeInverseElements(id,elemType)
3742 def GetNodePosition(self,NodeID):
3744 Return the position of a node on the shape
3747 :class:`SMESH.NodePosition`
3750 return self.mesh.GetNodePosition(NodeID)
3752 def GetElementPosition(self,ElemID):
3754 Return the position of an element on the shape
3757 :class:`SMESH.ElementPosition`
3760 return self.mesh.GetElementPosition(ElemID)
3762 def GetShapeID(self, id):
3764 Return the ID of the shape, on which the given node was generated.
3767 an integer value > 0 or -1 if there is no node for the given
3768 ID or the node is not assigned to any geometry
3771 return self.mesh.GetShapeID(id)
3773 def GetShapeIDForElem(self,id):
3775 Return the ID of the shape, on which the given element was generated.
3778 an integer value > 0 or -1 if there is no element for the given
3779 ID or the element is not assigned to any geometry
3782 return self.mesh.GetShapeIDForElem(id)
3784 def GetElemNbNodes(self, id):
3786 Return the number of nodes of the given element
3789 an integer value > 0 or -1 if there is no element for the given ID
3792 return self.mesh.GetElemNbNodes(id)
3794 def GetElemNode(self, id, index):
3796 Return the node ID the given (zero based) index for the given element.
3798 * If there is no element for the given ID - return -1.
3799 * If there is no node for the given index - return -2.
3802 id (int): element ID
3803 index (int): node index within the element
3806 an integer value (ID)
3809 :meth:`GetElemNodes`
3812 return self.mesh.GetElemNode(id, index)
3814 def GetElemNodes(self, id):
3816 Return the IDs of nodes of the given element
3819 a list of integer values
3822 return self.mesh.GetElemNodes(id)
3824 def IsMediumNode(self, elementID, nodeID):
3826 Return true if the given node is the medium node in the given quadratic element
3829 return self.mesh.IsMediumNode(elementID, nodeID)
3831 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3833 Return true if the given node is the medium node in one of quadratic elements
3836 nodeID: ID of the node
3837 elementType: the type of elements to check a state of the node, either of
3838 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3841 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3843 def ElemNbEdges(self, id):
3845 Return the number of edges for the given element
3848 return self.mesh.ElemNbEdges(id)
3850 def ElemNbFaces(self, id):
3852 Return the number of faces for the given element
3855 return self.mesh.ElemNbFaces(id)
3857 def GetElemFaceNodes(self,elemId, faceIndex):
3859 Return nodes of given face (counted from zero) for given volumic element.
3862 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3864 def GetFaceNormal(self, faceId, normalized=False):
3866 Return three components of normal of given mesh face
3867 (or an empty array in KO case)
3870 return self.mesh.GetFaceNormal(faceId,normalized)
3872 def FindElementByNodes(self, nodes):
3874 Return an element based on all given nodes.
3877 return self.mesh.FindElementByNodes(nodes)
3879 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3881 Return elements including all given nodes.
3884 return self.mesh.GetElementsByNodes( nodes, elemType )
3886 def IsPoly(self, id):
3888 Return true if the given element is a polygon
3891 return self.mesh.IsPoly(id)
3893 def IsQuadratic(self, id):
3895 Return true if the given element is quadratic
3898 return self.mesh.IsQuadratic(id)
3900 def GetBallDiameter(self, id):
3902 Return diameter of a ball discrete element or zero in case of an invalid *id*
3905 return self.mesh.GetBallDiameter(id)
3907 def BaryCenter(self, id):
3909 Return XYZ coordinates of the barycenter of the given element.
3910 If there is no element for the given ID - return an empty list
3913 a list of three double values
3916 :meth:`smeshBuilder.GetGravityCenter`
3919 return self.mesh.BaryCenter(id)
3921 def GetIdsFromFilter(self, filter, meshParts=[] ):
3923 Pass mesh elements through the given filter and return IDs of fitting elements
3926 filter: :class:`SMESH.Filter`
3927 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3933 :meth:`SMESH.Filter.GetIDs`
3934 :meth:`SMESH.Filter.GetElementsIdFromParts`
3937 filter.SetMesh( self.mesh )
3940 if isinstance( meshParts, Mesh ):
3941 filter.SetMesh( meshParts.GetMesh() )
3942 return theFilter.GetIDs()
3943 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3944 meshParts = [ meshParts ]
3945 return filter.GetElementsIdFromParts( meshParts )
3947 return filter.GetIDs()
3949 # Get mesh measurements information:
3950 # ------------------------------------
3952 def GetFreeBorders(self):
3954 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3955 Return a list of special structures (borders).
3958 a list of :class:`SMESH.FreeEdges.Border`
3961 aFilterMgr = self.smeshpyD.CreateFilterManager()
3962 aPredicate = aFilterMgr.CreateFreeEdges()
3963 aPredicate.SetMesh(self.mesh)
3964 aBorders = aPredicate.GetBorders()
3965 aFilterMgr.UnRegister()
3968 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3970 Get minimum distance between two nodes, elements or distance to the origin
3973 id1: first node/element id
3974 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3975 isElem1: *True* if *id1* is element id, *False* if it is node id
3976 isElem2: *True* if *id2* is element id, *False* if it is node id
3979 minimum distance value
3981 :meth:`GetMinDistance`
3984 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3985 return aMeasure.value
3987 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3989 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3992 id1: first node/element id
3993 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3994 isElem1: *True* if *id1* is element id, *False* if it is node id
3995 isElem2: *True* if *id2* is element id, *False* if it is node id
3998 :class:`SMESH.Measure` structure
4004 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
4006 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
4009 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
4011 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4016 aMeasurements = self.smeshpyD.CreateMeasurements()
4017 aMeasure = aMeasurements.MinDistance(id1, id2)
4018 genObjUnRegister([aMeasurements,id1, id2])
4021 def BoundingBox(self, objects=None, isElem=False):
4023 Get bounding box of the specified object(s)
4026 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4027 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4028 *False* specifies that *objects* are nodes
4031 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4034 :meth:`GetBoundingBox()`
4037 result = self.GetBoundingBox(objects, isElem)
4041 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4044 def GetBoundingBox(self, objects=None, isElem=False):
4046 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4049 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4050 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4051 False means that *objects* are nodes
4054 :class:`SMESH.Measure` structure
4057 :meth:`BoundingBox()`
4061 objects = [self.mesh]
4062 elif isinstance(objects, tuple):
4063 objects = list(objects)
4064 if not isinstance(objects, list):
4066 if len(objects) > 0 and isinstance(objects[0], int):
4069 unRegister = genObjUnRegister()
4071 if isinstance(o, Mesh):
4072 srclist.append(o.mesh)
4073 elif hasattr(o, "_narrow"):
4074 src = o._narrow(SMESH.SMESH_IDSource)
4075 if src: srclist.append(src)
4077 elif isinstance(o, list):
4079 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4081 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4082 unRegister.set( srclist[-1] )
4085 aMeasurements = self.smeshpyD.CreateMeasurements()
4086 unRegister.set( aMeasurements )
4087 aMeasure = aMeasurements.BoundingBox(srclist)
4090 # Mesh edition (SMESH_MeshEditor functionality):
4091 # ---------------------------------------------
4093 def RemoveElements(self, IDsOfElements):
4095 Remove the elements from the mesh by ids
4098 IDsOfElements: is a list of ids of elements to remove
4104 This operation can create gaps in numeration of elements.
4105 Call :meth:`RenumberElements` to remove the gaps.
4108 return self.editor.RemoveElements(IDsOfElements)
4110 def RemoveNodes(self, IDsOfNodes):
4112 Remove nodes from mesh by ids
4115 IDsOfNodes: is a list of ids of nodes to remove
4121 This operation can create gaps in numeration of nodes.
4122 Call :meth:`RenumberElements` to remove the gaps.
4125 return self.editor.RemoveNodes(IDsOfNodes)
4127 def RemoveOrphanNodes(self):
4129 Remove all orphan (free) nodes from mesh
4132 number of the removed nodes
4135 This operation can create gaps in numeration of nodes.
4136 Call :meth:`RenumberElements` to remove the gaps.
4139 return self.editor.RemoveOrphanNodes()
4141 def AddNode(self, x, y, z):
4143 Add a node to the mesh by coordinates
4149 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4150 if hasVars: self.mesh.SetParameters(Parameters)
4151 return self.editor.AddNode( x, y, z)
4153 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4155 Create a 0D element on a node with given number.
4158 IDOfNode: the ID of node for creation of the element.
4159 DuplicateElements: to add one more 0D element to a node or not
4162 ID of the new 0D element
4165 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4167 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4169 Create 0D elements on all nodes of the given elements except those
4170 nodes on which a 0D element already exists.
4173 theObject: an object on whose nodes 0D elements will be created.
4174 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4175 theGroupName: optional name of a group to add 0D elements created
4176 and/or found on nodes of *theObject*.
4177 DuplicateElements: to add one more 0D element to a node or not
4180 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4181 IDs of new and/or found 0D elements. IDs of 0D elements
4182 can be retrieved from the returned object by
4183 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4186 unRegister = genObjUnRegister()
4187 if isinstance( theObject, Mesh ):
4188 theObject = theObject.GetMesh()
4189 elif isinstance( theObject, list ):
4190 theObject = self.GetIDSource( theObject, SMESH.ALL )
4191 unRegister.set( theObject )
4192 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4194 def AddBall(self, IDOfNode, diameter):
4196 Create a ball element on a node with given ID.
4199 IDOfNode: the ID of node for creation of the element.
4200 diameter: the bal diameter.
4203 ID of the new ball element
4206 return self.editor.AddBall( IDOfNode, diameter )
4208 def AddEdge(self, IDsOfNodes):
4210 Create a linear or quadratic edge (this is determined
4211 by the number of given nodes).
4214 IDsOfNodes: list of node IDs for creation of the element.
4215 The order of nodes in this list should correspond to
4216 the :ref:`connectivity convention <connectivity_page>`.
4222 return self.editor.AddEdge(IDsOfNodes)
4224 def AddFace(self, IDsOfNodes):
4226 Create a linear or quadratic face (this is determined
4227 by the number of given nodes).
4230 IDsOfNodes: list of node IDs for creation of the element.
4231 The order of nodes in this list should correspond to
4232 the :ref:`connectivity convention <connectivity_page>`.
4238 return self.editor.AddFace(IDsOfNodes)
4240 def AddPolygonalFace(self, IdsOfNodes):
4242 Add a polygonal face defined by a list of node IDs
4245 IdsOfNodes: the list of node IDs for creation of the element.
4251 return self.editor.AddPolygonalFace(IdsOfNodes)
4253 def AddQuadPolygonalFace(self, IdsOfNodes):
4255 Add a quadratic polygonal face defined by a list of node IDs
4258 IdsOfNodes: the list of node IDs for creation of the element;
4259 corner nodes follow first.
4265 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4267 def AddVolume(self, IDsOfNodes):
4269 Create both simple and quadratic volume (this is determined
4270 by the number of given nodes).
4273 IDsOfNodes: list of node IDs for creation of the element.
4274 The order of nodes in this list should correspond to
4275 the :ref:`connectivity convention <connectivity_page>`.
4278 ID of the new volumic element
4281 return self.editor.AddVolume(IDsOfNodes)
4283 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4285 Create a volume of many faces, giving nodes for each face.
4288 IdsOfNodes: list of node IDs for volume creation, face by face.
4289 Quantities: list of integer values, Quantities[i]
4290 gives the quantity of nodes in face number i.
4293 ID of the new volumic element
4296 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4298 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4300 Create a volume of many faces, giving the IDs of the existing faces.
4303 The created volume will refer only to the nodes
4304 of the given faces, not to the faces themselves.
4307 IdsOfFaces: the list of face IDs for volume creation.
4310 ID of the new volumic element
4313 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4316 def SetNodeOnVertex(self, NodeID, Vertex):
4318 Bind a node to a vertex
4322 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4325 True if succeed else raises an exception
4328 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4329 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4333 self.editor.SetNodeOnVertex(NodeID, VertexID)
4334 except SALOME.SALOME_Exception as inst:
4335 raise ValueError(inst.details.text)
4339 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4341 Store the node position on an edge
4345 Edge: an edge (GEOM.GEOM_Object) or edge ID
4346 paramOnEdge: a parameter on the edge where the node is located
4349 True if succeed else raises an exception
4352 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4353 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4357 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4358 except SALOME.SALOME_Exception as inst:
4359 raise ValueError(inst.details.text)
4362 def SetNodeOnFace(self, NodeID, Face, u, v):
4364 Store node position on a face
4368 Face: a face (GEOM.GEOM_Object) or face ID
4369 u: U parameter on the face where the node is located
4370 v: V parameter on the face where the node is located
4373 True if succeed else raises an exception
4376 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4377 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4381 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4382 except SALOME.SALOME_Exception as inst:
4383 raise ValueError(inst.details.text)
4386 def SetNodeInVolume(self, NodeID, Solid):
4388 Bind a node to a solid
4392 Solid: a solid (GEOM.GEOM_Object) or solid ID
4395 True if succeed else raises an exception
4398 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4399 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4403 self.editor.SetNodeInVolume(NodeID, SolidID)
4404 except SALOME.SALOME_Exception as inst:
4405 raise ValueError(inst.details.text)
4408 def SetMeshElementOnShape(self, ElementID, Shape):
4410 Bind an element to a shape
4413 ElementID: an element ID
4414 Shape: a shape (GEOM.GEOM_Object) or shape ID
4417 True if succeed else raises an exception
4420 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4421 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4425 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4426 except SALOME.SALOME_Exception as inst:
4427 raise ValueError(inst.details.text)
4431 def MoveNode(self, NodeID, x, y, z):
4433 Move the node with the given id
4436 NodeID: the id of the node
4437 x: a new X coordinate
4438 y: a new Y coordinate
4439 z: a new Z coordinate
4442 True if succeed else False
4445 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4446 if hasVars: self.mesh.SetParameters(Parameters)
4447 return self.editor.MoveNode(NodeID, x, y, z)
4449 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4451 Find the node closest to a point and moves it to a point location
4454 x: the X coordinate of a point
4455 y: the Y coordinate of a point
4456 z: the Z coordinate of a point
4457 NodeID: if specified (>0), the node with this ID is moved,
4458 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4461 the ID of a moved node
4464 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4465 if hasVars: self.mesh.SetParameters(Parameters)
4466 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4468 def FindNodeClosestTo(self, x, y, z):
4470 Find the node closest to a point
4473 x: the X coordinate of a point
4474 y: the Y coordinate of a point
4475 z: the Z coordinate of a point
4481 return self.editor.FindNodeClosestTo(x, y, z)
4483 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4485 Find the elements where a point lays IN or ON
4488 x,y,z (float): coordinates of the point
4489 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4490 means elements of any type excluding nodes, discrete and 0D elements.
4491 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4494 list of IDs of found elements
4497 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4499 return self.editor.FindElementsByPoint(x, y, z, elementType)
4501 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4503 Project a point to a mesh object.
4504 Return ID of an element of given type where the given point is projected
4505 and coordinates of the projection point.
4506 In the case if nothing found, return -1 and []
4508 if isinstance( meshObject, Mesh ):
4509 meshObject = meshObject.GetMesh()
4511 meshObject = self.GetMesh()
4512 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4514 def GetPointState(self, x, y, z):
4516 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4517 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4518 UNKNOWN state means that either mesh is wrong or the analysis fails.
4521 return self.editor.GetPointState(x, y, z)
4523 def IsManifold(self):
4525 Check if a 2D mesh is manifold
4528 return self.editor.IsManifold()
4530 def IsCoherentOrientation2D(self):
4532 Check if orientation of 2D elements is coherent
4535 return self.editor.IsCoherentOrientation2D()
4537 def Get1DBranches( self, edges, startNode = 0 ):
4539 Partition given 1D elements into groups of contiguous edges.
4540 A node where number of meeting edges != 2 is a group end.
4541 An optional startNode is used to orient groups it belongs to.
4544 A list of edge groups and a list of corresponding node groups,
4545 where the group is a list of IDs of edges or nodes, like follows
4546 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4547 If a group is closed, the first and last nodes of the group are same.
4549 if isinstance( edges, Mesh ):
4550 edges = edges.GetMesh()
4551 unRegister = genObjUnRegister()
4552 if isinstance( edges, list ):
4553 edges = self.GetIDSource( edges, SMESH.EDGE )
4554 unRegister.set( edges )
4555 return self.editor.Get1DBranches( edges, startNode )
4557 def FindSharpEdges( self, angle, addExisting=False ):
4559 Return sharp edges of faces and non-manifold ones.
4560 Optionally add existing edges.
4563 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4564 addExisting: to return existing edges (1D elements) as well
4567 list of FaceEdge structures
4569 angle = ParseParameters( angle )[0]
4570 return self.editor.FindSharpEdges( angle, addExisting )
4572 def MeshToPassThroughAPoint(self, x, y, z):
4574 Find the node closest to a point and moves it to a point location
4577 x: the X coordinate of a point
4578 y: the Y coordinate of a point
4579 z: the Z coordinate of a point
4582 the ID of a moved node
4585 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4587 def InverseDiag(self, NodeID1, NodeID2):
4589 Replace two neighbour triangles sharing Node1-Node2 link
4590 with the triangles built on the same 4 nodes but having other common link.
4593 NodeID1: the ID of the first node
4594 NodeID2: the ID of the second node
4597 False if proper faces were not found
4599 return self.editor.InverseDiag(NodeID1, NodeID2)
4601 def DeleteDiag(self, NodeID1, NodeID2):
4603 Replace two neighbour triangles sharing *Node1-Node2* link
4604 with a quadrangle built on the same 4 nodes.
4607 NodeID1: ID of the first node
4608 NodeID2: ID of the second node
4611 False if proper faces were not found
4614 This operation can create gaps in numeration of elements.
4615 Call :meth:`RenumberElements` to remove the gaps.
4618 return self.editor.DeleteDiag(NodeID1, NodeID2)
4620 def Reorient(self, IDsOfElements=None):
4622 Reorient elements by ids
4625 IDsOfElements: if undefined reorients all mesh elements
4628 True if succeed else False
4631 if IDsOfElements == None:
4632 IDsOfElements = self.GetElementsId()
4633 return self.editor.Reorient(IDsOfElements)
4635 def ReorientObject(self, theObject):
4637 Reorient all elements of the object
4640 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4643 True if succeed else False
4646 if ( isinstance( theObject, Mesh )):
4647 theObject = theObject.GetMesh()
4648 return self.editor.ReorientObject(theObject)
4650 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4652 Reorient faces contained in *the2DObject*.
4655 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4656 theDirection: a desired direction of normal of *theFace*.
4657 It can be either a GEOM vector or a list of coordinates [x,y,z].
4658 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4659 compared with theDirection. It can be either ID of face or a point
4660 by which the face will be found. The point can be given as either
4661 a GEOM vertex or a list of point coordinates.
4664 number of reoriented faces
4667 unRegister = genObjUnRegister()
4669 if isinstance( the2DObject, Mesh ):
4670 the2DObject = the2DObject.GetMesh()
4671 if isinstance( the2DObject, list ):
4672 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4673 unRegister.set( the2DObject )
4674 # check theDirection
4675 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4676 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4677 if isinstance( theDirection, list ):
4678 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4679 # prepare theFace and thePoint
4680 theFace = theFaceOrPoint
4681 thePoint = PointStruct(0,0,0)
4682 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4683 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4685 if isinstance( theFaceOrPoint, list ):
4686 thePoint = PointStruct( *theFaceOrPoint )
4688 if isinstance( theFaceOrPoint, PointStruct ):
4689 thePoint = theFaceOrPoint
4691 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4693 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4695 Reorient faces according to adjacent volumes.
4698 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4699 either IDs of faces or face groups.
4700 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4701 theOutsideNormal: to orient faces to have their normals
4702 pointing either *outside* or *inside* the adjacent volumes.
4705 number of reoriented faces.
4708 unRegister = genObjUnRegister()
4710 if not isinstance( the2DObject, list ):
4711 the2DObject = [ the2DObject ]
4712 elif the2DObject and isinstance( the2DObject[0], int ):
4713 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4714 unRegister.set( the2DObject )
4715 the2DObject = [ the2DObject ]
4716 for i,obj2D in enumerate( the2DObject ):
4717 if isinstance( obj2D, Mesh ):
4718 the2DObject[i] = obj2D.GetMesh()
4719 if isinstance( obj2D, list ):
4720 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4721 unRegister.set( the2DObject[i] )
4723 if isinstance( the3DObject, Mesh ):
4724 the3DObject = the3DObject.GetMesh()
4725 if isinstance( the3DObject, list ):
4726 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4727 unRegister.set( the3DObject )
4728 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4730 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4732 Fuse the neighbouring triangles into quadrangles.
4735 IDsOfElements: The triangles to be fused.
4736 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4737 applied to possible quadrangles to choose a neighbour to fuse with.
4738 Note that not all items of :class:`SMESH.FunctorType` corresponds
4739 to numerical functors.
4740 MaxAngle: is the maximum angle between element normals at which the fusion
4741 is still performed; theMaxAngle is measured in radians.
4742 Also it could be a name of variable which defines angle in degrees.
4745 True in case of success, False otherwise.
4748 This operation can create gaps in numeration of elements.
4749 Call :meth:`RenumberElements` to remove the gaps.
4752 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4753 self.mesh.SetParameters(Parameters)
4754 if not IDsOfElements:
4755 IDsOfElements = self.GetElementsId()
4756 Functor = self.smeshpyD.GetFunctor(theCriterion)
4757 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4759 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4761 Fuse the neighbouring triangles of the object into quadrangles
4764 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4765 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4766 applied to possible quadrangles to choose a neighbour to fuse with.
4767 Note that not all items of :class:`SMESH.FunctorType` corresponds
4768 to numerical functors.
4769 MaxAngle: a max angle between element normals at which the fusion
4770 is still performed; theMaxAngle is measured in radians.
4773 True in case of success, False otherwise.
4776 This operation can create gaps in numeration of elements.
4777 Call :meth:`RenumberElements` to remove the gaps.
4780 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4781 self.mesh.SetParameters(Parameters)
4782 if isinstance( theObject, Mesh ):
4783 theObject = theObject.GetMesh()
4784 Functor = self.smeshpyD.GetFunctor(theCriterion)
4785 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4787 def QuadToTri (self, IDsOfElements, theCriterion = None):
4789 Split quadrangles into triangles.
4792 IDsOfElements: the faces to be splitted.
4793 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4794 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4795 value, then quadrangles will be split by the smallest diagonal.
4796 Note that not all items of :class:`SMESH.FunctorType` corresponds
4797 to numerical functors.
4800 True in case of success, False otherwise.
4803 This operation can create gaps in numeration of elements.
4804 Call :meth:`RenumberElements` to remove the gaps.
4806 if IDsOfElements == []:
4807 IDsOfElements = self.GetElementsId()
4808 if theCriterion is None:
4809 theCriterion = FT_MaxElementLength2D
4810 Functor = self.smeshpyD.GetFunctor(theCriterion)
4811 return self.editor.QuadToTri(IDsOfElements, Functor)
4813 def QuadToTriObject (self, theObject, theCriterion = None):
4815 Split quadrangles into triangles.
4818 theObject: the object from which the list of elements is taken,
4819 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4820 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4821 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4822 value, then quadrangles will be split by the smallest diagonal.
4823 Note that not all items of :class:`SMESH.FunctorType` corresponds
4824 to numerical functors.
4827 True in case of success, False otherwise.
4830 This operation can create gaps in numeration of elements.
4831 Call :meth:`RenumberElements` to remove the gaps.
4833 if ( isinstance( theObject, Mesh )):
4834 theObject = theObject.GetMesh()
4835 if theCriterion is None:
4836 theCriterion = FT_MaxElementLength2D
4837 Functor = self.smeshpyD.GetFunctor(theCriterion)
4838 return self.editor.QuadToTriObject(theObject, Functor)
4840 def QuadTo4Tri (self, theElements=[]):
4842 Split each of given quadrangles into 4 triangles. A node is added at the center of
4846 theElements: the faces to be splitted. This can be either
4847 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4848 or a list of face IDs. By default all quadrangles are split
4851 This operation can create gaps in numeration of elements.
4852 Call :meth:`RenumberElements` to remove the gaps.
4854 unRegister = genObjUnRegister()
4855 if isinstance( theElements, Mesh ):
4856 theElements = theElements.mesh
4857 elif not theElements:
4858 theElements = self.mesh
4859 elif isinstance( theElements, list ):
4860 theElements = self.GetIDSource( theElements, SMESH.FACE )
4861 unRegister.set( theElements )
4862 return self.editor.QuadTo4Tri( theElements )
4864 def SplitQuad (self, IDsOfElements, Diag13):
4866 Split quadrangles into triangles.
4869 IDsOfElements: the faces to be splitted
4870 Diag13 (boolean): is used to choose a diagonal for splitting.
4873 True in case of success, False otherwise.
4876 This operation can create gaps in numeration of elements.
4877 Call :meth:`RenumberElements` to remove the gaps.
4879 if IDsOfElements == []:
4880 IDsOfElements = self.GetElementsId()
4881 return self.editor.SplitQuad(IDsOfElements, Diag13)
4883 def SplitQuadObject (self, theObject, Diag13):
4885 Split quadrangles into triangles.
4888 theObject: the object from which the list of elements is taken,
4889 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4890 Diag13 (boolean): is used to choose a diagonal for splitting.
4893 True in case of success, False otherwise.
4896 This operation can create gaps in numeration of elements.
4897 Call :meth:`RenumberElements` to remove the gaps.
4899 if ( isinstance( theObject, Mesh )):
4900 theObject = theObject.GetMesh()
4901 return self.editor.SplitQuadObject(theObject, Diag13)
4903 def BestSplit (self, IDOfQuad, theCriterion):
4905 Find a better splitting of the given quadrangle.
4908 IDOfQuad: the ID of the quadrangle to be splitted.
4909 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4910 choose a diagonal for splitting.
4911 Note that not all items of :class:`SMESH.FunctorType` corresponds
4912 to numerical functors.
4915 * 1 if 1-3 diagonal is better,
4916 * 2 if 2-4 diagonal is better,
4917 * 0 if error occurs.
4920 This operation can create gaps in numeration of elements.
4921 Call :meth:`RenumberElements` to remove the gaps.
4923 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4925 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4927 Split volumic elements into tetrahedrons
4930 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4931 method: flags passing splitting method:
4932 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4933 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4936 This operation can create gaps in numeration of elements.
4937 Call :meth:`RenumberElements` to remove the gaps.
4939 unRegister = genObjUnRegister()
4940 if isinstance( elems, Mesh ):
4941 elems = elems.GetMesh()
4942 if ( isinstance( elems, list )):
4943 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4944 unRegister.set( elems )
4945 self.editor.SplitVolumesIntoTetra(elems, method)
4948 def SplitBiQuadraticIntoLinear(self, elems=None):
4950 Split bi-quadratic elements into linear ones without creation of additional nodes:
4952 - bi-quadratic triangle will be split into 3 linear quadrangles;
4953 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4954 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4956 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4957 will be split in order to keep the mesh conformal.
4960 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4961 if None (default), all bi-quadratic elements will be split
4964 This operation can create gaps in numeration of elements.
4965 Call :meth:`RenumberElements` to remove the gaps.
4967 unRegister = genObjUnRegister()
4968 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4969 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4970 unRegister.set( elems )
4972 elems = [ self.GetMesh() ]
4973 if isinstance( elems, Mesh ):
4974 elems = [ elems.GetMesh() ]
4975 if not isinstance( elems, list ):
4977 self.editor.SplitBiQuadraticIntoLinear( elems )
4979 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4980 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4982 Split hexahedra into prisms
4985 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4986 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4987 gives a normal vector defining facets to split into triangles.
4988 *startHexPoint* can be either a triple of coordinates or a vertex.
4989 facetNormal: a normal to a facet to split into triangles of a
4990 hexahedron found by *startHexPoint*.
4991 *facetNormal* can be either a triple of coordinates or an edge.
4992 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4993 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4994 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4995 to *startHexPoint* are split, else *startHexPoint*
4996 is used to find the facet to split in all domains present in *elems*.
4999 This operation can create gaps in numeration of elements.
5000 Call :meth:`RenumberElements` to remove the gaps.
5003 unRegister = genObjUnRegister()
5004 if isinstance( elems, Mesh ):
5005 elems = elems.GetMesh()
5006 if ( isinstance( elems, list )):
5007 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5008 unRegister.set( elems )
5011 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5012 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5013 elif isinstance( startHexPoint, list ):
5014 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5017 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5018 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5019 elif isinstance( facetNormal, list ):
5020 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5023 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5025 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5027 def SplitQuadsNearTriangularFacets(self):
5029 Split quadrangle faces near triangular facets of volumes
5032 This operation can create gaps in numeration of elements.
5033 Call :meth:`RenumberElements` to remove the gaps.
5035 faces_array = self.GetElementsByType(SMESH.FACE)
5036 for face_id in faces_array:
5037 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5038 quad_nodes = self.mesh.GetElemNodes(face_id)
5039 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5040 isVolumeFound = False
5041 for node1_elem in node1_elems:
5042 if not isVolumeFound:
5043 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5044 nb_nodes = self.GetElemNbNodes(node1_elem)
5045 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5046 volume_elem = node1_elem
5047 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5048 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5049 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5050 isVolumeFound = True
5051 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5052 self.SplitQuad([face_id], False) # diagonal 2-4
5053 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5054 isVolumeFound = True
5055 self.SplitQuad([face_id], True) # diagonal 1-3
5056 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5057 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5058 isVolumeFound = True
5059 self.SplitQuad([face_id], True) # diagonal 1-3
5061 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5063 Split hexahedrons into tetrahedrons.
5065 This operation uses :doc:`pattern_mapping` functionality for splitting.
5068 theObject: the object from which the list of hexahedrons is taken;
5069 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5070 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5071 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5072 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5073 key-point will be mapped into *theNode001*-th node of each volume.
5074 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5077 True in case of success, False otherwise.
5080 This operation can create gaps in numeration of elements.
5081 Call :meth:`RenumberElements` to remove the gaps.
5089 # (0,0,1) 4.---------.7 * |
5096 # (0,0,0) 0.---------.3
5097 pattern_tetra = "!!! Nb of points: \n 8 \n\
5107 !!! Indices of points of 6 tetras: \n\
5115 pattern = self.smeshpyD.GetPattern()
5116 isDone = pattern.LoadFromFile(pattern_tetra)
5118 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5121 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5122 isDone = pattern.MakeMesh(self.mesh, False, False)
5123 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5125 # split quafrangle faces near triangular facets of volumes
5126 self.SplitQuadsNearTriangularFacets()
5130 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5132 Split hexahedrons into prisms.
5134 Uses the :doc:`pattern_mapping` functionality for splitting.
5137 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5138 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5139 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5140 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5141 will be mapped into the *theNode001* -th node of each volume.
5142 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5145 True in case of success, False otherwise.
5148 This operation can create gaps in numeration of elements.
5149 Call :meth:`RenumberElements` to remove the gaps.
5151 # Pattern: 5.---------.6
5156 # (0,0,1) 4.---------.7 |
5163 # (0,0,0) 0.---------.3
5164 pattern_prism = "!!! Nb of points: \n 8 \n\
5174 !!! Indices of points of 2 prisms: \n\
5178 pattern = self.smeshpyD.GetPattern()
5179 isDone = pattern.LoadFromFile(pattern_prism)
5181 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5184 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5185 isDone = pattern.MakeMesh(self.mesh, False, False)
5186 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5188 # Split quafrangle faces near triangular facets of volumes
5189 self.SplitQuadsNearTriangularFacets()
5193 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5194 MaxNbOfIterations, MaxAspectRatio, Method):
5199 IDsOfElements: the list if ids of elements to smooth
5200 IDsOfFixedNodes: the list of ids of fixed nodes.
5201 Note that nodes built on edges and boundary nodes are always fixed.
5202 MaxNbOfIterations: the maximum number of iterations
5203 MaxAspectRatio: varies in range [1.0, inf]
5204 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5205 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5208 True in case of success, False otherwise.
5211 if IDsOfElements == []:
5212 IDsOfElements = self.GetElementsId()
5213 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5214 self.mesh.SetParameters(Parameters)
5215 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5216 MaxNbOfIterations, MaxAspectRatio, Method)
5218 def SmoothObject(self, theObject, IDsOfFixedNodes,
5219 MaxNbOfIterations, MaxAspectRatio, Method):
5221 Smooth elements which belong to the given object
5224 theObject: the object to smooth
5225 IDsOfFixedNodes: the list of ids of fixed nodes.
5226 Note that nodes built on edges and boundary nodes are always fixed.
5227 MaxNbOfIterations: the maximum number of iterations
5228 MaxAspectRatio: varies in range [1.0, inf]
5229 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5230 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5233 True in case of success, False otherwise.
5236 if ( isinstance( theObject, Mesh )):
5237 theObject = theObject.GetMesh()
5238 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5239 MaxNbOfIterations, MaxAspectRatio, Method)
5241 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5242 MaxNbOfIterations, MaxAspectRatio, Method):
5244 Parametrically smooth the given elements
5247 IDsOfElements: the list if ids of elements to smooth
5248 IDsOfFixedNodes: the list of ids of fixed nodes.
5249 Note that nodes built on edges and boundary nodes are always fixed.
5250 MaxNbOfIterations: the maximum number of iterations
5251 MaxAspectRatio: varies in range [1.0, inf]
5252 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5253 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5256 True in case of success, False otherwise.
5259 if IDsOfElements == []:
5260 IDsOfElements = self.GetElementsId()
5261 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5262 self.mesh.SetParameters(Parameters)
5263 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5264 MaxNbOfIterations, MaxAspectRatio, Method)
5266 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5267 MaxNbOfIterations, MaxAspectRatio, Method):
5269 Parametrically smooth the elements which belong to the given object
5272 theObject: the object to smooth
5273 IDsOfFixedNodes: the list of ids of fixed nodes.
5274 Note that nodes built on edges and boundary nodes are always fixed.
5275 MaxNbOfIterations: the maximum number of iterations
5276 MaxAspectRatio: varies in range [1.0, inf]
5277 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5278 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5281 True in case of success, False otherwise.
5284 if ( isinstance( theObject, Mesh )):
5285 theObject = theObject.GetMesh()
5286 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5287 MaxNbOfIterations, MaxAspectRatio, Method)
5289 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5291 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5292 them with quadratic with the same id.
5295 theForce3d: method of new node creation:
5297 * False - the medium node lies at the geometrical entity from which the mesh element is built
5298 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5299 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5300 theToBiQuad: If True, converts the mesh to bi-quadratic
5303 :class:`SMESH.ComputeError` which can hold a warning
5306 If *theSubMesh* is provided, the mesh can become non-conformal
5309 This operation can create gaps in numeration of nodes or elements.
5310 Call :meth:`RenumberElements` to remove the gaps.
5313 if isinstance( theSubMesh, Mesh ):
5314 theSubMesh = theSubMesh.mesh
5316 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5319 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5321 self.editor.ConvertToQuadratic(theForce3d)
5322 error = self.editor.GetLastError()
5323 if error and error.comment:
5324 print(error.comment)
5327 def ConvertFromQuadratic(self, theSubMesh=None):
5329 Convert the mesh from quadratic to ordinary,
5330 deletes old quadratic elements,
5331 replacing them with ordinary mesh elements with the same id.
5334 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5337 If *theSubMesh* is provided, the mesh can become non-conformal
5340 This operation can create gaps in numeration of nodes or elements.
5341 Call :meth:`RenumberElements` to remove the gaps.
5345 self.editor.ConvertFromQuadraticObject(theSubMesh)
5347 return self.editor.ConvertFromQuadratic()
5349 def Make2DMeshFrom3D(self):
5351 Create 2D mesh as skin on boundary faces of a 3D mesh
5354 True if operation has been completed successfully, False otherwise
5357 return self.editor.Make2DMeshFrom3D()
5359 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5360 toCopyElements=False, toCopyExistingBondary=False):
5362 Create missing boundary elements
5365 elements: elements whose boundary is to be checked:
5366 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5367 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5368 dimension: defines type of boundary elements to create, either of
5369 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5370 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5371 groupName: a name of group to store created boundary elements in,
5372 "" means not to create the group
5373 meshName: a name of new mesh to store created boundary elements in,
5374 "" means not to create the new mesh
5375 toCopyElements: if True, the checked elements will be copied into
5376 the new mesh else only boundary elements will be copied into the new mesh
5377 toCopyExistingBondary: if True, not only new but also pre-existing
5378 boundary elements will be copied into the new mesh
5381 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5384 unRegister = genObjUnRegister()
5385 if isinstance( elements, Mesh ):
5386 elements = elements.GetMesh()
5387 if ( isinstance( elements, list )):
5388 elemType = SMESH.ALL
5389 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5390 elements = self.editor.MakeIDSource(elements, elemType)
5391 unRegister.set( elements )
5392 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5393 toCopyElements,toCopyExistingBondary)
5394 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5397 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5398 toCopyAll=False, groups=[]):
5400 Create missing boundary elements around either the whole mesh or
5404 dimension: defines type of boundary elements to create, either of
5405 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5406 groupName: a name of group to store all boundary elements in,
5407 "" means not to create the group
5408 meshName: a name of a new mesh, which is a copy of the initial
5409 mesh + created boundary elements; "" means not to create the new mesh
5410 toCopyAll: if True, the whole initial mesh will be copied into
5411 the new mesh else only boundary elements will be copied into the new mesh
5412 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5415 tuple( long, mesh, group )
5416 - long - number of added boundary elements
5417 - mesh - the :class:`Mesh` where elements were added to
5418 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5421 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5423 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5424 return nb, mesh, group
5426 def RenumberNodes(self):
5428 Renumber mesh nodes to remove unused node IDs
5430 self.editor.RenumberNodes()
5432 def RenumberElements(self):
5434 Renumber mesh elements to remove unused element IDs
5436 self.editor.RenumberElements()
5438 def _getIdSourceList(self, arg, idType, unRegister):
5440 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5442 if arg and isinstance( arg, list ):
5443 if isinstance( arg[0], int ):
5444 arg = self.GetIDSource( arg, idType )
5445 unRegister.set( arg )
5446 elif isinstance( arg[0], Mesh ):
5447 arg[0] = arg[0].GetMesh()
5448 elif isinstance( arg, Mesh ):
5450 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5454 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5455 MakeGroups=False, TotalAngle=False):
5457 Generate new elements by rotation of the given elements and nodes around the axis
5460 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5461 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5462 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5463 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5464 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5465 which defines angle in degrees
5466 NbOfSteps: the number of steps
5467 Tolerance: tolerance
5468 MakeGroups: forces the generation of new groups from existing ones
5469 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5470 of all steps, else - size of each step
5473 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5476 unRegister = genObjUnRegister()
5477 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5478 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5479 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5481 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5482 Axis = self.smeshpyD.GetAxisStruct( Axis )
5483 if isinstance( Axis, list ):
5484 Axis = SMESH.AxisStruct( *Axis )
5486 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5487 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5488 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5489 self.mesh.SetParameters(Parameters)
5490 if TotalAngle and NbOfSteps:
5491 AngleInRadians /= NbOfSteps
5492 return self.editor.RotationSweepObjects( nodes, edges, faces,
5493 Axis, AngleInRadians,
5494 NbOfSteps, Tolerance, MakeGroups)
5496 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5497 MakeGroups=False, TotalAngle=False):
5499 Generate new elements by rotation of the elements around the axis
5502 IDsOfElements: the list of ids of elements to sweep
5503 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5504 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5505 NbOfSteps: the number of steps
5506 Tolerance: tolerance
5507 MakeGroups: forces the generation of new groups from existing ones
5508 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5509 of all steps, else - size of each step
5512 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5515 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5516 AngleInRadians, NbOfSteps, Tolerance,
5517 MakeGroups, TotalAngle)
5519 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5520 MakeGroups=False, TotalAngle=False):
5522 Generate new elements by rotation of the elements of object around the axis
5523 theObject object which elements should be sweeped.
5524 It can be a mesh, a sub mesh or a group.
5527 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5528 AngleInRadians: the angle of Rotation
5529 NbOfSteps: number of steps
5530 Tolerance: tolerance
5531 MakeGroups: forces the generation of new groups from existing ones
5532 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5533 of all steps, else - size of each step
5536 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5539 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5540 AngleInRadians, NbOfSteps, Tolerance,
5541 MakeGroups, TotalAngle )
5543 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5544 MakeGroups=False, TotalAngle=False):
5546 Generate new elements by rotation of the elements of object around the axis
5547 theObject object which elements should be sweeped.
5548 It can be a mesh, a sub mesh or a group.
5551 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5552 AngleInRadians: the angle of Rotation
5553 NbOfSteps: number of steps
5554 Tolerance: tolerance
5555 MakeGroups: forces the generation of new groups from existing ones
5556 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5557 of all steps, else - size of each step
5560 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5561 empty list otherwise
5564 return self.RotationSweepObjects([],theObject,[], Axis,
5565 AngleInRadians, NbOfSteps, Tolerance,
5566 MakeGroups, TotalAngle)
5568 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5569 MakeGroups=False, TotalAngle=False):
5571 Generate new elements by rotation of the elements of object around the axis
5572 theObject object which elements should be sweeped.
5573 It can be a mesh, a sub mesh or a group.
5576 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5577 AngleInRadians: the angle of Rotation
5578 NbOfSteps: number of steps
5579 Tolerance: tolerance
5580 MakeGroups: forces the generation of new groups from existing ones
5581 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5582 of all steps, else - size of each step
5585 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5588 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5589 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5591 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5592 scaleFactors=[], linearVariation=False, basePoint=[],
5593 angles=[], anglesVariation=False):
5595 Generate new elements by extrusion of the given elements and nodes
5598 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5599 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5600 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5601 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5602 the direction and value of extrusion for one step (the total extrusion
5603 length will be NbOfSteps * ||StepVector||)
5604 NbOfSteps: the number of steps
5605 MakeGroups: forces the generation of new groups from existing ones
5606 scaleFactors: optional scale factors to apply during extrusion
5607 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5608 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5609 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5610 nodes and elements being extruded is used as the scaling center.
5613 - a list of tree components of the point or
5616 angles: list of angles in radians. Nodes at each extrusion step are rotated
5617 around *basePoint*, additionally to previous steps.
5618 anglesVariation: forces the computation of rotation angles as linear
5619 variation of the given *angles* along path steps
5621 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5623 Example: :ref:`tui_extrusion`
5625 unRegister = genObjUnRegister()
5626 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5627 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5628 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5630 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5631 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5632 if isinstance( StepVector, list ):
5633 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5635 if isinstance( basePoint, int):
5636 xyz = self.GetNodeXYZ( basePoint )
5638 raise RuntimeError("Invalid node ID: %s" % basePoint)
5640 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5641 basePoint = self.geompyD.PointCoordinates( basePoint )
5643 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5644 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5645 angles,angleParameters,hasVars = ParseAngles(angles)
5646 Parameters = StepVector.PS.parameters + var_separator + \
5647 Parameters + var_separator + \
5648 scaleParameters + var_separator + angleParameters
5649 self.mesh.SetParameters(Parameters)
5651 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5652 StepVector, NbOfSteps, MakeGroups,
5653 scaleFactors, linearVariation, basePoint,
5654 angles, anglesVariation )
5657 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5659 Generate new elements by extrusion of the elements with given ids
5662 IDsOfElements: the list of ids of elements or nodes for extrusion
5663 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5664 the direction and value of extrusion for one step (the total extrusion
5665 length will be NbOfSteps * ||StepVector||)
5666 NbOfSteps: the number of steps
5667 MakeGroups: forces the generation of new groups from existing ones
5668 IsNodes: is True if elements with given ids are nodes
5671 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5673 Example: :ref:`tui_extrusion`
5676 if IsNodes: n = IDsOfElements
5677 else : e,f, = IDsOfElements,IDsOfElements
5678 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5680 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5681 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5683 Generate new elements by extrusion along the normal to a discretized surface or wire
5686 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5687 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5688 StepSize: length of one extrusion step (the total extrusion
5689 length will be *NbOfSteps* *StepSize*).
5690 NbOfSteps: number of extrusion steps.
5691 ByAverageNormal: if True each node is translated by *StepSize*
5692 along the average of the normal vectors to the faces sharing the node;
5693 else each node is translated along the same average normal till
5694 intersection with the plane got by translation of the face sharing
5695 the node along its own normal by *StepSize*.
5696 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5697 for every node of *Elements*.
5698 MakeGroups: forces generation of new groups from existing ones.
5699 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5700 is not yet implemented. This parameter is used if *Elements* contains
5701 both faces and edges, i.e. *Elements* is a Mesh.
5704 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5705 empty list otherwise.
5706 Example: :ref:`tui_extrusion`
5709 unRegister = genObjUnRegister()
5710 if isinstance( Elements, Mesh ):
5711 Elements = [ Elements.GetMesh() ]
5712 if isinstance( Elements, list ):
5714 raise RuntimeError("Elements empty!")
5715 if isinstance( Elements[0], Mesh ):
5716 Elements = [ Elements[0].GetMesh() ]
5717 if isinstance( Elements[0], int ):
5718 Elements = self.GetIDSource( Elements, SMESH.ALL )
5719 unRegister.set( Elements )
5720 if not isinstance( Elements, list ):
5721 Elements = [ Elements ]
5722 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5723 self.mesh.SetParameters(Parameters)
5724 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5725 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5727 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5729 Generate new elements by extrusion of the elements or nodes which belong to the object
5732 theObject: the object whose elements or nodes should be processed.
5733 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5734 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5735 the direction and value of extrusion for one step (the total extrusion
5736 length will be NbOfSteps * ||StepVector||)
5737 NbOfSteps: the number of steps
5738 MakeGroups: forces the generation of new groups from existing ones
5739 IsNodes: is True if elements to extrude are nodes
5742 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5743 Example: :ref:`tui_extrusion`
5747 if IsNodes: n = theObject
5748 else : e,f, = theObject,theObject
5749 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5751 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5753 Generate new elements by extrusion of edges which belong to the object
5756 theObject: object whose 1D elements should be processed.
5757 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5758 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5759 the direction and value of extrusion for one step (the total extrusion
5760 length will be NbOfSteps * ||StepVector||)
5761 NbOfSteps: the number of steps
5762 MakeGroups: to generate new groups from existing ones
5765 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5766 Example: :ref:`tui_extrusion`
5769 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5771 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5773 Generate new elements by extrusion of faces which belong to the object
5776 theObject: object whose 2D elements should be processed.
5777 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5778 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5779 the direction and value of extrusion for one step (the total extrusion
5780 length will be NbOfSteps * ||StepVector||)
5781 NbOfSteps: the number of steps
5782 MakeGroups: forces the generation of new groups from existing ones
5785 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5786 Example: :ref:`tui_extrusion`
5789 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5791 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5792 ExtrFlags, SewTolerance, MakeGroups=False):
5794 Generate new elements by extrusion of the elements with given ids
5797 IDsOfElements: is ids of elements
5798 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5799 the direction and value of extrusion for one step (the total extrusion
5800 length will be NbOfSteps * ||StepVector||)
5801 NbOfSteps: the number of steps
5802 ExtrFlags: sets flags for extrusion
5803 SewTolerance: uses for comparing locations of nodes if flag
5804 EXTRUSION_FLAG_SEW is set
5805 MakeGroups: forces the generation of new groups from existing ones
5808 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5811 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5812 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5813 if isinstance( StepVector, list ):
5814 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5815 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5816 ExtrFlags, SewTolerance, MakeGroups)
5818 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5819 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5820 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5821 ScaleFactors=[], ScalesVariation=False):
5823 Generate new elements by extrusion of the given elements and nodes along the path.
5824 The path of extrusion must be a meshed edge.
5827 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5828 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5829 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5830 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5831 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
5832 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5833 HasAngles: not used obsolete
5834 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5835 around *basePoint*, additionally to previous steps.
5836 LinearVariation: forces the computation of rotation angles as linear
5837 variation of the given Angles along path steps
5838 HasRefPoint: allows using the reference point
5839 RefPoint: optional scaling and rotation center (mass center of the extruded
5840 elements by default). The User can specify any point as the Reference Point.
5841 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5842 MakeGroups: forces the generation of new groups from existing ones
5843 ScaleFactors: optional scale factors to apply during extrusion
5844 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5845 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5848 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5849 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5850 Example: :ref:`tui_extrusion_along_path`
5853 unRegister = genObjUnRegister()
5854 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5855 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5856 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5858 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5859 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5860 if isinstance( RefPoint, list ):
5861 if not RefPoint: RefPoint = [0,0,0]
5862 RefPoint = SMESH.PointStruct( *RefPoint )
5863 if isinstance( PathObject, Mesh ):
5864 PathObject = PathObject.GetMesh()
5865 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5866 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5867 Parameters = AnglesParameters + var_separator + \
5868 RefPoint.parameters + var_separator + ScalesParameters
5869 self.mesh.SetParameters(Parameters)
5870 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5871 PathObject, PathShape, NodeStart,
5872 HasAngles, Angles, LinearVariation,
5873 HasRefPoint, RefPoint, MakeGroups,
5874 ScaleFactors, ScalesVariation)
5876 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5877 HasAngles=False, Angles=[], LinearVariation=False,
5878 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5879 ElemType=SMESH.FACE):
5881 Generate new elements by extrusion of the given elements.
5882 The path of extrusion must be a meshed edge.
5885 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5886 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5887 NodeStart: the start node from Path. Defines the direction of extrusion
5888 HasAngles: not used obsolete
5889 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5890 around *basePoint*, additionally to previous steps.
5891 LinearVariation: forces the computation of rotation angles as linear
5892 variation of the given Angles along path steps
5893 HasRefPoint: allows using the reference point
5894 RefPoint: the reference point around which the elements are rotated (the mass
5895 center of the elements by default).
5896 The User can specify any point as the Reference Point.
5897 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5898 MakeGroups: forces the generation of new groups from existing ones
5899 ElemType: type of elements for extrusion (if param Base is a mesh)
5902 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5903 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5904 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5906 Example: :ref:`tui_extrusion_along_path`
5910 if ElemType == SMESH.NODE: n = Base
5911 if ElemType == SMESH.EDGE: e = Base
5912 if ElemType == SMESH.FACE: f = Base
5913 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5914 HasAngles, Angles, LinearVariation,
5915 HasRefPoint, RefPoint, MakeGroups)
5916 if MakeGroups: return gr,er
5919 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5920 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5921 MakeGroups=False, LinearVariation=False):
5923 Generate new elements by extrusion of the given elements.
5924 The path of extrusion must be a meshed edge.
5927 IDsOfElements: ids of elements
5928 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5929 PathShape: shape (edge) defines the sub-mesh for the path
5930 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5931 HasAngles: not used obsolete
5932 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5933 around *basePoint*, additionally to previous steps.
5934 HasRefPoint: allows using the reference point
5935 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5936 The User can specify any point as the Reference Point.
5937 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5938 MakeGroups: forces the generation of new groups from existing ones
5939 LinearVariation: forces the computation of rotation angles as linear
5940 variation of the given Angles along path steps
5943 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5944 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5945 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5946 Example: :ref:`tui_extrusion_along_path`
5949 if not IDsOfElements:
5950 IDsOfElements = [ self.GetMesh() ]
5951 n,e,f = [],IDsOfElements,IDsOfElements
5952 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5953 NodeStart, HasAngles, Angles,
5955 HasRefPoint, RefPoint, MakeGroups)
5956 if MakeGroups: return gr,er
5959 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5960 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5961 MakeGroups=False, LinearVariation=False):
5963 Generate new elements by extrusion of the elements which belong to the object.
5964 The path of extrusion must be a meshed edge.
5967 theObject: the object whose elements should be processed.
5968 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5969 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5970 PathShape: shape (edge) defines the sub-mesh for the path
5971 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5972 HasAngles: not used obsolete
5973 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5974 around *basePoint*, additionally to previous steps.
5975 HasRefPoint: allows using the reference point
5976 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5977 The User can specify any point as the Reference Point.
5978 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5979 MakeGroups: forces the generation of new groups from existing ones
5980 LinearVariation: forces the computation of rotation angles as linear
5981 variation of the given Angles along path steps
5984 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5985 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5986 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5987 Example: :ref:`tui_extrusion_along_path`
5990 n,e,f = [],theObject,theObject
5991 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5992 HasAngles, Angles, LinearVariation,
5993 HasRefPoint, RefPoint, MakeGroups)
5994 if MakeGroups: return gr,er
5997 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5998 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5999 MakeGroups=False, LinearVariation=False):
6001 Generate new elements by extrusion of mesh segments which belong to the object.
6002 The path of extrusion must be a meshed edge.
6005 theObject: the object whose 1D elements should be processed.
6006 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6007 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6008 PathShape: shape (edge) defines the sub-mesh for the path
6009 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6010 HasAngles: not used obsolete
6011 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6012 around *basePoint*, additionally to previous steps.
6013 HasRefPoint: allows using the reference point
6014 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6015 The User can specify any point as the Reference Point.
6016 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6017 MakeGroups: forces the generation of new groups from existing ones
6018 LinearVariation: forces the computation of rotation angles as linear
6019 variation of the given Angles along path steps
6022 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6023 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6024 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6025 Example: :ref:`tui_extrusion_along_path`
6028 n,e,f = [],theObject,[]
6029 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6030 HasAngles, Angles, LinearVariation,
6031 HasRefPoint, RefPoint, MakeGroups)
6032 if MakeGroups: return gr,er
6035 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6036 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6037 MakeGroups=False, LinearVariation=False):
6039 Generate new elements by extrusion of faces which belong to the object.
6040 The path of extrusion must be a meshed edge.
6043 theObject: the object whose 2D elements should be processed.
6044 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6045 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6046 PathShape: shape (edge) defines the sub-mesh for the path
6047 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6048 HasAngles: not used obsolete
6049 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6050 around *basePoint*, additionally to previous steps.
6051 HasRefPoint: allows using the reference point
6052 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6053 The User can specify any point as the Reference Point.
6054 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6055 MakeGroups: forces the generation of new groups from existing ones
6056 LinearVariation: forces the computation of rotation angles as linear
6057 variation of the given Angles along path steps
6060 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6061 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6062 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6063 Example: :ref:`tui_extrusion_along_path`
6066 n,e,f = [],[],theObject
6067 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6068 HasAngles, Angles, LinearVariation,
6069 HasRefPoint, RefPoint, MakeGroups)
6070 if MakeGroups: return gr,er
6073 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6075 Create a symmetrical copy of mesh elements
6078 IDsOfElements: list of elements ids
6079 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6080 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6081 If the *Mirror* is a geom object this parameter is unnecessary
6082 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6083 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6086 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6089 if IDsOfElements == []:
6090 IDsOfElements = self.GetElementsId()
6091 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6092 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6093 theMirrorType = Mirror._mirrorType
6095 self.mesh.SetParameters(Mirror.parameters)
6096 if Copy and MakeGroups:
6097 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6098 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6101 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6103 Create a new mesh by a symmetrical copy of mesh elements
6106 IDsOfElements: the list of elements ids
6107 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6108 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6109 If the *Mirror* is a geom object this parameter is unnecessary
6110 MakeGroups: to generate new groups from existing ones
6111 NewMeshName: a name of the new mesh to create
6114 instance of class :class:`Mesh`
6117 if IDsOfElements == []:
6118 IDsOfElements = self.GetElementsId()
6119 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6120 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6121 theMirrorType = Mirror._mirrorType
6123 self.mesh.SetParameters(Mirror.parameters)
6124 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6125 MakeGroups, NewMeshName)
6126 return Mesh(self.smeshpyD,self.geompyD,mesh)
6128 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6130 Create a symmetrical copy of the object
6133 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6134 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6135 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6136 If the *Mirror* is a geom object this parameter is unnecessary
6137 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6138 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6141 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6144 if ( isinstance( theObject, Mesh )):
6145 theObject = theObject.GetMesh()
6146 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6147 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6148 theMirrorType = Mirror._mirrorType
6150 self.mesh.SetParameters(Mirror.parameters)
6151 if Copy and MakeGroups:
6152 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6153 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6156 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6158 Create a new mesh by a symmetrical copy of the object
6161 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6162 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6163 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6164 If the *Mirror* is a geom object this parameter is unnecessary
6165 MakeGroups: forces the generation of new groups from existing ones
6166 NewMeshName: the name of the new mesh to create
6169 instance of class :class:`Mesh`
6172 if ( isinstance( theObject, Mesh )):
6173 theObject = theObject.GetMesh()
6174 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6175 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6176 theMirrorType = Mirror._mirrorType
6178 self.mesh.SetParameters(Mirror.parameters)
6179 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6180 MakeGroups, NewMeshName)
6181 return Mesh( self.smeshpyD,self.geompyD,mesh )
6183 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6185 Translate the elements
6188 IDsOfElements: list of elements ids
6189 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6190 Copy: allows copying the translated elements
6191 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6194 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6197 if IDsOfElements == []:
6198 IDsOfElements = self.GetElementsId()
6199 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6200 Vector = self.smeshpyD.GetDirStruct(Vector)
6201 if isinstance( Vector, list ):
6202 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6203 self.mesh.SetParameters(Vector.PS.parameters)
6204 if Copy and MakeGroups:
6205 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6206 self.editor.Translate(IDsOfElements, Vector, Copy)
6209 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6211 Create a new mesh of translated elements
6214 IDsOfElements: list of elements ids
6215 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6216 MakeGroups: forces the generation of new groups from existing ones
6217 NewMeshName: the name of the newly created mesh
6220 instance of class :class:`Mesh`
6223 if IDsOfElements == []:
6224 IDsOfElements = self.GetElementsId()
6225 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6226 Vector = self.smeshpyD.GetDirStruct(Vector)
6227 if isinstance( Vector, list ):
6228 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6229 self.mesh.SetParameters(Vector.PS.parameters)
6230 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6231 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6233 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6235 Translate the object
6238 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6239 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6240 Copy: allows copying the translated elements
6241 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6244 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6247 if ( isinstance( theObject, Mesh )):
6248 theObject = theObject.GetMesh()
6249 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6250 Vector = self.smeshpyD.GetDirStruct(Vector)
6251 if isinstance( Vector, list ):
6252 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6253 self.mesh.SetParameters(Vector.PS.parameters)
6254 if Copy and MakeGroups:
6255 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6256 self.editor.TranslateObject(theObject, Vector, Copy)
6259 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6261 Create a new mesh from the translated object
6264 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6265 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6266 MakeGroups: forces the generation of new groups from existing ones
6267 NewMeshName: the name of the newly created mesh
6270 instance of class :class:`Mesh`
6273 if isinstance( theObject, Mesh ):
6274 theObject = theObject.GetMesh()
6275 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6276 Vector = self.smeshpyD.GetDirStruct(Vector)
6277 if isinstance( Vector, list ):
6278 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6279 self.mesh.SetParameters(Vector.PS.parameters)
6280 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6281 return Mesh( self.smeshpyD, self.geompyD, mesh )
6285 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6290 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6291 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6292 theScaleFact: list of 1-3 scale factors for axises
6293 Copy: allows copying the translated elements
6294 MakeGroups: forces the generation of new groups from existing
6298 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6299 empty list otherwise
6301 unRegister = genObjUnRegister()
6302 if ( isinstance( theObject, Mesh )):
6303 theObject = theObject.GetMesh()
6304 if ( isinstance( theObject, list )):
6305 theObject = self.GetIDSource(theObject, SMESH.ALL)
6306 unRegister.set( theObject )
6307 if ( isinstance( thePoint, list )):
6308 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6309 if ( isinstance( theScaleFact, float )):
6310 theScaleFact = [theScaleFact]
6311 if ( isinstance( theScaleFact, int )):
6312 theScaleFact = [ float(theScaleFact)]
6314 self.mesh.SetParameters(thePoint.parameters)
6316 if Copy and MakeGroups:
6317 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6318 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6321 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6323 Create a new mesh from the translated object
6326 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6327 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6328 theScaleFact: list of 1-3 scale factors for axises
6329 MakeGroups: forces the generation of new groups from existing ones
6330 NewMeshName: the name of the newly created mesh
6333 instance of class :class:`Mesh`
6335 unRegister = genObjUnRegister()
6336 if (isinstance(theObject, Mesh)):
6337 theObject = theObject.GetMesh()
6338 if ( isinstance( theObject, list )):
6339 theObject = self.GetIDSource(theObject,SMESH.ALL)
6340 unRegister.set( theObject )
6341 if ( isinstance( thePoint, list )):
6342 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6343 if ( isinstance( theScaleFact, float )):
6344 theScaleFact = [theScaleFact]
6345 if ( isinstance( theScaleFact, int )):
6346 theScaleFact = [ float(theScaleFact)]
6348 self.mesh.SetParameters(thePoint.parameters)
6349 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6350 MakeGroups, NewMeshName)
6351 return Mesh( self.smeshpyD, self.geompyD, mesh )
6355 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6360 IDsOfElements: list of elements ids
6361 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6362 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6363 Copy: allows copying the rotated elements
6364 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6367 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6371 if IDsOfElements == []:
6372 IDsOfElements = self.GetElementsId()
6373 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6374 Axis = self.smeshpyD.GetAxisStruct(Axis)
6375 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6376 Parameters = Axis.parameters + var_separator + Parameters
6377 self.mesh.SetParameters(Parameters)
6378 if Copy and MakeGroups:
6379 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6380 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6383 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6385 Create a new mesh of rotated elements
6388 IDsOfElements: list of element ids
6389 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6390 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6391 MakeGroups: forces the generation of new groups from existing ones
6392 NewMeshName: the name of the newly created mesh
6395 instance of class :class:`Mesh`
6398 if IDsOfElements == []:
6399 IDsOfElements = self.GetElementsId()
6400 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6401 Axis = self.smeshpyD.GetAxisStruct(Axis)
6402 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6403 Parameters = Axis.parameters + var_separator + Parameters
6404 self.mesh.SetParameters(Parameters)
6405 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6406 MakeGroups, NewMeshName)
6407 return Mesh( self.smeshpyD, self.geompyD, mesh )
6409 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6414 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6415 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6416 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6417 Copy: allows copying the rotated elements
6418 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6421 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6424 if (isinstance(theObject, Mesh)):
6425 theObject = theObject.GetMesh()
6426 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6427 Axis = self.smeshpyD.GetAxisStruct(Axis)
6428 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6429 Parameters = Axis.parameters + ":" + Parameters
6430 self.mesh.SetParameters(Parameters)
6431 if Copy and MakeGroups:
6432 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6433 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6436 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6438 Create a new mesh from the rotated object
6441 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6442 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6443 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6444 MakeGroups: forces the generation of new groups from existing ones
6445 NewMeshName: the name of the newly created mesh
6448 instance of class :class:`Mesh`
6451 if (isinstance( theObject, Mesh )):
6452 theObject = theObject.GetMesh()
6453 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6454 Axis = self.smeshpyD.GetAxisStruct(Axis)
6455 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6456 Parameters = Axis.parameters + ":" + Parameters
6457 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6458 MakeGroups, NewMeshName)
6459 self.mesh.SetParameters(Parameters)
6460 return Mesh( self.smeshpyD, self.geompyD, mesh )
6462 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6464 Create an offset mesh from the given 2D object
6467 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6468 theValue (float): signed offset size
6469 MakeGroups (boolean): forces the generation of new groups from existing ones
6470 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6471 False means to remove original elements.
6472 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6475 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6478 if isinstance( theObject, Mesh ):
6479 theObject = theObject.GetMesh()
6480 theValue,Parameters,hasVars = ParseParameters(Value)
6481 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6482 self.mesh.SetParameters(Parameters)
6484 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6487 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6489 Find groups of adjacent nodes within Tolerance.
6492 Tolerance (float): the value of tolerance
6493 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6494 corner and medium nodes in separate groups thus preventing
6495 their further merge.
6498 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6501 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6503 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6504 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6506 Find groups of adjacent nodes within Tolerance.
6509 Tolerance: the value of tolerance
6510 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6511 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6512 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6513 corner and medium nodes in separate groups thus preventing
6514 their further merge.
6517 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6520 unRegister = genObjUnRegister()
6521 if not isinstance( SubMeshOrGroup, list ):
6522 SubMeshOrGroup = [ SubMeshOrGroup ]
6523 for i,obj in enumerate( SubMeshOrGroup ):
6524 if isinstance( obj, Mesh ):
6525 SubMeshOrGroup = [ obj.GetMesh() ]
6527 if isinstance( obj, int ):
6528 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6529 unRegister.set( SubMeshOrGroup )
6532 if not isinstance( exceptNodes, list ):
6533 exceptNodes = [ exceptNodes ]
6534 if exceptNodes and isinstance( exceptNodes[0], int ):
6535 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6536 unRegister.set( exceptNodes )
6538 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6539 exceptNodes, SeparateCornerAndMediumNodes)
6541 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6546 GroupsOfNodes: a list of groups of nodes IDs for merging.
6547 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6548 in all elements and mesh groups by nodes 1 and 25 correspondingly
6549 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6550 If *NodesToKeep* does not include a node to keep for some group to merge,
6551 then the first node in the group is kept.
6552 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6556 This operation can create gaps in numeration of nodes or elements.
6557 Call :meth:`RenumberElements` to remove the gaps.
6559 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6561 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6563 Find the elements built on the same nodes.
6566 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6567 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6571 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6574 unRegister = genObjUnRegister()
6575 if MeshOrSubMeshOrGroup is None:
6576 MeshOrSubMeshOrGroup = [ self.mesh ]
6577 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6578 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6579 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6580 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6581 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6582 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6583 unRegister.set( MeshOrSubMeshOrGroup )
6584 for item in MeshOrSubMeshOrGroup:
6585 if isinstance( item, Mesh ):
6586 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6588 if not isinstance( exceptElements, list ):
6589 exceptElements = [ exceptElements ]
6590 if exceptElements and isinstance( exceptElements[0], int ):
6591 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6592 unRegister.set( exceptElements )
6594 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6596 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6598 Merge elements in each given group.
6601 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6602 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6603 replaced in all mesh groups by elements 1 and 25)
6604 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6605 If *ElementsToKeep* does not include an element to keep for some group to merge,
6606 then the first element in the group is kept.
6609 This operation can create gaps in numeration of elements.
6610 Call :meth:`RenumberElements` to remove the gaps.
6613 unRegister = genObjUnRegister()
6615 if not isinstance( ElementsToKeep, list ):
6616 ElementsToKeep = [ ElementsToKeep ]
6617 if isinstance( ElementsToKeep[0], int ):
6618 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6619 unRegister.set( ElementsToKeep )
6621 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6623 def MergeEqualElements(self):
6625 Leave one element and remove all other elements built on the same nodes.
6628 This operation can create gaps in numeration of elements.
6629 Call :meth:`RenumberElements` to remove the gaps.
6632 self.editor.MergeEqualElements()
6634 def FindFreeBorders(self, ClosedOnly=True):
6636 Returns all or only closed free borders
6639 list of SMESH.FreeBorder's
6642 return self.editor.FindFreeBorders( ClosedOnly )
6644 def FillHole(self, holeNodes, groupName=""):
6646 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6649 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6650 must describe all sequential nodes of the hole border. The first and the last
6651 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6652 groupName (string): name of a group to add new faces
6654 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6658 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6659 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6660 if not isinstance( holeNodes, SMESH.FreeBorder ):
6661 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6662 return self.editor.FillHole( holeNodes, groupName )
6664 def FindCoincidentFreeBorders (self, tolerance=0.):
6666 Return groups of FreeBorder's coincident within the given tolerance.
6669 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6670 size of elements adjacent to free borders being compared is used.
6673 SMESH.CoincidentFreeBorders structure
6676 return self.editor.FindCoincidentFreeBorders( tolerance )
6678 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6680 Sew FreeBorder's of each group
6683 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6684 where each enclosed list contains node IDs of a group of coincident free
6685 borders such that each consequent triple of IDs within a group describes
6686 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6687 last node of a border.
6688 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6689 groups of coincident free borders, each group including two borders.
6690 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6691 polygons if a node of opposite border falls on a face edge, else such
6692 faces are split into several ones.
6693 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6694 polyhedra if a node of opposite border falls on a volume edge, else such
6695 volumes, if any, remain intact and the mesh becomes non-conformal.
6698 a number of successfully sewed groups
6701 This operation can create gaps in numeration of nodes or elements.
6702 Call :meth:`RenumberElements` to remove the gaps.
6705 if freeBorders and isinstance( freeBorders, list ):
6706 # construct SMESH.CoincidentFreeBorders
6707 if isinstance( freeBorders[0], int ):
6708 freeBorders = [freeBorders]
6710 coincidentGroups = []
6711 for nodeList in freeBorders:
6712 if not nodeList or len( nodeList ) % 3:
6713 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6716 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6717 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6718 nodeList = nodeList[3:]
6720 coincidentGroups.append( group )
6722 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6724 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6726 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6727 FirstNodeID2, SecondNodeID2, LastNodeID2,
6728 CreatePolygons, CreatePolyedrs):
6733 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6736 This operation can create gaps in numeration of nodes or elements.
6737 Call :meth:`RenumberElements` to remove the gaps.
6740 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6741 FirstNodeID2, SecondNodeID2, LastNodeID2,
6742 CreatePolygons, CreatePolyedrs)
6744 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6745 FirstNodeID2, SecondNodeID2):
6747 Sew conform free borders
6750 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6753 This operation can create gaps in numeration of elements.
6754 Call :meth:`RenumberElements` to remove the gaps.
6757 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6758 FirstNodeID2, SecondNodeID2)
6760 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6761 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6766 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6769 This operation can create gaps in numeration of elements.
6770 Call :meth:`RenumberElements` to remove the gaps.
6773 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6774 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6776 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6777 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6778 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6780 Sew two sides of a mesh. The nodes belonging to Side1 are
6781 merged with the nodes of elements of Side2.
6782 The number of elements in theSide1 and in theSide2 must be
6783 equal and they should have similar nodal connectivity.
6784 The nodes to merge should belong to side borders and
6785 the first node should be linked to the second.
6788 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6791 This operation can create gaps in numeration of nodes.
6792 Call :meth:`RenumberElements` to remove the gaps.
6795 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6796 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6797 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6799 def ChangeElemNodes(self, ide, newIDs):
6801 Set new nodes for the given element. Number of nodes should be kept.
6808 False if the number of nodes does not correspond to the type of element
6811 return self.editor.ChangeElemNodes(ide, newIDs)
6813 def GetLastCreatedNodes(self):
6815 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6816 created, this method return the list of their IDs.
6817 If new nodes were not created - return empty list
6820 the list of integer values (can be empty)
6823 return self.editor.GetLastCreatedNodes()
6825 def GetLastCreatedElems(self):
6827 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6828 created this method return the list of their IDs.
6829 If new elements were not created - return empty list
6832 the list of integer values (can be empty)
6835 return self.editor.GetLastCreatedElems()
6837 def ClearLastCreated(self):
6839 Forget what nodes and elements were created by the last mesh edition operation
6842 self.editor.ClearLastCreated()
6844 def DoubleElements(self, theElements, theGroupName=""):
6846 Create duplicates of given elements, i.e. create new elements based on the
6847 same nodes as the given ones.
6850 theElements: container of elements to duplicate. It can be a
6851 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6852 or a list of element IDs. If *theElements* is
6853 a :class:`Mesh`, elements of highest dimension are duplicated
6854 theGroupName: a name of group to contain the generated elements.
6855 If a group with such a name already exists, the new elements
6856 are added to the existing group, else a new group is created.
6857 If *theGroupName* is empty, new elements are not added
6861 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6862 None if *theGroupName* == "".
6865 unRegister = genObjUnRegister()
6866 if isinstance( theElements, Mesh ):
6867 theElements = theElements.mesh
6868 elif isinstance( theElements, list ):
6869 theElements = self.GetIDSource( theElements, SMESH.ALL )
6870 unRegister.set( theElements )
6871 return self.editor.DoubleElements(theElements, theGroupName)
6873 def DoubleNodes(self, theNodes, theModifiedElems):
6875 Create a hole in a mesh by doubling the nodes of some particular elements
6878 theNodes: IDs of nodes to be doubled
6879 theModifiedElems: IDs of elements to be updated by the new (doubled)
6880 nodes. If list of element identifiers is empty then nodes are doubled but
6881 they not assigned to elements
6884 True if operation has been completed successfully, False otherwise
6887 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6889 def DoubleNode(self, theNodeId, theModifiedElems):
6891 Create a hole in a mesh by doubling the nodes of some particular elements.
6892 This method provided for convenience works as :meth:`DoubleNodes`.
6895 theNodeId: IDs of node to double
6896 theModifiedElems: IDs of elements to update
6899 True if operation has been completed successfully, False otherwise
6902 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6904 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6906 Create a hole in a mesh by doubling the nodes of some particular elements.
6907 This method provided for convenience works as :meth:`DoubleNodes`.
6910 theNodes: group of nodes to double.
6911 theModifiedElems: group of elements to update.
6912 theMakeGroup: forces the generation of a group containing new nodes.
6915 True or a created group if operation has been completed successfully,
6916 False or None otherwise
6920 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6921 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6923 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6925 Create a hole in a mesh by doubling the nodes of some particular elements.
6926 This method provided for convenience works as :meth:`DoubleNodes`.
6929 theNodes: list of groups of nodes to double.
6930 theModifiedElems: list of groups of elements to update.
6931 theMakeGroup: forces the generation of a group containing new nodes.
6934 True if operation has been completed successfully, False otherwise
6938 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6939 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6941 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6943 Create a hole in a mesh by doubling the nodes of some particular elements
6946 theElems: the list of elements (edges or faces) to replicate.
6947 The nodes for duplication could be found from these elements
6948 theNodesNot: list of nodes NOT to replicate
6949 theAffectedElems: the list of elements (cells and edges) to which the
6950 replicated nodes should be associated to
6953 True if operation has been completed successfully, False otherwise
6956 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6958 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6960 Create a hole in a mesh by doubling the nodes of some particular elements
6963 theElems: the list of elements (edges or faces) to replicate.
6964 The nodes for duplication could be found from these elements
6965 theNodesNot: list of nodes NOT to replicate
6966 theShape: shape to detect affected elements (element which geometric center
6967 located on or inside shape).
6968 The replicated nodes should be associated to affected elements.
6971 True if operation has been completed successfully, False otherwise
6974 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6976 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6977 theMakeGroup=False, theMakeNodeGroup=False):
6979 Create a hole in a mesh by doubling the nodes of some particular elements.
6980 This method provided for convenience works as :meth:`DoubleNodes`.
6983 theElems: group of of elements (edges or faces) to replicate.
6984 theNodesNot: group of nodes NOT to replicate.
6985 theAffectedElems: group of elements to which the replicated nodes
6986 should be associated to.
6987 theMakeGroup: forces the generation of a group containing new elements.
6988 theMakeNodeGroup: forces the generation of a group containing new nodes.
6991 True or created groups (one or two) if operation has been completed successfully,
6992 False or None otherwise
6995 if theMakeGroup or theMakeNodeGroup:
6996 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6998 theMakeGroup, theMakeNodeGroup)
6999 if theMakeGroup and theMakeNodeGroup:
7002 return twoGroups[ int(theMakeNodeGroup) ]
7003 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7005 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7007 Create a hole in a mesh by doubling the nodes of some particular elements.
7008 This method provided for convenience works as :meth:`DoubleNodes`.
7011 theElems: group of of elements (edges or faces) to replicate
7012 theNodesNot: group of nodes not to replicate
7013 theShape: shape to detect affected elements (element which geometric center
7014 located on or inside shape).
7015 The replicated nodes should be associated to affected elements
7018 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7020 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7021 theMakeGroup=False, theMakeNodeGroup=False):
7023 Create a hole in a mesh by doubling the nodes of some particular elements.
7024 This method provided for convenience works as :meth:`DoubleNodes`.
7027 theElems: list of groups of elements (edges or faces) to replicate
7028 theNodesNot: list of groups of nodes NOT to replicate
7029 theAffectedElems: group of elements to which the replicated nodes
7030 should be associated to
7031 theMakeGroup: forces generation of a group containing new elements.
7032 theMakeNodeGroup: forces generation of a group containing new nodes
7035 True or created groups (one or two) if operation has been completed successfully,
7036 False or None otherwise
7039 if theMakeGroup or theMakeNodeGroup:
7040 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7042 theMakeGroup, theMakeNodeGroup)
7043 if theMakeGroup and theMakeNodeGroup:
7046 return twoGroups[ int(theMakeNodeGroup) ]
7047 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7049 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7051 Create a hole in a mesh by doubling the nodes of some particular elements.
7052 This method provided for convenience works as :meth:`DoubleNodes`.
7055 theElems: list of groups of elements (edges or faces) to replicate
7056 theNodesNot: list of groups of nodes NOT to replicate
7057 theShape: shape to detect affected elements (element which geometric center
7058 located on or inside shape).
7059 The replicated nodes should be associated to affected elements
7062 True if operation has been completed successfully, False otherwise
7065 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7067 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7069 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7070 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7073 theElems: list of groups of nodes or elements (edges or faces) to replicate
7074 theNodesNot: list of groups of nodes NOT to replicate
7075 theShape: shape to detect affected elements (element which geometric center
7076 located on or inside shape).
7077 The replicated nodes should be associated to affected elements
7080 groups of affected elements in order: volumes, faces, edges
7083 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7085 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7088 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7089 The list of groups must describe a partition of the mesh volumes.
7090 The nodes of the internal faces at the boundaries of the groups are doubled.
7091 In option, the internal faces are replaced by flat elements.
7092 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7095 theDomains: list of groups of volumes
7096 createJointElems: if True, create the elements
7097 onAllBoundaries: if True, the nodes and elements are also created on
7098 the boundary between *theDomains* and the rest mesh
7101 True if operation has been completed successfully, False otherwise
7104 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7106 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7108 Double nodes on some external faces and create flat elements.
7109 Flat elements are mainly used by some types of mechanic calculations.
7111 Each group of the list must be constituted of faces.
7112 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7115 theGroupsOfFaces: list of groups of faces
7118 True if operation has been completed successfully, False otherwise
7121 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7123 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7125 Identify all the elements around a geom shape, get the faces delimiting the hole
7127 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7129 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7131 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7132 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7133 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7134 If there are several paths connecting a pair of points, the shortest path is
7135 selected by the module. Position of the cutting plane is defined by the two
7136 points and an optional vector lying on the plane specified by a PolySegment.
7137 By default the vector is defined by Mesh module as following. A middle point
7138 of the two given points is computed. The middle point is projected to the mesh.
7139 The vector goes from the middle point to the projection point. In case of planar
7140 mesh, the vector is normal to the mesh.
7142 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7145 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7146 groupName: optional name of a group where created mesh segments will be added.
7149 editor = self.editor
7151 editor = self.mesh.GetMeshEditPreviewer()
7152 segmentsRes = editor.MakePolyLine( segments, groupName )
7153 for i, seg in enumerate( segmentsRes ):
7154 segments[i].vector = seg.vector
7156 return editor.GetPreviewData()
7159 def MakeSlot(self, segmentGroup, width ):
7161 Create a slot of given width around given 1D elements lying on a triangle mesh.
7162 The slot is constructed by cutting faces by cylindrical surfaces made
7163 around each segment. Segments are expected to be created by MakePolyLine().
7166 FaceEdge's located at the slot boundary
7168 return self.editor.MakeSlot( segmentGroup, width )
7170 def GetFunctor(self, funcType ):
7172 Return a cached numerical functor by its type.
7175 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7176 Note that not all items correspond to numerical functors.
7179 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7182 fn = self.functors[ funcType._v ]
7184 fn = self.smeshpyD.GetFunctor(funcType)
7185 fn.SetMesh(self.mesh)
7186 self.functors[ funcType._v ] = fn
7189 def FunctorValue(self, funcType, elemId, isElem=True):
7191 Return value of a functor for a given element
7194 funcType: an item of :class:`SMESH.FunctorType` enum.
7195 elemId: element or node ID
7196 isElem: *elemId* is ID of element or node
7199 the functor value or zero in case of invalid arguments
7202 fn = self.GetFunctor( funcType )
7203 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7204 val = fn.GetValue(elemId)
7209 def GetLength(self, elemId=None):
7211 Get length of given 1D elements or of all 1D mesh elements
7214 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.
7217 Sum of lengths of given elements
7222 length = self.smeshpyD.GetLength(self)
7223 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7224 length = self.smeshpyD.GetLength(elemId)
7227 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7229 length += self.smeshpyD.GetLength(obj)
7230 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7231 unRegister = genObjUnRegister()
7232 obj = self.GetIDSource( elemId )
7233 unRegister.set( obj )
7234 length = self.smeshpyD.GetLength( obj )
7236 length = self.FunctorValue(SMESH.FT_Length, elemId)
7239 def GetArea(self, elemId=None):
7241 Get area of given 2D elements or of all 2D mesh elements
7244 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.
7247 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7252 area = self.smeshpyD.GetArea(self)
7253 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7254 area = self.smeshpyD.GetArea(elemId)
7257 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7259 area += self.smeshpyD.GetArea(obj)
7260 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7261 unRegister = genObjUnRegister()
7262 obj = self.GetIDSource( elemId )
7263 unRegister.set( obj )
7264 area = self.smeshpyD.GetArea( obj )
7266 area = self.FunctorValue(SMESH.FT_Area, elemId)
7269 def GetVolume(self, elemId=None):
7271 Get volume of given 3D elements or of all 3D mesh elements
7274 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.
7277 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7282 volume= self.smeshpyD.GetVolume(self)
7283 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7284 volume= self.smeshpyD.GetVolume(elemId)
7287 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7289 volume+= self.smeshpyD.GetVolume(obj)
7290 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7291 unRegister = genObjUnRegister()
7292 obj = self.GetIDSource( elemId )
7293 unRegister.set( obj )
7294 volume= self.smeshpyD.GetVolume( obj )
7296 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7299 def GetAngle(self, node1, node2, node3 ):
7301 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7304 node1,node2,node3: IDs of the three nodes
7307 Angle in radians [0,PI]. -1 if failure case.
7309 p1 = self.GetNodeXYZ( node1 )
7310 p2 = self.GetNodeXYZ( node2 )
7311 p3 = self.GetNodeXYZ( node3 )
7312 if p1 and p2 and p3:
7313 return self.smeshpyD.GetAngle( p1,p2,p3 )
7317 def GetMaxElementLength(self, elemId):
7319 Get maximum element length.
7322 elemId: mesh element ID
7325 element's maximum length value
7328 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7329 ftype = SMESH.FT_MaxElementLength3D
7331 ftype = SMESH.FT_MaxElementLength2D
7332 return self.FunctorValue(ftype, elemId)
7334 def GetAspectRatio(self, elemId):
7336 Get aspect ratio of 2D or 3D element.
7339 elemId: mesh element ID
7342 element's aspect ratio value
7345 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7346 ftype = SMESH.FT_AspectRatio3D
7348 ftype = SMESH.FT_AspectRatio
7349 return self.FunctorValue(ftype, elemId)
7351 def GetWarping(self, elemId):
7353 Get warping angle of 2D element.
7356 elemId: mesh element ID
7359 element's warping angle value
7362 return self.FunctorValue(SMESH.FT_Warping, elemId)
7364 def GetMinimumAngle(self, elemId):
7366 Get minimum angle of 2D element.
7369 elemId: mesh element ID
7372 element's minimum angle value
7375 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7377 def GetTaper(self, elemId):
7379 Get taper of 2D element.
7382 elemId: mesh element ID
7385 element's taper value
7388 return self.FunctorValue(SMESH.FT_Taper, elemId)
7390 def GetSkew(self, elemId):
7392 Get skew of 2D element.
7395 elemId: mesh element ID
7398 element's skew value
7401 return self.FunctorValue(SMESH.FT_Skew, elemId)
7403 def GetMinMax(self, funType, meshPart=None):
7405 Return minimal and maximal value of a given functor.
7408 funType (SMESH.FunctorType): a functor type.
7409 Note that not all items of :class:`SMESH.FunctorType` corresponds
7410 to numerical functors.
7411 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7417 unRegister = genObjUnRegister()
7418 if isinstance( meshPart, list ):
7419 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7420 unRegister.set( meshPart )
7421 if isinstance( meshPart, Mesh ):
7422 meshPart = meshPart.mesh
7423 fun = self.GetFunctor( funType )
7426 if hasattr( meshPart, "SetMesh" ):
7427 meshPart.SetMesh( self.mesh ) # set mesh to filter
7428 hist = fun.GetLocalHistogram( 1, False, meshPart )
7430 hist = fun.GetHistogram( 1, False )
7432 return hist[0].min, hist[0].max
7435 pass # end of Mesh class
7438 class meshProxy(SMESH._objref_SMESH_Mesh):
7440 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7441 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7443 def __init__(self,*args):
7444 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7445 def __deepcopy__(self, memo=None):
7446 new = self.__class__(self)
7448 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7449 if len( args ) == 3:
7450 args += SMESH.ALL_NODES, True
7451 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7452 def ExportToMEDX(self, *args): # function removed
7453 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7454 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7455 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7456 def ExportToMED(self, *args): # function removed
7457 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7458 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7460 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7462 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7463 def ExportPartToMED(self, *args): # 'version' parameter removed
7464 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7465 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7466 def ExportMED(self, *args): # signature of method changed
7467 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7469 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7471 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7472 def ExportUNV(self, *args): # renumber arg added
7473 if len( args ) == 1:
7475 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
7476 def ExportDAT(self, *args): # renumber arg added
7477 if len( args ) == 1:
7479 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
7481 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7484 class submeshProxy(SMESH._objref_SMESH_subMesh):
7487 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7489 def __init__(self,*args):
7490 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7492 def __deepcopy__(self, memo=None):
7493 new = self.__class__(self)
7496 def Compute(self,refresh=False):
7498 Compute the sub-mesh and return the status of the computation
7501 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7506 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7507 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7511 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7513 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7515 if salome.sg.hasDesktop():
7516 if refresh: salome.sg.updateObjBrowser()
7521 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7524 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7526 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7527 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7530 def __init__(self,*args):
7531 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7533 def __getattr__(self, name ): # method called if an attribute not found
7534 if not self.mesh: # look for name() method in Mesh class
7535 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7536 if hasattr( self.mesh, name ):
7537 return getattr( self.mesh, name )
7538 if name == "ExtrusionAlongPathObjX":
7539 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7540 print("meshEditor: attribute '%s' NOT FOUND" % name)
7542 def __deepcopy__(self, memo=None):
7543 new = self.__class__(self)
7545 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7546 if len( args ) == 1: args += False,
7547 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7548 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7549 if len( args ) == 2: args += False,
7550 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7551 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7552 if len( args ) == 1:
7553 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7554 NodesToKeep = args[1]
7555 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7556 unRegister = genObjUnRegister()
7558 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7559 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7560 if not isinstance( NodesToKeep, list ):
7561 NodesToKeep = [ NodesToKeep ]
7562 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7564 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7566 class Pattern(SMESH._objref_SMESH_Pattern):
7568 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7569 variables in some methods
7572 def LoadFromFile(self, patternTextOrFile ):
7573 text = patternTextOrFile
7574 if os.path.exists( text ):
7575 text = open( patternTextOrFile ).read()
7577 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7579 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7580 decrFun = lambda i: i-1
7581 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7582 theMesh.SetParameters(Parameters)
7583 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7585 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7586 decrFun = lambda i: i-1
7587 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7588 theMesh.SetParameters(Parameters)
7589 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7591 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7592 if isinstance( mesh, Mesh ):
7593 mesh = mesh.GetMesh()
7594 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7596 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7598 Registering the new proxy for Pattern
7603 Private class used to bind methods creating algorithms to the class Mesh
7606 def __init__(self, method):
7608 self.defaultAlgoType = ""
7609 self.algoTypeToClass = {}
7610 self.method = method
7612 def add(self, algoClass):
7614 Store a python class of algorithm
7616 if inspect.isclass(algoClass) and \
7617 hasattr( algoClass, "algoType"):
7618 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7619 if not self.defaultAlgoType and \
7620 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7621 self.defaultAlgoType = algoClass.algoType
7622 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7624 def copy(self, mesh):
7626 Create a copy of self and assign mesh to the copy
7629 other = algoCreator( self.method )
7630 other.defaultAlgoType = self.defaultAlgoType
7631 other.algoTypeToClass = self.algoTypeToClass
7635 def __call__(self,algo="",geom=0,*args):
7637 Create an instance of algorithm
7641 if isinstance( algo, str ):
7643 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7644 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7649 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7651 elif not algoType and isinstance( geom, str ):
7656 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7658 elif isinstance( arg, str ) and not algoType:
7661 import traceback, sys
7662 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7663 sys.stderr.write( msg + '\n' )
7664 tb = traceback.extract_stack(None,2)
7665 traceback.print_list( [tb[0]] )
7667 algoType = self.defaultAlgoType
7668 if not algoType and self.algoTypeToClass:
7669 algoType = sorted( self.algoTypeToClass.keys() )[0]
7670 if algoType in self.algoTypeToClass:
7671 #print("Create algo",algoType)
7672 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7673 raise RuntimeError( "No class found for algo type %s" % algoType)
7676 class hypMethodWrapper:
7678 Private class used to substitute and store variable parameters of hypotheses.
7681 def __init__(self, hyp, method):
7683 self.method = method
7684 #print("REBIND:", method.__name__)
7687 def __call__(self,*args):
7689 call a method of hypothesis with calling SetVarParameter() before
7693 return self.method( self.hyp, *args ) # hypothesis method with no args
7695 #print("MethWrapper.__call__", self.method.__name__, args)
7697 parsed = ParseParameters(*args) # replace variables with their values
7698 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7699 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7700 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7701 # maybe there is a replaced string arg which is not variable
7702 result = self.method( self.hyp, *args )
7703 except ValueError as detail: # raised by ParseParameters()
7705 result = self.method( self.hyp, *args )
7706 except omniORB.CORBA.BAD_PARAM:
7707 raise ValueError(detail) # wrong variable name
7712 class genObjUnRegister:
7714 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7717 def __init__(self, genObj=None):
7718 self.genObjList = []
7722 def set(self, genObj):
7723 "Store one or a list of of SALOME.GenericObj'es"
7724 if isinstance( genObj, list ):
7725 self.genObjList.extend( genObj )
7727 self.genObjList.append( genObj )
7731 for genObj in self.genObjList:
7732 if genObj and hasattr( genObj, "UnRegister" ):
7735 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7737 Bind methods creating mesher plug-ins to the Mesh class
7740 # print("pluginName: ", pluginName)
7741 pluginBuilderName = pluginName + "Builder"
7743 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7744 except Exception as e:
7745 from salome_utils import verbose
7746 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7748 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7749 plugin = eval( pluginBuilderName )
7750 # print(" plugin:" , str(plugin))
7752 # add methods creating algorithms to Mesh
7753 for k in dir( plugin ):
7754 if k[0] == '_': continue
7755 algo = getattr( plugin, k )
7756 #print(" algo:", str(algo))
7757 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7758 #print(" meshMethod:" , str(algo.meshMethod))
7759 if not hasattr( Mesh, algo.meshMethod ):
7760 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7762 _mmethod = getattr( Mesh, algo.meshMethod )
7763 if hasattr( _mmethod, "add" ):