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>`) to export instead of the mesh
2313 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2315 - 1D if all mesh nodes lie on OX coordinate axis, or
2316 - 2D if all mesh nodes lie on XOY coordinate plane, or
2317 - 3D in the rest cases.
2319 If *autoDimension* is *False*, the space dimension is always 3.
2320 fields: list of GEOM fields defined on the shape to mesh.
2321 geomAssocFields: each character of this string means a need to export a
2322 corresponding field; correspondence between fields and characters
2325 - 'v' stands for "_vertices_" field;
2326 - 'e' stands for "_edges_" field;
2327 - 'f' stands for "_faces_" field;
2328 - 's' stands for "_solids_" field.
2330 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2331 close to zero within a given tolerance, the coordinate is set to zero.
2332 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2334 auto_groups = args[0] if len(args) > 0 else False
2335 meshPart = args[1] if len(args) > 1 else None
2336 autoDimension = args[2] if len(args) > 2 else True
2337 fields = args[3] if len(args) > 3 else []
2338 geomAssocFields = args[4] if len(args) > 4 else ''
2339 z_tolerance = args[5] if len(args) > 5 else -1.
2340 # process keywords arguments
2341 auto_groups = kwargs.get("auto_groups", auto_groups)
2342 meshPart = kwargs.get("meshPart", meshPart)
2343 autoDimension = kwargs.get("autoDimension", autoDimension)
2344 fields = kwargs.get("fields", fields)
2345 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2346 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2348 # invoke engine's function
2349 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2350 unRegister = genObjUnRegister()
2351 if isinstance( meshPart, list ):
2352 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2353 unRegister.set( meshPart )
2355 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2356 self.mesh.SetParameters(Parameters)
2358 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension, fields, geomAssocFields, z_tolerance)
2360 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2361 return medcoupling.MEDFileData.New(dab)
2363 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2365 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2366 return medcoupling.MEDFileMesh.New(dab)
2368 def ExportMED(self, *args, **kwargs):
2370 Export the mesh in a file in MED format
2371 allowing to overwrite the file if it exists or add the exported data to its contents
2374 fileName: is the file name
2375 auto_groups (boolean): parameter for creating/not creating
2376 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2377 the typical use is auto_groups=False.
2378 version (int): define the version (xy, where version is x.y.z) of MED file format.
2379 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2380 The rules of compatibility to write a mesh in an older version than
2381 the current version depend on the current version. For instance,
2382 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2383 or 3.2.1 or 3.3.1 formats.
2384 If the version is equal to -1, the version is not changed (default).
2385 overwrite (boolean): parameter for overwriting/not overwriting the file
2386 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2387 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2389 - 1D if all mesh nodes lie on OX coordinate axis, or
2390 - 2D if all mesh nodes lie on XOY coordinate plane, or
2391 - 3D in the rest cases.
2393 If *autoDimension* is *False*, the space dimension is always 3.
2394 fields: list of GEOM fields defined on the shape to mesh.
2395 geomAssocFields: each character of this string means a need to export a
2396 corresponding field; correspondence between fields and characters
2399 - 'v' stands for "_vertices_" field;
2400 - 'e' stands for "_edges_" field;
2401 - 'f' stands for "_faces_" field;
2402 - 's' stands for "_solids_" field.
2404 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2405 close to zero within a given tolerance, the coordinate is set to zero.
2406 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2408 # process positional arguments
2409 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2411 auto_groups = args[1] if len(args) > 1 else False
2412 version = args[2] if len(args) > 2 else -1
2413 overwrite = args[3] if len(args) > 3 else True
2414 meshPart = args[4] if len(args) > 4 else None
2415 autoDimension = args[5] if len(args) > 5 else True
2416 fields = args[6] if len(args) > 6 else []
2417 geomAssocFields = args[7] if len(args) > 7 else ''
2418 z_tolerance = args[8] if len(args) > 8 else -1.
2419 # process keywords arguments
2420 auto_groups = kwargs.get("auto_groups", auto_groups)
2421 version = kwargs.get("version", version)
2422 version = kwargs.get("minor", version)
2423 overwrite = kwargs.get("overwrite", overwrite)
2424 meshPart = kwargs.get("meshPart", meshPart)
2425 autoDimension = kwargs.get("autoDimension", autoDimension)
2426 fields = kwargs.get("fields", fields)
2427 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2428 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2430 # invoke engine's function
2431 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2432 unRegister = genObjUnRegister()
2433 if isinstance( meshPart, list ):
2434 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2435 unRegister.set( meshPart )
2437 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2438 self.mesh.SetParameters(Parameters)
2440 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2441 version, overwrite, autoDimension,
2442 fields, geomAssocFields, z_tolerance)
2444 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2446 def ExportSAUV(self, f, auto_groups=0):
2448 Export the mesh in a file in SAUV format
2453 auto_groups: boolean parameter for creating/not creating
2454 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2455 the typical use is auto_groups=False.
2458 self.mesh.ExportSAUV(f, auto_groups)
2460 def ExportDAT(self, f, meshPart=None):
2462 Export the mesh in a file in DAT format
2466 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2470 unRegister = genObjUnRegister()
2471 if isinstance( meshPart, list ):
2472 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2473 unRegister.set( meshPart )
2474 self.mesh.ExportPartToDAT( meshPart, f )
2476 self.mesh.ExportDAT(f)
2478 def ExportUNV(self, f, meshPart=None):
2480 Export the mesh in a file in UNV format
2484 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2488 unRegister = genObjUnRegister()
2489 if isinstance( meshPart, list ):
2490 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2491 unRegister.set( meshPart )
2492 self.mesh.ExportPartToUNV( meshPart, f )
2494 self.mesh.ExportUNV(f)
2496 def ExportSTL(self, f, ascii=1, meshPart=None):
2498 Export the mesh in a file in STL format
2502 ascii: defines the file encoding
2503 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2507 unRegister = genObjUnRegister()
2508 if isinstance( meshPart, list ):
2509 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2510 unRegister.set( meshPart )
2511 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2513 self.mesh.ExportSTL(f, ascii)
2515 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2517 Export the mesh in a file in CGNS format
2521 overwrite: boolean parameter for overwriting/not overwriting the file
2522 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2523 groupElemsByType: if True all elements of same entity type are exported at ones,
2524 else elements are exported in order of their IDs which can cause creation
2525 of multiple cgns sections
2528 unRegister = genObjUnRegister()
2529 if isinstance( meshPart, list ):
2530 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2531 unRegister.set( meshPart )
2532 if isinstance( meshPart, Mesh ):
2533 meshPart = meshPart.mesh
2535 meshPart = self.mesh
2536 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2538 def ExportGMF(self, f, meshPart=None):
2540 Export the mesh in a file in GMF format.
2541 GMF files must have .mesh extension for the ASCII format and .meshb for
2542 the bynary format. Other extensions are not allowed.
2546 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2549 unRegister = genObjUnRegister()
2550 if isinstance( meshPart, list ):
2551 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2552 unRegister.set( meshPart )
2553 if isinstance( meshPart, Mesh ):
2554 meshPart = meshPart.mesh
2556 meshPart = self.mesh
2557 self.mesh.ExportGMF(meshPart, f, True)
2559 def ExportToMED(self, *args, **kwargs):
2561 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2562 Export the mesh in a file in MED format
2563 allowing to overwrite the file if it exists or add the exported data to its contents
2566 fileName: the file name
2567 opt (boolean): parameter for creating/not creating
2568 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2569 overwrite: boolean parameter for overwriting/not overwriting the file
2570 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2572 - 1D if all mesh nodes lie on OX coordinate axis, or
2573 - 2D if all mesh nodes lie on XOY coordinate plane, or
2574 - 3D in the rest cases.
2576 If **autoDimension** is *False*, the space dimension is always 3.
2579 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2580 # process positional arguments
2581 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2583 auto_groups = args[1] if len(args) > 1 else False
2584 overwrite = args[2] if len(args) > 2 else True
2585 autoDimension = args[3] if len(args) > 3 else True
2586 # process keywords arguments
2587 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2588 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2589 overwrite = kwargs.get("overwrite", overwrite)
2590 autoDimension = kwargs.get("autoDimension", autoDimension)
2592 # invoke engine's function
2593 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2595 def ExportToMEDX(self, *args, **kwargs):
2597 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2598 Export the mesh in a file in MED format
2601 fileName: the file name
2602 opt (boolean): parameter for creating/not creating
2603 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2604 overwrite: boolean parameter for overwriting/not overwriting the file
2605 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2607 - 1D if all mesh nodes lie on OX coordinate axis, or
2608 - 2D if all mesh nodes lie on XOY coordinate plane, or
2609 - 3D in the rest cases.
2611 If **autoDimension** is *False*, the space dimension is always 3.
2614 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2615 # process positional arguments
2616 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2618 auto_groups = args[1] if len(args) > 1 else False
2619 overwrite = args[2] if len(args) > 2 else True
2620 autoDimension = args[3] if len(args) > 3 else True
2621 # process keywords arguments
2622 auto_groups = kwargs.get("auto_groups", auto_groups)
2623 overwrite = kwargs.get("overwrite", overwrite)
2624 autoDimension = kwargs.get("autoDimension", autoDimension)
2626 # invoke engine's function
2627 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2631 def Append(self, meshes, uniteIdenticalGroups = True,
2632 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2634 Append given meshes into this mesh.
2635 All groups of input meshes will be created in this mesh.
2638 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2639 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2640 mergeNodesAndElements: if True, equal nodes and elements are merged
2641 mergeTolerance: tolerance for merging nodes
2642 allGroups: forces creation of groups corresponding to every input mesh
2644 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2645 mergeNodesAndElements, mergeTolerance, allGroups,
2646 meshToAppendTo = self.GetMesh() )
2648 # Operations with groups:
2649 # ----------------------
2650 def CreateEmptyGroup(self, elementType, name):
2652 Create an empty standalone mesh group
2655 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2656 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2657 name: the name of the mesh group
2660 :class:`SMESH.SMESH_Group`
2663 return self.mesh.CreateGroup(elementType, name)
2665 def Group(self, grp, name=""):
2667 Create a mesh group based on the geometric object *grp*
2668 and give it a *name*.
2669 If *name* is not defined the name of the geometric group is used
2672 Works like :meth:`GroupOnGeom`.
2675 grp: a geometric group, a vertex, an edge, a face or a solid
2676 name: the name of the mesh group
2679 :class:`SMESH.SMESH_GroupOnGeom`
2682 return self.GroupOnGeom(grp, name)
2684 def GroupOnGeom(self, grp, name="", typ=None):
2686 Create a mesh group based on the geometrical object *grp*
2687 and give it a *name*.
2688 if *name* is not defined the name of the geometric group is used
2691 grp: a geometrical group, a vertex, an edge, a face or a solid
2692 name: the name of the mesh group
2693 typ: the type of elements in the group; either of
2694 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2695 automatically detected by the type of the geometry
2698 :class:`SMESH.SMESH_GroupOnGeom`
2701 AssureGeomPublished( self, grp, name )
2703 name = grp.GetName()
2705 typ = self._groupTypeFromShape( grp )
2706 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2708 def _groupTypeFromShape( self, shape ):
2710 Pivate method to get a type of group on geometry
2712 tgeo = str(shape.GetShapeType())
2713 if tgeo == "VERTEX":
2715 elif tgeo == "EDGE" or tgeo == "WIRE":
2717 elif tgeo == "FACE" or tgeo == "SHELL":
2719 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2721 elif tgeo == "COMPOUND":
2723 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2725 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2726 # simplification of access in geomBuilder: omniORB.registerObjref
2727 from SHAPERSTUDY_utils import getEngine
2730 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2732 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2733 return self._groupTypeFromShape( sub[0] )
2735 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2738 def GroupOnFilter(self, typ, name, filter):
2740 Create a mesh group with given *name* based on the *filter*.
2741 It is a special type of group dynamically updating it's contents during
2745 typ: the type of elements in the group; either of
2746 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2747 name: the name of the mesh group
2748 filter (SMESH.Filter): the filter defining group contents
2751 :class:`SMESH.SMESH_GroupOnFilter`
2754 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2756 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2758 Create a mesh group by the given ids of elements
2761 groupName: the name of the mesh group
2762 elementType: the type of elements in the group; either of
2763 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2764 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2767 :class:`SMESH.SMESH_Group`
2770 group = self.mesh.CreateGroup(elementType, groupName)
2771 if isinstance( elemIDs, Mesh ):
2772 elemIDs = elemIDs.GetMesh()
2773 if hasattr( elemIDs, "GetIDs" ):
2774 if hasattr( elemIDs, "SetMesh" ):
2775 elemIDs.SetMesh( self.GetMesh() )
2776 group.AddFrom( elemIDs )
2784 CritType=FT_Undefined,
2787 UnaryOp=FT_Undefined,
2790 Create a mesh group by the given conditions
2793 groupName: the name of the mesh group
2794 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2795 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2796 Note that the items starting from FT_LessThan are not suitable for CritType.
2797 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2798 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2799 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2800 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2801 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2804 :class:`SMESH.SMESH_GroupOnFilter`
2807 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2808 group = self.MakeGroupByCriterion(groupName, aCriterion)
2811 def MakeGroupByCriterion(self, groupName, Criterion):
2813 Create a mesh group by the given criterion
2816 groupName: the name of the mesh group
2817 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2820 :class:`SMESH.SMESH_GroupOnFilter`
2823 :meth:`smeshBuilder.GetCriterion`
2826 return self.MakeGroupByCriteria( groupName, [Criterion] )
2828 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2830 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2833 groupName: the name of the mesh group
2834 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2835 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2838 :class:`SMESH.SMESH_GroupOnFilter`
2841 :meth:`smeshBuilder.GetCriterion`
2844 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2845 group = self.MakeGroupByFilter(groupName, aFilter)
2848 def MakeGroupByFilter(self, groupName, theFilter):
2850 Create a mesh group by the given filter
2853 groupName (string): the name of the mesh group
2854 theFilter (SMESH.Filter): the filter
2857 :class:`SMESH.SMESH_GroupOnFilter`
2860 :meth:`smeshBuilder.GetFilter`
2863 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2864 #theFilter.SetMesh( self.mesh )
2865 #group.AddFrom( theFilter )
2866 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2869 def RemoveGroup(self, group):
2874 group (SMESH.SMESH_GroupBase): group to remove
2877 self.mesh.RemoveGroup(group)
2879 def RemoveGroupWithContents(self, group):
2881 Remove a group with its contents
2884 group (SMESH.SMESH_GroupBase): group to remove
2887 This operation can create gaps in numeration of nodes or elements.
2888 Call :meth:`RenumberElements` to remove the gaps.
2891 self.mesh.RemoveGroupWithContents(group)
2893 def GetGroups(self, elemType = SMESH.ALL):
2895 Get the list of groups existing in the mesh in the order of creation
2896 (starting from the oldest one)
2899 elemType (SMESH.ElementType): type of elements the groups contain;
2900 by default groups of elements of all types are returned
2903 a list of :class:`SMESH.SMESH_GroupBase`
2906 groups = self.mesh.GetGroups()
2907 if elemType == SMESH.ALL:
2911 if g.GetType() == elemType:
2912 typedGroups.append( g )
2919 Get the number of groups existing in the mesh
2922 the quantity of groups as an integer value
2925 return self.mesh.NbGroups()
2927 def GetGroupNames(self):
2929 Get the list of names of groups existing in the mesh
2935 groups = self.GetGroups()
2937 for group in groups:
2938 names.append(group.GetName())
2941 def GetGroupByName(self, name, elemType = None):
2943 Find groups by name and type
2946 name (string): name of the group of interest
2947 elemType (SMESH.ElementType): type of elements the groups contain;
2948 by default one group of any type is returned;
2949 if elemType == SMESH.ALL then all groups of any type are returned
2952 a list of :class:`SMESH.SMESH_GroupBase`
2956 for group in self.GetGroups():
2957 if group.GetName() == name:
2958 if elemType is None:
2960 if ( elemType == SMESH.ALL or
2961 group.GetType() == elemType ):
2962 groups.append( group )
2965 def UnionGroups(self, group1, group2, name):
2967 Produce a union of two groups.
2968 A new group is created. All mesh elements that are
2969 present in the initial groups are added to the new one
2972 group1 (SMESH.SMESH_GroupBase): a group
2973 group2 (SMESH.SMESH_GroupBase): another group
2976 instance of :class:`SMESH.SMESH_Group`
2979 return self.mesh.UnionGroups(group1, group2, name)
2981 def UnionListOfGroups(self, groups, name):
2983 Produce a union list of groups.
2984 New group is created. All mesh elements that are present in
2985 initial groups are added to the new one
2988 groups: list of :class:`SMESH.SMESH_GroupBase`
2991 instance of :class:`SMESH.SMESH_Group`
2993 return self.mesh.UnionListOfGroups(groups, name)
2995 def IntersectGroups(self, group1, group2, name):
2997 Prodice an intersection of two groups.
2998 A new group is created. All mesh elements that are common
2999 for the two initial groups are added to the new one.
3002 group1 (SMESH.SMESH_GroupBase): a group
3003 group2 (SMESH.SMESH_GroupBase): another group
3006 instance of :class:`SMESH.SMESH_Group`
3009 return self.mesh.IntersectGroups(group1, group2, name)
3011 def IntersectListOfGroups(self, groups, name):
3013 Produce an intersection of groups.
3014 New group is created. All mesh elements that are present in all
3015 initial groups simultaneously are added to the new one
3018 groups: a list of :class:`SMESH.SMESH_GroupBase`
3021 instance of :class:`SMESH.SMESH_Group`
3023 return self.mesh.IntersectListOfGroups(groups, name)
3025 def CutGroups(self, main_group, tool_group, name):
3027 Produce a cut of two groups.
3028 A new group is created. All mesh elements that are present in
3029 the main group but are not present in the tool group are added to the new one
3032 main_group (SMESH.SMESH_GroupBase): a group to cut from
3033 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3036 an instance of :class:`SMESH.SMESH_Group`
3039 return self.mesh.CutGroups(main_group, tool_group, name)
3041 def CutListOfGroups(self, main_groups, tool_groups, name):
3043 Produce a cut of groups.
3044 A new group is created. All mesh elements that are present in main groups
3045 but do not present in tool groups are added to the new one
3048 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3049 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3052 an instance of :class:`SMESH.SMESH_Group`
3055 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3057 def CreateDimGroup(self, groups, elemType, name,
3058 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3060 Create a standalone group of entities basing on nodes of other groups.
3063 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3064 elemType: a type of elements to include to the new group; either of
3065 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3066 name: a name of the new group.
3067 nbCommonNodes: a criterion of inclusion of an element to the new group
3068 basing on number of element nodes common with reference *groups*.
3069 Meaning of possible values are:
3071 - SMESH.ALL_NODES - include if all nodes are common,
3072 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3073 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3074 - SMEHS.MAJORITY - include if half of nodes or more are common.
3075 underlyingOnly: if *True* (default), an element is included to the
3076 new group provided that it is based on nodes of an element of *groups*;
3077 in this case the reference *groups* are supposed to be of higher dimension
3078 than *elemType*, which can be useful for example to get all faces lying on
3079 volumes of the reference *groups*.
3082 an instance of :class:`SMESH.SMESH_Group`
3085 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3087 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3089 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3091 Distribute all faces of the mesh among groups using sharp edges and optionally
3092 existing 1D elements as group boundaries.
3095 sharpAngle: edge is considered sharp if an angle between normals of
3096 adjacent faces is more than \a sharpAngle in degrees.
3097 createEdges (boolean): to create 1D elements for detected sharp edges.
3098 useExistingEdges (boolean): to use existing edges as group boundaries
3100 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3102 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3103 self.mesh.SetParameters(Parameters)
3104 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3106 def ConvertToStandalone(self, group):
3108 Convert group on geom into standalone group
3111 return self.mesh.ConvertToStandalone(group)
3113 # Get some info about mesh:
3114 # ------------------------
3116 def GetLog(self, clearAfterGet):
3118 Return the log of nodes and elements added or removed
3119 since the previous clear of the log.
3122 clearAfterGet: log is emptied after Get (safe if concurrents access)
3125 list of SMESH.log_block structures { commandType, number, coords, indexes }
3128 return self.mesh.GetLog(clearAfterGet)
3132 Clear the log of nodes and elements added or removed since the previous
3133 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3136 self.mesh.ClearLog()
3138 def SetAutoColor(self, theAutoColor):
3140 Toggle auto color mode on the object.
3141 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3144 theAutoColor (boolean): the flag which toggles auto color mode.
3147 self.mesh.SetAutoColor(theAutoColor)
3149 def GetAutoColor(self):
3151 Get flag of object auto color mode.
3157 return self.mesh.GetAutoColor()
3164 integer value, which is the internal Id of the mesh
3167 return self.mesh.GetId()
3169 def HasDuplicatedGroupNamesMED(self):
3171 Check the group names for duplications.
3172 Consider the maximum group name length stored in MED file.
3178 return self.mesh.HasDuplicatedGroupNamesMED()
3180 def GetMeshEditor(self):
3182 Obtain the mesh editor tool
3185 an instance of :class:`SMESH.SMESH_MeshEditor`
3190 def GetIDSource(self, ids, elemType = SMESH.ALL):
3192 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3193 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3197 elemType: type of elements; this parameter is used to distinguish
3198 IDs of nodes from IDs of elements; by default ids are treated as
3199 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3202 an instance of :class:`SMESH.SMESH_IDSource`
3205 call UnRegister() for the returned object as soon as it is no more useful::
3207 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3208 mesh.DoSomething( idSrc )
3212 if isinstance( ids, int ):
3214 return self.editor.MakeIDSource(ids, elemType)
3217 # Get information about mesh contents:
3218 # ------------------------------------
3220 def GetMeshInfo(self, obj = None):
3222 Get the mesh statistic.
3225 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3228 if not obj: obj = self.mesh
3229 return self.smeshpyD.GetMeshInfo(obj)
3233 Return the number of nodes in the mesh
3239 return self.mesh.NbNodes()
3241 def NbElements(self):
3243 Return the number of elements in the mesh
3249 return self.mesh.NbElements()
3251 def Nb0DElements(self):
3253 Return the number of 0d elements in the mesh
3259 return self.mesh.Nb0DElements()
3263 Return the number of ball discrete elements in the mesh
3269 return self.mesh.NbBalls()
3273 Return the number of edges in the mesh
3279 return self.mesh.NbEdges()
3281 def NbEdgesOfOrder(self, elementOrder):
3283 Return the number of edges with the given order in the mesh
3286 elementOrder: the order of elements
3287 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3293 return self.mesh.NbEdgesOfOrder(elementOrder)
3297 Return the number of faces in the mesh
3303 return self.mesh.NbFaces()
3305 def NbFacesOfOrder(self, elementOrder):
3307 Return the number of faces with the given order in the mesh
3310 elementOrder: the order of elements
3311 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3317 return self.mesh.NbFacesOfOrder(elementOrder)
3319 def NbTriangles(self):
3321 Return the number of triangles in the mesh
3327 return self.mesh.NbTriangles()
3329 def NbTrianglesOfOrder(self, elementOrder):
3331 Return the number of triangles with the given order in the mesh
3334 elementOrder: is the order of elements
3335 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3341 return self.mesh.NbTrianglesOfOrder(elementOrder)
3343 def NbBiQuadTriangles(self):
3345 Return the number of biquadratic triangles in the mesh
3351 return self.mesh.NbBiQuadTriangles()
3353 def NbQuadrangles(self):
3355 Return the number of quadrangles in the mesh
3361 return self.mesh.NbQuadrangles()
3363 def NbQuadranglesOfOrder(self, elementOrder):
3365 Return the number of quadrangles with the given order in the mesh
3368 elementOrder: the order of elements
3369 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3375 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3377 def NbBiQuadQuadrangles(self):
3379 Return the number of biquadratic quadrangles in the mesh
3385 return self.mesh.NbBiQuadQuadrangles()
3387 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3389 Return the number of polygons of given order in the mesh
3392 elementOrder: the order of elements
3393 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3399 return self.mesh.NbPolygonsOfOrder(elementOrder)
3401 def NbVolumes(self):
3403 Return the number of volumes in the mesh
3409 return self.mesh.NbVolumes()
3412 def NbVolumesOfOrder(self, elementOrder):
3414 Return the number of volumes with the given order in the mesh
3417 elementOrder: the order of elements
3418 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3424 return self.mesh.NbVolumesOfOrder(elementOrder)
3428 Return the number of tetrahedrons in the mesh
3434 return self.mesh.NbTetras()
3436 def NbTetrasOfOrder(self, elementOrder):
3438 Return the number of tetrahedrons with the given order in the mesh
3441 elementOrder: the order of elements
3442 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3448 return self.mesh.NbTetrasOfOrder(elementOrder)
3452 Return the number of hexahedrons in the mesh
3458 return self.mesh.NbHexas()
3460 def NbHexasOfOrder(self, elementOrder):
3462 Return the number of hexahedrons with the given order in the mesh
3465 elementOrder: the order of elements
3466 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3472 return self.mesh.NbHexasOfOrder(elementOrder)
3474 def NbTriQuadraticHexas(self):
3476 Return the number of triquadratic hexahedrons in the mesh
3482 return self.mesh.NbTriQuadraticHexas()
3484 def NbPyramids(self):
3486 Return the number of pyramids in the mesh
3492 return self.mesh.NbPyramids()
3494 def NbPyramidsOfOrder(self, elementOrder):
3496 Return the number of pyramids with the given order in the mesh
3499 elementOrder: the order of elements
3500 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3506 return self.mesh.NbPyramidsOfOrder(elementOrder)
3510 Return the number of prisms in the mesh
3516 return self.mesh.NbPrisms()
3518 def NbPrismsOfOrder(self, elementOrder):
3520 Return the number of prisms with the given order in the mesh
3523 elementOrder: the order of elements
3524 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3530 return self.mesh.NbPrismsOfOrder(elementOrder)
3532 def NbHexagonalPrisms(self):
3534 Return the number of hexagonal prisms in the mesh
3540 return self.mesh.NbHexagonalPrisms()
3542 def NbPolyhedrons(self):
3544 Return the number of polyhedrons in the mesh
3550 return self.mesh.NbPolyhedrons()
3552 def NbSubMesh(self):
3554 Return the number of submeshes in the mesh
3560 return self.mesh.NbSubMesh()
3562 def GetElementsId(self):
3564 Return the list of all mesh elements IDs
3567 the list of integer values
3570 :meth:`GetElementsByType`
3573 return self.mesh.GetElementsId()
3575 def GetElementsByType(self, elementType):
3577 Return the list of IDs of mesh elements with the given type
3580 elementType (SMESH.ElementType): the required type of elements
3583 list of integer values
3586 return self.mesh.GetElementsByType(elementType)
3588 def GetNodesId(self):
3590 Return the list of mesh nodes IDs
3593 the list of integer values
3596 return self.mesh.GetNodesId()
3598 # Get the information about mesh elements:
3599 # ------------------------------------
3601 def GetElementType(self, id, iselem=True):
3603 Return the type of mesh element or node
3606 the value from :class:`SMESH.ElementType` enumeration.
3607 Return SMESH.ALL if element or node with the given ID does not exist
3610 return self.mesh.GetElementType(id, iselem)
3612 def GetElementGeomType(self, id):
3614 Return the geometric type of mesh element
3617 the value from :class:`SMESH.EntityType` enumeration.
3620 return self.mesh.GetElementGeomType(id)
3622 def GetElementShape(self, id):
3624 Return the shape type of mesh element
3627 the value from :class:`SMESH.GeometryType` enumeration.
3630 return self.mesh.GetElementShape(id)
3632 def GetSubMeshElementsId(self, Shape):
3634 Return the list of sub-mesh elements IDs
3637 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3638 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3641 list of integer values
3644 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3645 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3648 return self.mesh.GetSubMeshElementsId(ShapeID)
3650 def GetSubMeshNodesId(self, Shape, all):
3652 Return the list of sub-mesh nodes IDs
3655 Shape: a geom object (sub-shape).
3656 *Shape* must be the sub-shape of a :meth:`GetShape`
3657 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3660 list of integer values
3663 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3664 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3667 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3669 def GetSubMeshElementType(self, Shape):
3671 Return type of elements on given shape
3674 Shape: a geom object (sub-shape).
3675 *Shape* must be a sub-shape of a ShapeToMesh()
3678 :class:`SMESH.ElementType`
3681 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3682 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3685 return self.mesh.GetSubMeshElementType(ShapeID)
3689 Get the mesh description
3695 return self.mesh.Dump()
3698 # Get the information about nodes and elements of a mesh by its IDs:
3699 # -----------------------------------------------------------
3701 def GetNodeXYZ(self, id):
3703 Get XYZ coordinates of a node.
3704 If there is no node for the given ID - return an empty list
3707 list of float values
3710 return self.mesh.GetNodeXYZ(id)
3712 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3714 Return list of IDs of inverse elements for the given node.
3715 If there is no node for the given ID - return an empty list
3719 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3722 list of integer values
3725 return self.mesh.GetNodeInverseElements(id,elemType)
3727 def GetNodePosition(self,NodeID):
3729 Return the position of a node on the shape
3732 :class:`SMESH.NodePosition`
3735 return self.mesh.GetNodePosition(NodeID)
3737 def GetElementPosition(self,ElemID):
3739 Return the position of an element on the shape
3742 :class:`SMESH.ElementPosition`
3745 return self.mesh.GetElementPosition(ElemID)
3747 def GetShapeID(self, id):
3749 Return the ID of the shape, on which the given node was generated.
3752 an integer value > 0 or -1 if there is no node for the given
3753 ID or the node is not assigned to any geometry
3756 return self.mesh.GetShapeID(id)
3758 def GetShapeIDForElem(self,id):
3760 Return the ID of the shape, on which the given element was generated.
3763 an integer value > 0 or -1 if there is no element for the given
3764 ID or the element is not assigned to any geometry
3767 return self.mesh.GetShapeIDForElem(id)
3769 def GetElemNbNodes(self, id):
3771 Return the number of nodes of the given element
3774 an integer value > 0 or -1 if there is no element for the given ID
3777 return self.mesh.GetElemNbNodes(id)
3779 def GetElemNode(self, id, index):
3781 Return the node ID the given (zero based) index for the given element.
3783 * If there is no element for the given ID - return -1.
3784 * If there is no node for the given index - return -2.
3787 id (int): element ID
3788 index (int): node index within the element
3791 an integer value (ID)
3794 :meth:`GetElemNodes`
3797 return self.mesh.GetElemNode(id, index)
3799 def GetElemNodes(self, id):
3801 Return the IDs of nodes of the given element
3804 a list of integer values
3807 return self.mesh.GetElemNodes(id)
3809 def IsMediumNode(self, elementID, nodeID):
3811 Return true if the given node is the medium node in the given quadratic element
3814 return self.mesh.IsMediumNode(elementID, nodeID)
3816 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3818 Return true if the given node is the medium node in one of quadratic elements
3821 nodeID: ID of the node
3822 elementType: the type of elements to check a state of the node, either of
3823 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3826 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3828 def ElemNbEdges(self, id):
3830 Return the number of edges for the given element
3833 return self.mesh.ElemNbEdges(id)
3835 def ElemNbFaces(self, id):
3837 Return the number of faces for the given element
3840 return self.mesh.ElemNbFaces(id)
3842 def GetElemFaceNodes(self,elemId, faceIndex):
3844 Return nodes of given face (counted from zero) for given volumic element.
3847 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3849 def GetFaceNormal(self, faceId, normalized=False):
3851 Return three components of normal of given mesh face
3852 (or an empty array in KO case)
3855 return self.mesh.GetFaceNormal(faceId,normalized)
3857 def FindElementByNodes(self, nodes):
3859 Return an element based on all given nodes.
3862 return self.mesh.FindElementByNodes(nodes)
3864 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3866 Return elements including all given nodes.
3869 return self.mesh.GetElementsByNodes( nodes, elemType )
3871 def IsPoly(self, id):
3873 Return true if the given element is a polygon
3876 return self.mesh.IsPoly(id)
3878 def IsQuadratic(self, id):
3880 Return true if the given element is quadratic
3883 return self.mesh.IsQuadratic(id)
3885 def GetBallDiameter(self, id):
3887 Return diameter of a ball discrete element or zero in case of an invalid *id*
3890 return self.mesh.GetBallDiameter(id)
3892 def BaryCenter(self, id):
3894 Return XYZ coordinates of the barycenter of the given element.
3895 If there is no element for the given ID - return an empty list
3898 a list of three double values
3901 :meth:`smeshBuilder.GetGravityCenter`
3904 return self.mesh.BaryCenter(id)
3906 def GetIdsFromFilter(self, filter, meshParts=[] ):
3908 Pass mesh elements through the given filter and return IDs of fitting elements
3911 filter: :class:`SMESH.Filter`
3912 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3918 :meth:`SMESH.Filter.GetIDs`
3919 :meth:`SMESH.Filter.GetElementsIdFromParts`
3922 filter.SetMesh( self.mesh )
3925 if isinstance( meshParts, Mesh ):
3926 filter.SetMesh( meshParts.GetMesh() )
3927 return theFilter.GetIDs()
3928 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3929 meshParts = [ meshParts ]
3930 return filter.GetElementsIdFromParts( meshParts )
3932 return filter.GetIDs()
3934 # Get mesh measurements information:
3935 # ------------------------------------
3937 def GetFreeBorders(self):
3939 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3940 Return a list of special structures (borders).
3943 a list of :class:`SMESH.FreeEdges.Border`
3946 aFilterMgr = self.smeshpyD.CreateFilterManager()
3947 aPredicate = aFilterMgr.CreateFreeEdges()
3948 aPredicate.SetMesh(self.mesh)
3949 aBorders = aPredicate.GetBorders()
3950 aFilterMgr.UnRegister()
3953 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3955 Get minimum distance between two nodes, elements or distance to the origin
3958 id1: first node/element id
3959 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3960 isElem1: *True* if *id1* is element id, *False* if it is node id
3961 isElem2: *True* if *id2* is element id, *False* if it is node id
3964 minimum distance value
3966 :meth:`GetMinDistance`
3969 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3970 return aMeasure.value
3972 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3974 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3977 id1: first node/element id
3978 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3979 isElem1: *True* if *id1* is element id, *False* if it is node id
3980 isElem2: *True* if *id2* is element id, *False* if it is node id
3983 :class:`SMESH.Measure` structure
3989 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3991 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3994 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3996 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4001 aMeasurements = self.smeshpyD.CreateMeasurements()
4002 aMeasure = aMeasurements.MinDistance(id1, id2)
4003 genObjUnRegister([aMeasurements,id1, id2])
4006 def BoundingBox(self, objects=None, isElem=False):
4008 Get bounding box of the specified object(s)
4011 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4012 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4013 *False* specifies that *objects* are nodes
4016 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4019 :meth:`GetBoundingBox()`
4022 result = self.GetBoundingBox(objects, isElem)
4026 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4029 def GetBoundingBox(self, objects=None, isElem=False):
4031 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4034 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4035 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4036 False means that *objects* are nodes
4039 :class:`SMESH.Measure` structure
4042 :meth:`BoundingBox()`
4046 objects = [self.mesh]
4047 elif isinstance(objects, tuple):
4048 objects = list(objects)
4049 if not isinstance(objects, list):
4051 if len(objects) > 0 and isinstance(objects[0], int):
4054 unRegister = genObjUnRegister()
4056 if isinstance(o, Mesh):
4057 srclist.append(o.mesh)
4058 elif hasattr(o, "_narrow"):
4059 src = o._narrow(SMESH.SMESH_IDSource)
4060 if src: srclist.append(src)
4062 elif isinstance(o, list):
4064 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4066 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4067 unRegister.set( srclist[-1] )
4070 aMeasurements = self.smeshpyD.CreateMeasurements()
4071 unRegister.set( aMeasurements )
4072 aMeasure = aMeasurements.BoundingBox(srclist)
4075 # Mesh edition (SMESH_MeshEditor functionality):
4076 # ---------------------------------------------
4078 def RemoveElements(self, IDsOfElements):
4080 Remove the elements from the mesh by ids
4083 IDsOfElements: is a list of ids of elements to remove
4089 This operation can create gaps in numeration of elements.
4090 Call :meth:`RenumberElements` to remove the gaps.
4093 return self.editor.RemoveElements(IDsOfElements)
4095 def RemoveNodes(self, IDsOfNodes):
4097 Remove nodes from mesh by ids
4100 IDsOfNodes: is a list of ids of nodes to remove
4106 This operation can create gaps in numeration of nodes.
4107 Call :meth:`RenumberElements` to remove the gaps.
4110 return self.editor.RemoveNodes(IDsOfNodes)
4112 def RemoveOrphanNodes(self):
4114 Remove all orphan (free) nodes from mesh
4117 number of the removed nodes
4120 This operation can create gaps in numeration of nodes.
4121 Call :meth:`RenumberElements` to remove the gaps.
4124 return self.editor.RemoveOrphanNodes()
4126 def AddNode(self, x, y, z):
4128 Add a node to the mesh by coordinates
4134 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4135 if hasVars: self.mesh.SetParameters(Parameters)
4136 return self.editor.AddNode( x, y, z)
4138 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4140 Create a 0D element on a node with given number.
4143 IDOfNode: the ID of node for creation of the element.
4144 DuplicateElements: to add one more 0D element to a node or not
4147 ID of the new 0D element
4150 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4152 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4154 Create 0D elements on all nodes of the given elements except those
4155 nodes on which a 0D element already exists.
4158 theObject: an object on whose nodes 0D elements will be created.
4159 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4160 theGroupName: optional name of a group to add 0D elements created
4161 and/or found on nodes of *theObject*.
4162 DuplicateElements: to add one more 0D element to a node or not
4165 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4166 IDs of new and/or found 0D elements. IDs of 0D elements
4167 can be retrieved from the returned object by
4168 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4171 unRegister = genObjUnRegister()
4172 if isinstance( theObject, Mesh ):
4173 theObject = theObject.GetMesh()
4174 elif isinstance( theObject, list ):
4175 theObject = self.GetIDSource( theObject, SMESH.ALL )
4176 unRegister.set( theObject )
4177 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4179 def AddBall(self, IDOfNode, diameter):
4181 Create a ball element on a node with given ID.
4184 IDOfNode: the ID of node for creation of the element.
4185 diameter: the bal diameter.
4188 ID of the new ball element
4191 return self.editor.AddBall( IDOfNode, diameter )
4193 def AddEdge(self, IDsOfNodes):
4195 Create a linear or quadratic edge (this is determined
4196 by the number of given nodes).
4199 IDsOfNodes: list of node IDs for creation of the element.
4200 The order of nodes in this list should correspond to
4201 the :ref:`connectivity convention <connectivity_page>`.
4207 return self.editor.AddEdge(IDsOfNodes)
4209 def AddFace(self, IDsOfNodes):
4211 Create a linear or quadratic face (this is determined
4212 by the number of given nodes).
4215 IDsOfNodes: list of node IDs for creation of the element.
4216 The order of nodes in this list should correspond to
4217 the :ref:`connectivity convention <connectivity_page>`.
4223 return self.editor.AddFace(IDsOfNodes)
4225 def AddPolygonalFace(self, IdsOfNodes):
4227 Add a polygonal face defined by a list of node IDs
4230 IdsOfNodes: the list of node IDs for creation of the element.
4236 return self.editor.AddPolygonalFace(IdsOfNodes)
4238 def AddQuadPolygonalFace(self, IdsOfNodes):
4240 Add a quadratic polygonal face defined by a list of node IDs
4243 IdsOfNodes: the list of node IDs for creation of the element;
4244 corner nodes follow first.
4250 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4252 def AddVolume(self, IDsOfNodes):
4254 Create both simple and quadratic volume (this is determined
4255 by the number of given nodes).
4258 IDsOfNodes: list of node IDs for creation of the element.
4259 The order of nodes in this list should correspond to
4260 the :ref:`connectivity convention <connectivity_page>`.
4263 ID of the new volumic element
4266 return self.editor.AddVolume(IDsOfNodes)
4268 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4270 Create a volume of many faces, giving nodes for each face.
4273 IdsOfNodes: list of node IDs for volume creation, face by face.
4274 Quantities: list of integer values, Quantities[i]
4275 gives the quantity of nodes in face number i.
4278 ID of the new volumic element
4281 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4283 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4285 Create a volume of many faces, giving the IDs of the existing faces.
4288 The created volume will refer only to the nodes
4289 of the given faces, not to the faces themselves.
4292 IdsOfFaces: the list of face IDs for volume creation.
4295 ID of the new volumic element
4298 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4301 def SetNodeOnVertex(self, NodeID, Vertex):
4303 Bind a node to a vertex
4307 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4310 True if succeed else raises an exception
4313 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4314 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4318 self.editor.SetNodeOnVertex(NodeID, VertexID)
4319 except SALOME.SALOME_Exception as inst:
4320 raise ValueError(inst.details.text)
4324 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4326 Store the node position on an edge
4330 Edge: an edge (GEOM.GEOM_Object) or edge ID
4331 paramOnEdge: a parameter on the edge where the node is located
4334 True if succeed else raises an exception
4337 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4338 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4342 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4343 except SALOME.SALOME_Exception as inst:
4344 raise ValueError(inst.details.text)
4347 def SetNodeOnFace(self, NodeID, Face, u, v):
4349 Store node position on a face
4353 Face: a face (GEOM.GEOM_Object) or face ID
4354 u: U parameter on the face where the node is located
4355 v: V parameter on the face where the node is located
4358 True if succeed else raises an exception
4361 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4362 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4366 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4367 except SALOME.SALOME_Exception as inst:
4368 raise ValueError(inst.details.text)
4371 def SetNodeInVolume(self, NodeID, Solid):
4373 Bind a node to a solid
4377 Solid: a solid (GEOM.GEOM_Object) or solid ID
4380 True if succeed else raises an exception
4383 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4384 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4388 self.editor.SetNodeInVolume(NodeID, SolidID)
4389 except SALOME.SALOME_Exception as inst:
4390 raise ValueError(inst.details.text)
4393 def SetMeshElementOnShape(self, ElementID, Shape):
4395 Bind an element to a shape
4398 ElementID: an element ID
4399 Shape: a shape (GEOM.GEOM_Object) or shape ID
4402 True if succeed else raises an exception
4405 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4406 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4410 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4411 except SALOME.SALOME_Exception as inst:
4412 raise ValueError(inst.details.text)
4416 def MoveNode(self, NodeID, x, y, z):
4418 Move the node with the given id
4421 NodeID: the id of the node
4422 x: a new X coordinate
4423 y: a new Y coordinate
4424 z: a new Z coordinate
4427 True if succeed else False
4430 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4431 if hasVars: self.mesh.SetParameters(Parameters)
4432 return self.editor.MoveNode(NodeID, x, y, z)
4434 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4436 Find the node closest to a point and moves it to a point location
4439 x: the X coordinate of a point
4440 y: the Y coordinate of a point
4441 z: the Z coordinate of a point
4442 NodeID: if specified (>0), the node with this ID is moved,
4443 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4446 the ID of a moved node
4449 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4450 if hasVars: self.mesh.SetParameters(Parameters)
4451 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4453 def FindNodeClosestTo(self, x, y, z):
4455 Find the node closest to a point
4458 x: the X coordinate of a point
4459 y: the Y coordinate of a point
4460 z: the Z coordinate of a point
4466 return self.editor.FindNodeClosestTo(x, y, z)
4468 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4470 Find the elements where a point lays IN or ON
4473 x,y,z (float): coordinates of the point
4474 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4475 means elements of any type excluding nodes, discrete and 0D elements.
4476 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4479 list of IDs of found elements
4482 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4484 return self.editor.FindElementsByPoint(x, y, z, elementType)
4486 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4488 Project a point to a mesh object.
4489 Return ID of an element of given type where the given point is projected
4490 and coordinates of the projection point.
4491 In the case if nothing found, return -1 and []
4493 if isinstance( meshObject, Mesh ):
4494 meshObject = meshObject.GetMesh()
4496 meshObject = self.GetMesh()
4497 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4499 def GetPointState(self, x, y, z):
4501 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4502 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4503 UNKNOWN state means that either mesh is wrong or the analysis fails.
4506 return self.editor.GetPointState(x, y, z)
4508 def IsManifold(self):
4510 Check if a 2D mesh is manifold
4513 return self.editor.IsManifold()
4515 def IsCoherentOrientation2D(self):
4517 Check if orientation of 2D elements is coherent
4520 return self.editor.IsCoherentOrientation2D()
4522 def Get1DBranches( self, edges, startNode = 0 ):
4524 Partition given 1D elements into groups of contiguous edges.
4525 A node where number of meeting edges != 2 is a group end.
4526 An optional startNode is used to orient groups it belongs to.
4529 A list of edge groups and a list of corresponding node groups,
4530 where the group is a list of IDs of edges or nodes, like follows
4531 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4532 If a group is closed, the first and last nodes of the group are same.
4534 if isinstance( edges, Mesh ):
4535 edges = edges.GetMesh()
4536 unRegister = genObjUnRegister()
4537 if isinstance( edges, list ):
4538 edges = self.GetIDSource( edges, SMESH.EDGE )
4539 unRegister.set( edges )
4540 return self.editor.Get1DBranches( edges, startNode )
4542 def FindSharpEdges( self, angle, addExisting=False ):
4544 Return sharp edges of faces and non-manifold ones.
4545 Optionally add existing edges.
4548 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4549 addExisting: to return existing edges (1D elements) as well
4552 list of FaceEdge structures
4554 angle = ParseParameters( angle )[0]
4555 return self.editor.FindSharpEdges( angle, addExisting )
4557 def MeshToPassThroughAPoint(self, x, y, z):
4559 Find the node closest to a point and moves it to a point location
4562 x: the X coordinate of a point
4563 y: the Y coordinate of a point
4564 z: the Z coordinate of a point
4567 the ID of a moved node
4570 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4572 def InverseDiag(self, NodeID1, NodeID2):
4574 Replace two neighbour triangles sharing Node1-Node2 link
4575 with the triangles built on the same 4 nodes but having other common link.
4578 NodeID1: the ID of the first node
4579 NodeID2: the ID of the second node
4582 False if proper faces were not found
4584 return self.editor.InverseDiag(NodeID1, NodeID2)
4586 def DeleteDiag(self, NodeID1, NodeID2):
4588 Replace two neighbour triangles sharing *Node1-Node2* link
4589 with a quadrangle built on the same 4 nodes.
4592 NodeID1: ID of the first node
4593 NodeID2: ID of the second node
4596 False if proper faces were not found
4599 This operation can create gaps in numeration of elements.
4600 Call :meth:`RenumberElements` to remove the gaps.
4603 return self.editor.DeleteDiag(NodeID1, NodeID2)
4605 def Reorient(self, IDsOfElements=None):
4607 Reorient elements by ids
4610 IDsOfElements: if undefined reorients all mesh elements
4613 True if succeed else False
4616 if IDsOfElements == None:
4617 IDsOfElements = self.GetElementsId()
4618 return self.editor.Reorient(IDsOfElements)
4620 def ReorientObject(self, theObject):
4622 Reorient all elements of the object
4625 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4628 True if succeed else False
4631 if ( isinstance( theObject, Mesh )):
4632 theObject = theObject.GetMesh()
4633 return self.editor.ReorientObject(theObject)
4635 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4637 Reorient faces contained in *the2DObject*.
4640 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4641 theDirection: a desired direction of normal of *theFace*.
4642 It can be either a GEOM vector or a list of coordinates [x,y,z].
4643 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4644 compared with theDirection. It can be either ID of face or a point
4645 by which the face will be found. The point can be given as either
4646 a GEOM vertex or a list of point coordinates.
4649 number of reoriented faces
4652 unRegister = genObjUnRegister()
4654 if isinstance( the2DObject, Mesh ):
4655 the2DObject = the2DObject.GetMesh()
4656 if isinstance( the2DObject, list ):
4657 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4658 unRegister.set( the2DObject )
4659 # check theDirection
4660 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4661 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4662 if isinstance( theDirection, list ):
4663 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4664 # prepare theFace and thePoint
4665 theFace = theFaceOrPoint
4666 thePoint = PointStruct(0,0,0)
4667 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4668 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4670 if isinstance( theFaceOrPoint, list ):
4671 thePoint = PointStruct( *theFaceOrPoint )
4673 if isinstance( theFaceOrPoint, PointStruct ):
4674 thePoint = theFaceOrPoint
4676 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4678 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4680 Reorient faces according to adjacent volumes.
4683 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4684 either IDs of faces or face groups.
4685 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4686 theOutsideNormal: to orient faces to have their normals
4687 pointing either *outside* or *inside* the adjacent volumes.
4690 number of reoriented faces.
4693 unRegister = genObjUnRegister()
4695 if not isinstance( the2DObject, list ):
4696 the2DObject = [ the2DObject ]
4697 elif the2DObject and isinstance( the2DObject[0], int ):
4698 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4699 unRegister.set( the2DObject )
4700 the2DObject = [ the2DObject ]
4701 for i,obj2D in enumerate( the2DObject ):
4702 if isinstance( obj2D, Mesh ):
4703 the2DObject[i] = obj2D.GetMesh()
4704 if isinstance( obj2D, list ):
4705 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4706 unRegister.set( the2DObject[i] )
4708 if isinstance( the3DObject, Mesh ):
4709 the3DObject = the3DObject.GetMesh()
4710 if isinstance( the3DObject, list ):
4711 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4712 unRegister.set( the3DObject )
4713 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4715 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4717 Fuse the neighbouring triangles into quadrangles.
4720 IDsOfElements: The triangles to be fused.
4721 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4722 applied to possible quadrangles to choose a neighbour to fuse with.
4723 Note that not all items of :class:`SMESH.FunctorType` corresponds
4724 to numerical functors.
4725 MaxAngle: is the maximum angle between element normals at which the fusion
4726 is still performed; theMaxAngle is measured in radians.
4727 Also it could be a name of variable which defines angle in degrees.
4730 True in case of success, False otherwise.
4733 This operation can create gaps in numeration of elements.
4734 Call :meth:`RenumberElements` to remove the gaps.
4737 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4738 self.mesh.SetParameters(Parameters)
4739 if not IDsOfElements:
4740 IDsOfElements = self.GetElementsId()
4741 Functor = self.smeshpyD.GetFunctor(theCriterion)
4742 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4744 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4746 Fuse the neighbouring triangles of the object into quadrangles
4749 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4750 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4751 applied to possible quadrangles to choose a neighbour to fuse with.
4752 Note that not all items of :class:`SMESH.FunctorType` corresponds
4753 to numerical functors.
4754 MaxAngle: a max angle between element normals at which the fusion
4755 is still performed; theMaxAngle is measured in radians.
4758 True in case of success, False otherwise.
4761 This operation can create gaps in numeration of elements.
4762 Call :meth:`RenumberElements` to remove the gaps.
4765 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4766 self.mesh.SetParameters(Parameters)
4767 if isinstance( theObject, Mesh ):
4768 theObject = theObject.GetMesh()
4769 Functor = self.smeshpyD.GetFunctor(theCriterion)
4770 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4772 def QuadToTri (self, IDsOfElements, theCriterion = None):
4774 Split quadrangles into triangles.
4777 IDsOfElements: the faces to be splitted.
4778 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4779 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4780 value, then quadrangles will be split by the smallest diagonal.
4781 Note that not all items of :class:`SMESH.FunctorType` corresponds
4782 to numerical functors.
4785 True in case of success, False otherwise.
4788 This operation can create gaps in numeration of elements.
4789 Call :meth:`RenumberElements` to remove the gaps.
4791 if IDsOfElements == []:
4792 IDsOfElements = self.GetElementsId()
4793 if theCriterion is None:
4794 theCriterion = FT_MaxElementLength2D
4795 Functor = self.smeshpyD.GetFunctor(theCriterion)
4796 return self.editor.QuadToTri(IDsOfElements, Functor)
4798 def QuadToTriObject (self, theObject, theCriterion = None):
4800 Split quadrangles into triangles.
4803 theObject: the object from which the list of elements is taken,
4804 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4805 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4806 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4807 value, then quadrangles will be split by the smallest diagonal.
4808 Note that not all items of :class:`SMESH.FunctorType` corresponds
4809 to numerical functors.
4812 True in case of success, False otherwise.
4815 This operation can create gaps in numeration of elements.
4816 Call :meth:`RenumberElements` to remove the gaps.
4818 if ( isinstance( theObject, Mesh )):
4819 theObject = theObject.GetMesh()
4820 if theCriterion is None:
4821 theCriterion = FT_MaxElementLength2D
4822 Functor = self.smeshpyD.GetFunctor(theCriterion)
4823 return self.editor.QuadToTriObject(theObject, Functor)
4825 def QuadTo4Tri (self, theElements=[]):
4827 Split each of given quadrangles into 4 triangles. A node is added at the center of
4831 theElements: the faces to be splitted. This can be either
4832 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4833 or a list of face IDs. By default all quadrangles are split
4836 This operation can create gaps in numeration of elements.
4837 Call :meth:`RenumberElements` to remove the gaps.
4839 unRegister = genObjUnRegister()
4840 if isinstance( theElements, Mesh ):
4841 theElements = theElements.mesh
4842 elif not theElements:
4843 theElements = self.mesh
4844 elif isinstance( theElements, list ):
4845 theElements = self.GetIDSource( theElements, SMESH.FACE )
4846 unRegister.set( theElements )
4847 return self.editor.QuadTo4Tri( theElements )
4849 def SplitQuad (self, IDsOfElements, Diag13):
4851 Split quadrangles into triangles.
4854 IDsOfElements: the faces to be splitted
4855 Diag13 (boolean): is used to choose a diagonal for splitting.
4858 True in case of success, False otherwise.
4861 This operation can create gaps in numeration of elements.
4862 Call :meth:`RenumberElements` to remove the gaps.
4864 if IDsOfElements == []:
4865 IDsOfElements = self.GetElementsId()
4866 return self.editor.SplitQuad(IDsOfElements, Diag13)
4868 def SplitQuadObject (self, theObject, Diag13):
4870 Split quadrangles into triangles.
4873 theObject: the object from which the list of elements is taken,
4874 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4875 Diag13 (boolean): is used to choose a diagonal for splitting.
4878 True in case of success, False otherwise.
4881 This operation can create gaps in numeration of elements.
4882 Call :meth:`RenumberElements` to remove the gaps.
4884 if ( isinstance( theObject, Mesh )):
4885 theObject = theObject.GetMesh()
4886 return self.editor.SplitQuadObject(theObject, Diag13)
4888 def BestSplit (self, IDOfQuad, theCriterion):
4890 Find a better splitting of the given quadrangle.
4893 IDOfQuad: the ID of the quadrangle to be splitted.
4894 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4895 choose a diagonal for splitting.
4896 Note that not all items of :class:`SMESH.FunctorType` corresponds
4897 to numerical functors.
4900 * 1 if 1-3 diagonal is better,
4901 * 2 if 2-4 diagonal is better,
4902 * 0 if error occurs.
4905 This operation can create gaps in numeration of elements.
4906 Call :meth:`RenumberElements` to remove the gaps.
4908 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4910 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4912 Split volumic elements into tetrahedrons
4915 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4916 method: flags passing splitting method:
4917 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4918 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4921 This operation can create gaps in numeration of elements.
4922 Call :meth:`RenumberElements` to remove the gaps.
4924 unRegister = genObjUnRegister()
4925 if isinstance( elems, Mesh ):
4926 elems = elems.GetMesh()
4927 if ( isinstance( elems, list )):
4928 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4929 unRegister.set( elems )
4930 self.editor.SplitVolumesIntoTetra(elems, method)
4933 def SplitBiQuadraticIntoLinear(self, elems=None):
4935 Split bi-quadratic elements into linear ones without creation of additional nodes:
4937 - bi-quadratic triangle will be split into 3 linear quadrangles;
4938 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4939 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4941 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4942 will be split in order to keep the mesh conformal.
4945 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4946 if None (default), all bi-quadratic elements will be split
4949 This operation can create gaps in numeration of elements.
4950 Call :meth:`RenumberElements` to remove the gaps.
4952 unRegister = genObjUnRegister()
4953 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4954 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4955 unRegister.set( elems )
4957 elems = [ self.GetMesh() ]
4958 if isinstance( elems, Mesh ):
4959 elems = [ elems.GetMesh() ]
4960 if not isinstance( elems, list ):
4962 self.editor.SplitBiQuadraticIntoLinear( elems )
4964 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4965 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4967 Split hexahedra into prisms
4970 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4971 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4972 gives a normal vector defining facets to split into triangles.
4973 *startHexPoint* can be either a triple of coordinates or a vertex.
4974 facetNormal: a normal to a facet to split into triangles of a
4975 hexahedron found by *startHexPoint*.
4976 *facetNormal* can be either a triple of coordinates or an edge.
4977 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4978 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4979 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4980 to *startHexPoint* are split, else *startHexPoint*
4981 is used to find the facet to split in all domains present in *elems*.
4984 This operation can create gaps in numeration of elements.
4985 Call :meth:`RenumberElements` to remove the gaps.
4988 unRegister = genObjUnRegister()
4989 if isinstance( elems, Mesh ):
4990 elems = elems.GetMesh()
4991 if ( isinstance( elems, list )):
4992 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4993 unRegister.set( elems )
4996 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4997 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4998 elif isinstance( startHexPoint, list ):
4999 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5002 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5003 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5004 elif isinstance( facetNormal, list ):
5005 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5008 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5010 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5012 def SplitQuadsNearTriangularFacets(self):
5014 Split quadrangle faces near triangular facets of volumes
5017 This operation can create gaps in numeration of elements.
5018 Call :meth:`RenumberElements` to remove the gaps.
5020 faces_array = self.GetElementsByType(SMESH.FACE)
5021 for face_id in faces_array:
5022 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5023 quad_nodes = self.mesh.GetElemNodes(face_id)
5024 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5025 isVolumeFound = False
5026 for node1_elem in node1_elems:
5027 if not isVolumeFound:
5028 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5029 nb_nodes = self.GetElemNbNodes(node1_elem)
5030 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5031 volume_elem = node1_elem
5032 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5033 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5034 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5035 isVolumeFound = True
5036 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5037 self.SplitQuad([face_id], False) # diagonal 2-4
5038 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5039 isVolumeFound = True
5040 self.SplitQuad([face_id], True) # diagonal 1-3
5041 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5042 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5043 isVolumeFound = True
5044 self.SplitQuad([face_id], True) # diagonal 1-3
5046 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5048 Split hexahedrons into tetrahedrons.
5050 This operation uses :doc:`pattern_mapping` functionality for splitting.
5053 theObject: the object from which the list of hexahedrons is taken;
5054 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5055 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5056 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5057 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5058 key-point will be mapped into *theNode001*-th node of each volume.
5059 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5062 True in case of success, False otherwise.
5065 This operation can create gaps in numeration of elements.
5066 Call :meth:`RenumberElements` to remove the gaps.
5074 # (0,0,1) 4.---------.7 * |
5081 # (0,0,0) 0.---------.3
5082 pattern_tetra = "!!! Nb of points: \n 8 \n\
5092 !!! Indices of points of 6 tetras: \n\
5100 pattern = self.smeshpyD.GetPattern()
5101 isDone = pattern.LoadFromFile(pattern_tetra)
5103 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5106 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5107 isDone = pattern.MakeMesh(self.mesh, False, False)
5108 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5110 # split quafrangle faces near triangular facets of volumes
5111 self.SplitQuadsNearTriangularFacets()
5115 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5117 Split hexahedrons into prisms.
5119 Uses the :doc:`pattern_mapping` functionality for splitting.
5122 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5123 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5124 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5125 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5126 will be mapped into the *theNode001* -th node of each volume.
5127 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5130 True in case of success, False otherwise.
5133 This operation can create gaps in numeration of elements.
5134 Call :meth:`RenumberElements` to remove the gaps.
5136 # Pattern: 5.---------.6
5141 # (0,0,1) 4.---------.7 |
5148 # (0,0,0) 0.---------.3
5149 pattern_prism = "!!! Nb of points: \n 8 \n\
5159 !!! Indices of points of 2 prisms: \n\
5163 pattern = self.smeshpyD.GetPattern()
5164 isDone = pattern.LoadFromFile(pattern_prism)
5166 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5169 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5170 isDone = pattern.MakeMesh(self.mesh, False, False)
5171 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5173 # Split quafrangle faces near triangular facets of volumes
5174 self.SplitQuadsNearTriangularFacets()
5178 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5179 MaxNbOfIterations, MaxAspectRatio, Method):
5184 IDsOfElements: the list if ids of elements to smooth
5185 IDsOfFixedNodes: the list of ids of fixed nodes.
5186 Note that nodes built on edges and boundary nodes are always fixed.
5187 MaxNbOfIterations: the maximum number of iterations
5188 MaxAspectRatio: varies in range [1.0, inf]
5189 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5190 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5193 True in case of success, False otherwise.
5196 if IDsOfElements == []:
5197 IDsOfElements = self.GetElementsId()
5198 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5199 self.mesh.SetParameters(Parameters)
5200 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5201 MaxNbOfIterations, MaxAspectRatio, Method)
5203 def SmoothObject(self, theObject, IDsOfFixedNodes,
5204 MaxNbOfIterations, MaxAspectRatio, Method):
5206 Smooth elements which belong to the given object
5209 theObject: the object to smooth
5210 IDsOfFixedNodes: the list of ids of fixed nodes.
5211 Note that nodes built on edges and boundary nodes are always fixed.
5212 MaxNbOfIterations: the maximum number of iterations
5213 MaxAspectRatio: varies in range [1.0, inf]
5214 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5215 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5218 True in case of success, False otherwise.
5221 if ( isinstance( theObject, Mesh )):
5222 theObject = theObject.GetMesh()
5223 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5224 MaxNbOfIterations, MaxAspectRatio, Method)
5226 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5227 MaxNbOfIterations, MaxAspectRatio, Method):
5229 Parametrically smooth the given elements
5232 IDsOfElements: the list if ids of elements to smooth
5233 IDsOfFixedNodes: the list of ids of fixed nodes.
5234 Note that nodes built on edges and boundary nodes are always fixed.
5235 MaxNbOfIterations: the maximum number of iterations
5236 MaxAspectRatio: varies in range [1.0, inf]
5237 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5238 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5241 True in case of success, False otherwise.
5244 if IDsOfElements == []:
5245 IDsOfElements = self.GetElementsId()
5246 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5247 self.mesh.SetParameters(Parameters)
5248 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5249 MaxNbOfIterations, MaxAspectRatio, Method)
5251 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5252 MaxNbOfIterations, MaxAspectRatio, Method):
5254 Parametrically smooth the elements which belong to the given object
5257 theObject: the object to smooth
5258 IDsOfFixedNodes: the list of ids of fixed nodes.
5259 Note that nodes built on edges and boundary nodes are always fixed.
5260 MaxNbOfIterations: the maximum number of iterations
5261 MaxAspectRatio: varies in range [1.0, inf]
5262 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5263 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5266 True in case of success, False otherwise.
5269 if ( isinstance( theObject, Mesh )):
5270 theObject = theObject.GetMesh()
5271 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5272 MaxNbOfIterations, MaxAspectRatio, Method)
5274 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5276 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5277 them with quadratic with the same id.
5280 theForce3d: method of new node creation:
5282 * False - the medium node lies at the geometrical entity from which the mesh element is built
5283 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5284 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5285 theToBiQuad: If True, converts the mesh to bi-quadratic
5288 :class:`SMESH.ComputeError` which can hold a warning
5291 If *theSubMesh* is provided, the mesh can become non-conformal
5294 This operation can create gaps in numeration of nodes or elements.
5295 Call :meth:`RenumberElements` to remove the gaps.
5298 if isinstance( theSubMesh, Mesh ):
5299 theSubMesh = theSubMesh.mesh
5301 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5304 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5306 self.editor.ConvertToQuadratic(theForce3d)
5307 error = self.editor.GetLastError()
5308 if error and error.comment:
5309 print(error.comment)
5312 def ConvertFromQuadratic(self, theSubMesh=None):
5314 Convert the mesh from quadratic to ordinary,
5315 deletes old quadratic elements,
5316 replacing them with ordinary mesh elements with the same id.
5319 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5322 If *theSubMesh* is provided, the mesh can become non-conformal
5325 This operation can create gaps in numeration of nodes or elements.
5326 Call :meth:`RenumberElements` to remove the gaps.
5330 self.editor.ConvertFromQuadraticObject(theSubMesh)
5332 return self.editor.ConvertFromQuadratic()
5334 def Make2DMeshFrom3D(self):
5336 Create 2D mesh as skin on boundary faces of a 3D mesh
5339 True if operation has been completed successfully, False otherwise
5342 return self.editor.Make2DMeshFrom3D()
5344 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5345 toCopyElements=False, toCopyExistingBondary=False):
5347 Create missing boundary elements
5350 elements: elements whose boundary is to be checked:
5351 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5352 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5353 dimension: defines type of boundary elements to create, either of
5354 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5355 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5356 groupName: a name of group to store created boundary elements in,
5357 "" means not to create the group
5358 meshName: a name of new mesh to store created boundary elements in,
5359 "" means not to create the new mesh
5360 toCopyElements: if True, the checked elements will be copied into
5361 the new mesh else only boundary elements will be copied into the new mesh
5362 toCopyExistingBondary: if True, not only new but also pre-existing
5363 boundary elements will be copied into the new mesh
5366 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5369 unRegister = genObjUnRegister()
5370 if isinstance( elements, Mesh ):
5371 elements = elements.GetMesh()
5372 if ( isinstance( elements, list )):
5373 elemType = SMESH.ALL
5374 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5375 elements = self.editor.MakeIDSource(elements, elemType)
5376 unRegister.set( elements )
5377 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5378 toCopyElements,toCopyExistingBondary)
5379 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5382 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5383 toCopyAll=False, groups=[]):
5385 Create missing boundary elements around either the whole mesh or
5389 dimension: defines type of boundary elements to create, either of
5390 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5391 groupName: a name of group to store all boundary elements in,
5392 "" means not to create the group
5393 meshName: a name of a new mesh, which is a copy of the initial
5394 mesh + created boundary elements; "" means not to create the new mesh
5395 toCopyAll: if True, the whole initial mesh will be copied into
5396 the new mesh else only boundary elements will be copied into the new mesh
5397 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5400 tuple( long, mesh, group )
5401 - long - number of added boundary elements
5402 - mesh - the :class:`Mesh` where elements were added to
5403 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5406 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5408 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5409 return nb, mesh, group
5411 def RenumberNodes(self):
5413 Renumber mesh nodes to remove unused node IDs
5415 self.editor.RenumberNodes()
5417 def RenumberElements(self):
5419 Renumber mesh elements to remove unused element IDs
5421 self.editor.RenumberElements()
5423 def _getIdSourceList(self, arg, idType, unRegister):
5425 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5427 if arg and isinstance( arg, list ):
5428 if isinstance( arg[0], int ):
5429 arg = self.GetIDSource( arg, idType )
5430 unRegister.set( arg )
5431 elif isinstance( arg[0], Mesh ):
5432 arg[0] = arg[0].GetMesh()
5433 elif isinstance( arg, Mesh ):
5435 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5439 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5440 MakeGroups=False, TotalAngle=False):
5442 Generate new elements by rotation of the given elements and nodes around the axis
5445 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5446 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5447 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5448 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5449 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5450 which defines angle in degrees
5451 NbOfSteps: the number of steps
5452 Tolerance: tolerance
5453 MakeGroups: forces the generation of new groups from existing ones
5454 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5455 of all steps, else - size of each step
5458 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5461 unRegister = genObjUnRegister()
5462 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5463 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5464 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5466 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5467 Axis = self.smeshpyD.GetAxisStruct( Axis )
5468 if isinstance( Axis, list ):
5469 Axis = SMESH.AxisStruct( *Axis )
5471 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5472 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5473 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5474 self.mesh.SetParameters(Parameters)
5475 if TotalAngle and NbOfSteps:
5476 AngleInRadians /= NbOfSteps
5477 return self.editor.RotationSweepObjects( nodes, edges, faces,
5478 Axis, AngleInRadians,
5479 NbOfSteps, Tolerance, MakeGroups)
5481 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5482 MakeGroups=False, TotalAngle=False):
5484 Generate new elements by rotation of the elements around the axis
5487 IDsOfElements: the list of ids of elements to sweep
5488 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5489 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5490 NbOfSteps: the number of steps
5491 Tolerance: tolerance
5492 MakeGroups: forces the generation of new groups from existing ones
5493 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5494 of all steps, else - size of each step
5497 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5500 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5501 AngleInRadians, NbOfSteps, Tolerance,
5502 MakeGroups, TotalAngle)
5504 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5505 MakeGroups=False, TotalAngle=False):
5507 Generate new elements by rotation of the elements of object around the axis
5508 theObject object which elements should be sweeped.
5509 It can be a mesh, a sub mesh or a group.
5512 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5513 AngleInRadians: the angle of Rotation
5514 NbOfSteps: number of steps
5515 Tolerance: tolerance
5516 MakeGroups: forces the generation of new groups from existing ones
5517 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5518 of all steps, else - size of each step
5521 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5524 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5525 AngleInRadians, NbOfSteps, Tolerance,
5526 MakeGroups, TotalAngle )
5528 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5529 MakeGroups=False, TotalAngle=False):
5531 Generate new elements by rotation of the elements of object around the axis
5532 theObject object which elements should be sweeped.
5533 It can be a mesh, a sub mesh or a group.
5536 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5537 AngleInRadians: the angle of Rotation
5538 NbOfSteps: number of steps
5539 Tolerance: tolerance
5540 MakeGroups: forces the generation of new groups from existing ones
5541 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5542 of all steps, else - size of each step
5545 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5546 empty list otherwise
5549 return self.RotationSweepObjects([],theObject,[], Axis,
5550 AngleInRadians, NbOfSteps, Tolerance,
5551 MakeGroups, TotalAngle)
5553 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5554 MakeGroups=False, TotalAngle=False):
5556 Generate new elements by rotation of the elements of object around the axis
5557 theObject object which elements should be sweeped.
5558 It can be a mesh, a sub mesh or a group.
5561 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5562 AngleInRadians: the angle of Rotation
5563 NbOfSteps: number of steps
5564 Tolerance: tolerance
5565 MakeGroups: forces the generation of new groups from existing ones
5566 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5567 of all steps, else - size of each step
5570 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5573 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5574 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5576 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5577 scaleFactors=[], linearVariation=False, basePoint=[],
5578 angles=[], anglesVariation=False):
5580 Generate new elements by extrusion of the given elements and nodes
5583 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5584 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5585 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5586 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5587 the direction and value of extrusion for one step (the total extrusion
5588 length will be NbOfSteps * ||StepVector||)
5589 NbOfSteps: the number of steps
5590 MakeGroups: forces the generation of new groups from existing ones
5591 scaleFactors: optional scale factors to apply during extrusion
5592 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5593 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5594 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5595 nodes and elements being extruded is used as the scaling center.
5598 - a list of tree components of the point or
5601 angles: list of angles in radians. Nodes at each extrusion step are rotated
5602 around *basePoint*, additionally to previous steps.
5603 anglesVariation: forces the computation of rotation angles as linear
5604 variation of the given *angles* along path steps
5606 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5608 Example: :ref:`tui_extrusion`
5610 unRegister = genObjUnRegister()
5611 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5612 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5613 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5615 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5616 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5617 if isinstance( StepVector, list ):
5618 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5620 if isinstance( basePoint, int):
5621 xyz = self.GetNodeXYZ( basePoint )
5623 raise RuntimeError("Invalid node ID: %s" % basePoint)
5625 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5626 basePoint = self.geompyD.PointCoordinates( basePoint )
5628 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5629 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5630 angles,angleParameters,hasVars = ParseAngles(angles)
5631 Parameters = StepVector.PS.parameters + var_separator + \
5632 Parameters + var_separator + \
5633 scaleParameters + var_separator + angleParameters
5634 self.mesh.SetParameters(Parameters)
5636 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5637 StepVector, NbOfSteps, MakeGroups,
5638 scaleFactors, linearVariation, basePoint,
5639 angles, anglesVariation )
5642 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5644 Generate new elements by extrusion of the elements with given ids
5647 IDsOfElements: the list of ids of elements or nodes for extrusion
5648 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5649 the direction and value of extrusion for one step (the total extrusion
5650 length will be NbOfSteps * ||StepVector||)
5651 NbOfSteps: the number of steps
5652 MakeGroups: forces the generation of new groups from existing ones
5653 IsNodes: is True if elements with given ids are nodes
5656 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5658 Example: :ref:`tui_extrusion`
5661 if IsNodes: n = IDsOfElements
5662 else : e,f, = IDsOfElements,IDsOfElements
5663 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5665 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5666 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5668 Generate new elements by extrusion along the normal to a discretized surface or wire
5671 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5672 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5673 StepSize: length of one extrusion step (the total extrusion
5674 length will be *NbOfSteps* *StepSize*).
5675 NbOfSteps: number of extrusion steps.
5676 ByAverageNormal: if True each node is translated by *StepSize*
5677 along the average of the normal vectors to the faces sharing the node;
5678 else each node is translated along the same average normal till
5679 intersection with the plane got by translation of the face sharing
5680 the node along its own normal by *StepSize*.
5681 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5682 for every node of *Elements*.
5683 MakeGroups: forces generation of new groups from existing ones.
5684 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5685 is not yet implemented. This parameter is used if *Elements* contains
5686 both faces and edges, i.e. *Elements* is a Mesh.
5689 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5690 empty list otherwise.
5691 Example: :ref:`tui_extrusion`
5694 unRegister = genObjUnRegister()
5695 if isinstance( Elements, Mesh ):
5696 Elements = [ Elements.GetMesh() ]
5697 if isinstance( Elements, list ):
5699 raise RuntimeError("Elements empty!")
5700 if isinstance( Elements[0], Mesh ):
5701 Elements = [ Elements[0].GetMesh() ]
5702 if isinstance( Elements[0], int ):
5703 Elements = self.GetIDSource( Elements, SMESH.ALL )
5704 unRegister.set( Elements )
5705 if not isinstance( Elements, list ):
5706 Elements = [ Elements ]
5707 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5708 self.mesh.SetParameters(Parameters)
5709 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5710 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5712 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5714 Generate new elements by extrusion of the elements or nodes which belong to the object
5717 theObject: the object whose elements or nodes should be processed.
5718 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5719 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5720 the direction and value of extrusion for one step (the total extrusion
5721 length will be NbOfSteps * ||StepVector||)
5722 NbOfSteps: the number of steps
5723 MakeGroups: forces the generation of new groups from existing ones
5724 IsNodes: is True if elements to extrude are nodes
5727 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5728 Example: :ref:`tui_extrusion`
5732 if IsNodes: n = theObject
5733 else : e,f, = theObject,theObject
5734 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5736 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5738 Generate new elements by extrusion of edges which belong to the object
5741 theObject: object whose 1D elements should be processed.
5742 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5743 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5744 the direction and value of extrusion for one step (the total extrusion
5745 length will be NbOfSteps * ||StepVector||)
5746 NbOfSteps: the number of steps
5747 MakeGroups: to generate new groups from existing ones
5750 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5751 Example: :ref:`tui_extrusion`
5754 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5756 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5758 Generate new elements by extrusion of faces which belong to the object
5761 theObject: object whose 2D elements should be processed.
5762 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5763 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5764 the direction and value of extrusion for one step (the total extrusion
5765 length will be NbOfSteps * ||StepVector||)
5766 NbOfSteps: the number of steps
5767 MakeGroups: forces the generation of new groups from existing ones
5770 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5771 Example: :ref:`tui_extrusion`
5774 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5776 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5777 ExtrFlags, SewTolerance, MakeGroups=False):
5779 Generate new elements by extrusion of the elements with given ids
5782 IDsOfElements: is ids of elements
5783 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5784 the direction and value of extrusion for one step (the total extrusion
5785 length will be NbOfSteps * ||StepVector||)
5786 NbOfSteps: the number of steps
5787 ExtrFlags: sets flags for extrusion
5788 SewTolerance: uses for comparing locations of nodes if flag
5789 EXTRUSION_FLAG_SEW is set
5790 MakeGroups: forces the generation of new groups from existing ones
5793 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5796 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5797 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5798 if isinstance( StepVector, list ):
5799 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5800 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5801 ExtrFlags, SewTolerance, MakeGroups)
5803 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5804 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5805 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5806 ScaleFactors=[], ScalesVariation=False):
5808 Generate new elements by extrusion of the given elements and nodes along the path.
5809 The path of extrusion must be a meshed edge.
5812 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5813 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5814 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5815 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5816 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
5817 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5818 HasAngles: not used obsolete
5819 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5820 around *basePoint*, additionally to previous steps.
5821 LinearVariation: forces the computation of rotation angles as linear
5822 variation of the given Angles along path steps
5823 HasRefPoint: allows using the reference point
5824 RefPoint: optional scaling and rotation center (mass center of the extruded
5825 elements by default). The User can specify any point as the Reference Point.
5826 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5827 MakeGroups: forces the generation of new groups from existing ones
5828 ScaleFactors: optional scale factors to apply during extrusion
5829 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5830 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5833 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5834 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5835 Example: :ref:`tui_extrusion_along_path`
5838 unRegister = genObjUnRegister()
5839 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5840 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5841 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5843 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5844 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5845 if isinstance( RefPoint, list ):
5846 if not RefPoint: RefPoint = [0,0,0]
5847 RefPoint = SMESH.PointStruct( *RefPoint )
5848 if isinstance( PathObject, Mesh ):
5849 PathObject = PathObject.GetMesh()
5850 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5851 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5852 Parameters = AnglesParameters + var_separator + \
5853 RefPoint.parameters + var_separator + ScalesParameters
5854 self.mesh.SetParameters(Parameters)
5855 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5856 PathObject, PathShape, NodeStart,
5857 HasAngles, Angles, LinearVariation,
5858 HasRefPoint, RefPoint, MakeGroups,
5859 ScaleFactors, ScalesVariation)
5861 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5862 HasAngles=False, Angles=[], LinearVariation=False,
5863 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5864 ElemType=SMESH.FACE):
5866 Generate new elements by extrusion of the given elements.
5867 The path of extrusion must be a meshed edge.
5870 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5871 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5872 NodeStart: the start node from Path. Defines the direction of extrusion
5873 HasAngles: not used obsolete
5874 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5875 around *basePoint*, additionally to previous steps.
5876 LinearVariation: forces the computation of rotation angles as linear
5877 variation of the given Angles along path steps
5878 HasRefPoint: allows using the reference point
5879 RefPoint: the reference point around which the elements are rotated (the mass
5880 center of the elements by default).
5881 The User can specify any point as the Reference Point.
5882 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5883 MakeGroups: forces the generation of new groups from existing ones
5884 ElemType: type of elements for extrusion (if param Base is a mesh)
5887 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5888 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5889 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5891 Example: :ref:`tui_extrusion_along_path`
5895 if ElemType == SMESH.NODE: n = Base
5896 if ElemType == SMESH.EDGE: e = Base
5897 if ElemType == SMESH.FACE: f = Base
5898 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5899 HasAngles, Angles, LinearVariation,
5900 HasRefPoint, RefPoint, MakeGroups)
5901 if MakeGroups: return gr,er
5904 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5905 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5906 MakeGroups=False, LinearVariation=False):
5908 Generate new elements by extrusion of the given elements.
5909 The path of extrusion must be a meshed edge.
5912 IDsOfElements: ids of elements
5913 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5914 PathShape: shape (edge) defines the sub-mesh for the path
5915 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5916 HasAngles: not used obsolete
5917 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5918 around *basePoint*, additionally to previous steps.
5919 HasRefPoint: allows using the reference point
5920 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5921 The User can specify any point as the Reference Point.
5922 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5923 MakeGroups: forces the generation of new groups from existing ones
5924 LinearVariation: forces the computation of rotation angles as linear
5925 variation of the given Angles along path steps
5928 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5929 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5930 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5931 Example: :ref:`tui_extrusion_along_path`
5934 if not IDsOfElements:
5935 IDsOfElements = [ self.GetMesh() ]
5936 n,e,f = [],IDsOfElements,IDsOfElements
5937 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5938 NodeStart, HasAngles, Angles,
5940 HasRefPoint, RefPoint, MakeGroups)
5941 if MakeGroups: return gr,er
5944 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5945 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5946 MakeGroups=False, LinearVariation=False):
5948 Generate new elements by extrusion of the elements which belong to the object.
5949 The path of extrusion must be a meshed edge.
5952 theObject: the object whose elements should be processed.
5953 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5954 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5955 PathShape: shape (edge) defines the sub-mesh for the path
5956 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5957 HasAngles: not used obsolete
5958 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5959 around *basePoint*, additionally to previous steps.
5960 HasRefPoint: allows using the reference point
5961 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5962 The User can specify any point as the Reference Point.
5963 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5964 MakeGroups: forces the generation of new groups from existing ones
5965 LinearVariation: forces the computation of rotation angles as linear
5966 variation of the given Angles along path steps
5969 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5970 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5971 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5972 Example: :ref:`tui_extrusion_along_path`
5975 n,e,f = [],theObject,theObject
5976 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5977 HasAngles, Angles, LinearVariation,
5978 HasRefPoint, RefPoint, MakeGroups)
5979 if MakeGroups: return gr,er
5982 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5983 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5984 MakeGroups=False, LinearVariation=False):
5986 Generate new elements by extrusion of mesh segments which belong to the object.
5987 The path of extrusion must be a meshed edge.
5990 theObject: the object whose 1D elements should be processed.
5991 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5992 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5993 PathShape: shape (edge) defines the sub-mesh for the path
5994 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5995 HasAngles: not used obsolete
5996 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5997 around *basePoint*, additionally to previous steps.
5998 HasRefPoint: allows using the reference point
5999 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6000 The User can specify any point as the Reference Point.
6001 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6002 MakeGroups: forces the generation of new groups from existing ones
6003 LinearVariation: forces the computation of rotation angles as linear
6004 variation of the given Angles along path steps
6007 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6008 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6009 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6010 Example: :ref:`tui_extrusion_along_path`
6013 n,e,f = [],theObject,[]
6014 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6015 HasAngles, Angles, LinearVariation,
6016 HasRefPoint, RefPoint, MakeGroups)
6017 if MakeGroups: return gr,er
6020 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6021 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6022 MakeGroups=False, LinearVariation=False):
6024 Generate new elements by extrusion of faces which belong to the object.
6025 The path of extrusion must be a meshed edge.
6028 theObject: the object whose 2D elements should be processed.
6029 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6030 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6031 PathShape: shape (edge) defines the sub-mesh for the path
6032 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6033 HasAngles: not used obsolete
6034 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6035 around *basePoint*, additionally to previous steps.
6036 HasRefPoint: allows using the reference point
6037 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6038 The User can specify any point as the Reference Point.
6039 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6040 MakeGroups: forces the generation of new groups from existing ones
6041 LinearVariation: forces the computation of rotation angles as linear
6042 variation of the given Angles along path steps
6045 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6046 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6047 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6048 Example: :ref:`tui_extrusion_along_path`
6051 n,e,f = [],[],theObject
6052 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6053 HasAngles, Angles, LinearVariation,
6054 HasRefPoint, RefPoint, MakeGroups)
6055 if MakeGroups: return gr,er
6058 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6060 Create a symmetrical copy of mesh elements
6063 IDsOfElements: list of elements ids
6064 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6065 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6066 If the *Mirror* is a geom object this parameter is unnecessary
6067 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6068 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6071 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6074 if IDsOfElements == []:
6075 IDsOfElements = self.GetElementsId()
6076 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6077 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6078 theMirrorType = Mirror._mirrorType
6080 self.mesh.SetParameters(Mirror.parameters)
6081 if Copy and MakeGroups:
6082 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6083 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6086 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6088 Create a new mesh by a symmetrical copy of mesh elements
6091 IDsOfElements: the list of elements ids
6092 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6093 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6094 If the *Mirror* is a geom object this parameter is unnecessary
6095 MakeGroups: to generate new groups from existing ones
6096 NewMeshName: a name of the new mesh to create
6099 instance of class :class:`Mesh`
6102 if IDsOfElements == []:
6103 IDsOfElements = self.GetElementsId()
6104 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6105 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6106 theMirrorType = Mirror._mirrorType
6108 self.mesh.SetParameters(Mirror.parameters)
6109 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6110 MakeGroups, NewMeshName)
6111 return Mesh(self.smeshpyD,self.geompyD,mesh)
6113 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6115 Create a symmetrical copy of the object
6118 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6119 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6120 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6121 If the *Mirror* is a geom object this parameter is unnecessary
6122 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6123 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6126 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6129 if ( isinstance( theObject, Mesh )):
6130 theObject = theObject.GetMesh()
6131 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6132 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6133 theMirrorType = Mirror._mirrorType
6135 self.mesh.SetParameters(Mirror.parameters)
6136 if Copy and MakeGroups:
6137 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6138 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6141 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6143 Create a new mesh by a symmetrical copy of the object
6146 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6147 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6148 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6149 If the *Mirror* is a geom object this parameter is unnecessary
6150 MakeGroups: forces the generation of new groups from existing ones
6151 NewMeshName: the name of the new mesh to create
6154 instance of class :class:`Mesh`
6157 if ( isinstance( theObject, Mesh )):
6158 theObject = theObject.GetMesh()
6159 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6160 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6161 theMirrorType = Mirror._mirrorType
6163 self.mesh.SetParameters(Mirror.parameters)
6164 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6165 MakeGroups, NewMeshName)
6166 return Mesh( self.smeshpyD,self.geompyD,mesh )
6168 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6170 Translate the elements
6173 IDsOfElements: list of elements ids
6174 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6175 Copy: allows copying the translated elements
6176 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6179 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6182 if IDsOfElements == []:
6183 IDsOfElements = self.GetElementsId()
6184 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6185 Vector = self.smeshpyD.GetDirStruct(Vector)
6186 if isinstance( Vector, list ):
6187 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6188 self.mesh.SetParameters(Vector.PS.parameters)
6189 if Copy and MakeGroups:
6190 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6191 self.editor.Translate(IDsOfElements, Vector, Copy)
6194 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6196 Create a new mesh of translated elements
6199 IDsOfElements: list of elements ids
6200 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6201 MakeGroups: forces the generation of new groups from existing ones
6202 NewMeshName: the name of the newly created mesh
6205 instance of class :class:`Mesh`
6208 if IDsOfElements == []:
6209 IDsOfElements = self.GetElementsId()
6210 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6211 Vector = self.smeshpyD.GetDirStruct(Vector)
6212 if isinstance( Vector, list ):
6213 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6214 self.mesh.SetParameters(Vector.PS.parameters)
6215 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6216 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6218 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6220 Translate the object
6223 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6224 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6225 Copy: allows copying the translated elements
6226 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6229 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6232 if ( isinstance( theObject, Mesh )):
6233 theObject = theObject.GetMesh()
6234 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6235 Vector = self.smeshpyD.GetDirStruct(Vector)
6236 if isinstance( Vector, list ):
6237 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6238 self.mesh.SetParameters(Vector.PS.parameters)
6239 if Copy and MakeGroups:
6240 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6241 self.editor.TranslateObject(theObject, Vector, Copy)
6244 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6246 Create a new mesh from the translated object
6249 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6250 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6251 MakeGroups: forces the generation of new groups from existing ones
6252 NewMeshName: the name of the newly created mesh
6255 instance of class :class:`Mesh`
6258 if isinstance( theObject, Mesh ):
6259 theObject = theObject.GetMesh()
6260 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6261 Vector = self.smeshpyD.GetDirStruct(Vector)
6262 if isinstance( Vector, list ):
6263 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6264 self.mesh.SetParameters(Vector.PS.parameters)
6265 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6266 return Mesh( self.smeshpyD, self.geompyD, mesh )
6270 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6275 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6276 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6277 theScaleFact: list of 1-3 scale factors for axises
6278 Copy: allows copying the translated elements
6279 MakeGroups: forces the generation of new groups from existing
6283 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6284 empty list otherwise
6286 unRegister = genObjUnRegister()
6287 if ( isinstance( theObject, Mesh )):
6288 theObject = theObject.GetMesh()
6289 if ( isinstance( theObject, list )):
6290 theObject = self.GetIDSource(theObject, SMESH.ALL)
6291 unRegister.set( theObject )
6292 if ( isinstance( thePoint, list )):
6293 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6294 if ( isinstance( theScaleFact, float )):
6295 theScaleFact = [theScaleFact]
6296 if ( isinstance( theScaleFact, int )):
6297 theScaleFact = [ float(theScaleFact)]
6299 self.mesh.SetParameters(thePoint.parameters)
6301 if Copy and MakeGroups:
6302 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6303 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6306 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6308 Create a new mesh from the translated object
6311 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6312 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6313 theScaleFact: list of 1-3 scale factors for axises
6314 MakeGroups: forces the generation of new groups from existing ones
6315 NewMeshName: the name of the newly created mesh
6318 instance of class :class:`Mesh`
6320 unRegister = genObjUnRegister()
6321 if (isinstance(theObject, Mesh)):
6322 theObject = theObject.GetMesh()
6323 if ( isinstance( theObject, list )):
6324 theObject = self.GetIDSource(theObject,SMESH.ALL)
6325 unRegister.set( theObject )
6326 if ( isinstance( thePoint, list )):
6327 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6328 if ( isinstance( theScaleFact, float )):
6329 theScaleFact = [theScaleFact]
6330 if ( isinstance( theScaleFact, int )):
6331 theScaleFact = [ float(theScaleFact)]
6333 self.mesh.SetParameters(thePoint.parameters)
6334 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6335 MakeGroups, NewMeshName)
6336 return Mesh( self.smeshpyD, self.geompyD, mesh )
6340 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6345 IDsOfElements: list of elements ids
6346 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6347 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6348 Copy: allows copying the rotated elements
6349 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6352 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6356 if IDsOfElements == []:
6357 IDsOfElements = self.GetElementsId()
6358 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6359 Axis = self.smeshpyD.GetAxisStruct(Axis)
6360 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6361 Parameters = Axis.parameters + var_separator + Parameters
6362 self.mesh.SetParameters(Parameters)
6363 if Copy and MakeGroups:
6364 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6365 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6368 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6370 Create a new mesh of rotated elements
6373 IDsOfElements: list of element ids
6374 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6375 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6376 MakeGroups: forces the generation of new groups from existing ones
6377 NewMeshName: the name of the newly created mesh
6380 instance of class :class:`Mesh`
6383 if IDsOfElements == []:
6384 IDsOfElements = self.GetElementsId()
6385 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6386 Axis = self.smeshpyD.GetAxisStruct(Axis)
6387 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6388 Parameters = Axis.parameters + var_separator + Parameters
6389 self.mesh.SetParameters(Parameters)
6390 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6391 MakeGroups, NewMeshName)
6392 return Mesh( self.smeshpyD, self.geompyD, mesh )
6394 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6399 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6400 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6401 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6402 Copy: allows copying the rotated elements
6403 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6406 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6409 if (isinstance(theObject, Mesh)):
6410 theObject = theObject.GetMesh()
6411 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6412 Axis = self.smeshpyD.GetAxisStruct(Axis)
6413 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6414 Parameters = Axis.parameters + ":" + Parameters
6415 self.mesh.SetParameters(Parameters)
6416 if Copy and MakeGroups:
6417 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6418 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6421 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6423 Create a new mesh from the rotated object
6426 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6427 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6428 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6429 MakeGroups: forces the generation of new groups from existing ones
6430 NewMeshName: the name of the newly created mesh
6433 instance of class :class:`Mesh`
6436 if (isinstance( theObject, Mesh )):
6437 theObject = theObject.GetMesh()
6438 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6439 Axis = self.smeshpyD.GetAxisStruct(Axis)
6440 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6441 Parameters = Axis.parameters + ":" + Parameters
6442 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6443 MakeGroups, NewMeshName)
6444 self.mesh.SetParameters(Parameters)
6445 return Mesh( self.smeshpyD, self.geompyD, mesh )
6447 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6449 Create an offset mesh from the given 2D object
6452 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6453 theValue (float): signed offset size
6454 MakeGroups (boolean): forces the generation of new groups from existing ones
6455 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6456 False means to remove original elements.
6457 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6460 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6463 if isinstance( theObject, Mesh ):
6464 theObject = theObject.GetMesh()
6465 theValue,Parameters,hasVars = ParseParameters(Value)
6466 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6467 self.mesh.SetParameters(Parameters)
6469 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6472 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6474 Find groups of adjacent nodes within Tolerance.
6477 Tolerance (float): the value of tolerance
6478 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6479 corner and medium nodes in separate groups thus preventing
6480 their further merge.
6483 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6486 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6488 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6489 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6491 Find groups of adjacent nodes within Tolerance.
6494 Tolerance: the value of tolerance
6495 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6496 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6497 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6498 corner and medium nodes in separate groups thus preventing
6499 their further merge.
6502 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6505 unRegister = genObjUnRegister()
6506 if not isinstance( SubMeshOrGroup, list ):
6507 SubMeshOrGroup = [ SubMeshOrGroup ]
6508 for i,obj in enumerate( SubMeshOrGroup ):
6509 if isinstance( obj, Mesh ):
6510 SubMeshOrGroup = [ obj.GetMesh() ]
6512 if isinstance( obj, int ):
6513 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6514 unRegister.set( SubMeshOrGroup )
6517 if not isinstance( exceptNodes, list ):
6518 exceptNodes = [ exceptNodes ]
6519 if exceptNodes and isinstance( exceptNodes[0], int ):
6520 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6521 unRegister.set( exceptNodes )
6523 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6524 exceptNodes, SeparateCornerAndMediumNodes)
6526 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6531 GroupsOfNodes: a list of groups of nodes IDs for merging.
6532 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6533 in all elements and mesh groups by nodes 1 and 25 correspondingly
6534 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6535 If *NodesToKeep* does not include a node to keep for some group to merge,
6536 then the first node in the group is kept.
6537 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6541 This operation can create gaps in numeration of nodes or elements.
6542 Call :meth:`RenumberElements` to remove the gaps.
6544 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6546 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6548 Find the elements built on the same nodes.
6551 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6552 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6556 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6559 unRegister = genObjUnRegister()
6560 if MeshOrSubMeshOrGroup is None:
6561 MeshOrSubMeshOrGroup = [ self.mesh ]
6562 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6563 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6564 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6565 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6566 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6567 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6568 unRegister.set( MeshOrSubMeshOrGroup )
6569 for item in MeshOrSubMeshOrGroup:
6570 if isinstance( item, Mesh ):
6571 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6573 if not isinstance( exceptElements, list ):
6574 exceptElements = [ exceptElements ]
6575 if exceptElements and isinstance( exceptElements[0], int ):
6576 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6577 unRegister.set( exceptElements )
6579 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6581 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6583 Merge elements in each given group.
6586 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6587 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6588 replaced in all mesh groups by elements 1 and 25)
6589 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6590 If *ElementsToKeep* does not include an element to keep for some group to merge,
6591 then the first element in the group is kept.
6594 This operation can create gaps in numeration of elements.
6595 Call :meth:`RenumberElements` to remove the gaps.
6598 unRegister = genObjUnRegister()
6600 if not isinstance( ElementsToKeep, list ):
6601 ElementsToKeep = [ ElementsToKeep ]
6602 if isinstance( ElementsToKeep[0], int ):
6603 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6604 unRegister.set( ElementsToKeep )
6606 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6608 def MergeEqualElements(self):
6610 Leave one element and remove all other elements built on the same nodes.
6613 This operation can create gaps in numeration of elements.
6614 Call :meth:`RenumberElements` to remove the gaps.
6617 self.editor.MergeEqualElements()
6619 def FindFreeBorders(self, ClosedOnly=True):
6621 Returns all or only closed free borders
6624 list of SMESH.FreeBorder's
6627 return self.editor.FindFreeBorders( ClosedOnly )
6629 def FillHole(self, holeNodes, groupName=""):
6631 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6634 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6635 must describe all sequential nodes of the hole border. The first and the last
6636 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6637 groupName (string): name of a group to add new faces
6639 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6643 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6644 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6645 if not isinstance( holeNodes, SMESH.FreeBorder ):
6646 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6647 return self.editor.FillHole( holeNodes, groupName )
6649 def FindCoincidentFreeBorders (self, tolerance=0.):
6651 Return groups of FreeBorder's coincident within the given tolerance.
6654 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6655 size of elements adjacent to free borders being compared is used.
6658 SMESH.CoincidentFreeBorders structure
6661 return self.editor.FindCoincidentFreeBorders( tolerance )
6663 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6665 Sew FreeBorder's of each group
6668 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6669 where each enclosed list contains node IDs of a group of coincident free
6670 borders such that each consequent triple of IDs within a group describes
6671 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6672 last node of a border.
6673 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6674 groups of coincident free borders, each group including two borders.
6675 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6676 polygons if a node of opposite border falls on a face edge, else such
6677 faces are split into several ones.
6678 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6679 polyhedra if a node of opposite border falls on a volume edge, else such
6680 volumes, if any, remain intact and the mesh becomes non-conformal.
6683 a number of successfully sewed groups
6686 This operation can create gaps in numeration of nodes or elements.
6687 Call :meth:`RenumberElements` to remove the gaps.
6690 if freeBorders and isinstance( freeBorders, list ):
6691 # construct SMESH.CoincidentFreeBorders
6692 if isinstance( freeBorders[0], int ):
6693 freeBorders = [freeBorders]
6695 coincidentGroups = []
6696 for nodeList in freeBorders:
6697 if not nodeList or len( nodeList ) % 3:
6698 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6701 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6702 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6703 nodeList = nodeList[3:]
6705 coincidentGroups.append( group )
6707 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6709 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6711 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6712 FirstNodeID2, SecondNodeID2, LastNodeID2,
6713 CreatePolygons, CreatePolyedrs):
6718 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6721 This operation can create gaps in numeration of nodes or elements.
6722 Call :meth:`RenumberElements` to remove the gaps.
6725 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6726 FirstNodeID2, SecondNodeID2, LastNodeID2,
6727 CreatePolygons, CreatePolyedrs)
6729 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6730 FirstNodeID2, SecondNodeID2):
6732 Sew conform free borders
6735 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6738 This operation can create gaps in numeration of elements.
6739 Call :meth:`RenumberElements` to remove the gaps.
6742 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6743 FirstNodeID2, SecondNodeID2)
6745 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6746 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6751 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6754 This operation can create gaps in numeration of elements.
6755 Call :meth:`RenumberElements` to remove the gaps.
6758 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6759 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6761 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6762 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6763 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6765 Sew two sides of a mesh. The nodes belonging to Side1 are
6766 merged with the nodes of elements of Side2.
6767 The number of elements in theSide1 and in theSide2 must be
6768 equal and they should have similar nodal connectivity.
6769 The nodes to merge should belong to side borders and
6770 the first node should be linked to the second.
6773 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6776 This operation can create gaps in numeration of nodes.
6777 Call :meth:`RenumberElements` to remove the gaps.
6780 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6781 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6782 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6784 def ChangeElemNodes(self, ide, newIDs):
6786 Set new nodes for the given element. Number of nodes should be kept.
6793 False if the number of nodes does not correspond to the type of element
6796 return self.editor.ChangeElemNodes(ide, newIDs)
6798 def GetLastCreatedNodes(self):
6800 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6801 created, this method return the list of their IDs.
6802 If new nodes were not created - return empty list
6805 the list of integer values (can be empty)
6808 return self.editor.GetLastCreatedNodes()
6810 def GetLastCreatedElems(self):
6812 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6813 created this method return the list of their IDs.
6814 If new elements were not created - return empty list
6817 the list of integer values (can be empty)
6820 return self.editor.GetLastCreatedElems()
6822 def ClearLastCreated(self):
6824 Forget what nodes and elements were created by the last mesh edition operation
6827 self.editor.ClearLastCreated()
6829 def DoubleElements(self, theElements, theGroupName=""):
6831 Create duplicates of given elements, i.e. create new elements based on the
6832 same nodes as the given ones.
6835 theElements: container of elements to duplicate. It can be a
6836 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6837 or a list of element IDs. If *theElements* is
6838 a :class:`Mesh`, elements of highest dimension are duplicated
6839 theGroupName: a name of group to contain the generated elements.
6840 If a group with such a name already exists, the new elements
6841 are added to the existing group, else a new group is created.
6842 If *theGroupName* is empty, new elements are not added
6846 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6847 None if *theGroupName* == "".
6850 unRegister = genObjUnRegister()
6851 if isinstance( theElements, Mesh ):
6852 theElements = theElements.mesh
6853 elif isinstance( theElements, list ):
6854 theElements = self.GetIDSource( theElements, SMESH.ALL )
6855 unRegister.set( theElements )
6856 return self.editor.DoubleElements(theElements, theGroupName)
6858 def DoubleNodes(self, theNodes, theModifiedElems):
6860 Create a hole in a mesh by doubling the nodes of some particular elements
6863 theNodes: IDs of nodes to be doubled
6864 theModifiedElems: IDs of elements to be updated by the new (doubled)
6865 nodes. If list of element identifiers is empty then nodes are doubled but
6866 they not assigned to elements
6869 True if operation has been completed successfully, False otherwise
6872 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6874 def DoubleNode(self, theNodeId, theModifiedElems):
6876 Create a hole in a mesh by doubling the nodes of some particular elements.
6877 This method provided for convenience works as :meth:`DoubleNodes`.
6880 theNodeId: IDs of node to double
6881 theModifiedElems: IDs of elements to update
6884 True if operation has been completed successfully, False otherwise
6887 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6889 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
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 theNodes: group of nodes to double.
6896 theModifiedElems: group of elements to update.
6897 theMakeGroup: forces the generation of a group containing new nodes.
6900 True or a created group if operation has been completed successfully,
6901 False or None otherwise
6905 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6906 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6908 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6910 Create a hole in a mesh by doubling the nodes of some particular elements.
6911 This method provided for convenience works as :meth:`DoubleNodes`.
6914 theNodes: list of groups of nodes to double.
6915 theModifiedElems: list of groups of elements to update.
6916 theMakeGroup: forces the generation of a group containing new nodes.
6919 True if operation has been completed successfully, False otherwise
6923 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6924 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6926 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6928 Create a hole in a mesh by doubling the nodes of some particular elements
6931 theElems: the list of elements (edges or faces) to replicate.
6932 The nodes for duplication could be found from these elements
6933 theNodesNot: list of nodes NOT to replicate
6934 theAffectedElems: the list of elements (cells and edges) to which the
6935 replicated nodes should be associated to
6938 True if operation has been completed successfully, False otherwise
6941 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6943 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6945 Create a hole in a mesh by doubling the nodes of some particular elements
6948 theElems: the list of elements (edges or faces) to replicate.
6949 The nodes for duplication could be found from these elements
6950 theNodesNot: list of nodes NOT to replicate
6951 theShape: shape to detect affected elements (element which geometric center
6952 located on or inside shape).
6953 The replicated nodes should be associated to affected elements.
6956 True if operation has been completed successfully, False otherwise
6959 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6961 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6962 theMakeGroup=False, theMakeNodeGroup=False):
6964 Create a hole in a mesh by doubling the nodes of some particular elements.
6965 This method provided for convenience works as :meth:`DoubleNodes`.
6968 theElems: group of of elements (edges or faces) to replicate.
6969 theNodesNot: group of nodes NOT to replicate.
6970 theAffectedElems: group of elements to which the replicated nodes
6971 should be associated to.
6972 theMakeGroup: forces the generation of a group containing new elements.
6973 theMakeNodeGroup: forces the generation of a group containing new nodes.
6976 True or created groups (one or two) if operation has been completed successfully,
6977 False or None otherwise
6980 if theMakeGroup or theMakeNodeGroup:
6981 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6983 theMakeGroup, theMakeNodeGroup)
6984 if theMakeGroup and theMakeNodeGroup:
6987 return twoGroups[ int(theMakeNodeGroup) ]
6988 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6990 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6992 Create a hole in a mesh by doubling the nodes of some particular elements.
6993 This method provided for convenience works as :meth:`DoubleNodes`.
6996 theElems: group of of elements (edges or faces) to replicate
6997 theNodesNot: group of nodes not to replicate
6998 theShape: shape to detect affected elements (element which geometric center
6999 located on or inside shape).
7000 The replicated nodes should be associated to affected elements
7003 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7005 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7006 theMakeGroup=False, theMakeNodeGroup=False):
7008 Create a hole in a mesh by doubling the nodes of some particular elements.
7009 This method provided for convenience works as :meth:`DoubleNodes`.
7012 theElems: list of groups of elements (edges or faces) to replicate
7013 theNodesNot: list of groups of nodes NOT to replicate
7014 theAffectedElems: group of elements to which the replicated nodes
7015 should be associated to
7016 theMakeGroup: forces generation of a group containing new elements.
7017 theMakeNodeGroup: forces generation of a group containing new nodes
7020 True or created groups (one or two) if operation has been completed successfully,
7021 False or None otherwise
7024 if theMakeGroup or theMakeNodeGroup:
7025 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7027 theMakeGroup, theMakeNodeGroup)
7028 if theMakeGroup and theMakeNodeGroup:
7031 return twoGroups[ int(theMakeNodeGroup) ]
7032 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7034 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7036 Create a hole in a mesh by doubling the nodes of some particular elements.
7037 This method provided for convenience works as :meth:`DoubleNodes`.
7040 theElems: list of groups of elements (edges or faces) to replicate
7041 theNodesNot: list of groups of nodes NOT to replicate
7042 theShape: shape to detect affected elements (element which geometric center
7043 located on or inside shape).
7044 The replicated nodes should be associated to affected elements
7047 True if operation has been completed successfully, False otherwise
7050 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7052 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7054 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7055 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7058 theElems: list of groups of nodes or elements (edges or faces) to replicate
7059 theNodesNot: list of groups of nodes NOT to replicate
7060 theShape: shape to detect affected elements (element which geometric center
7061 located on or inside shape).
7062 The replicated nodes should be associated to affected elements
7065 groups of affected elements in order: volumes, faces, edges
7068 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7070 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7073 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7074 The list of groups must describe a partition of the mesh volumes.
7075 The nodes of the internal faces at the boundaries of the groups are doubled.
7076 In option, the internal faces are replaced by flat elements.
7077 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7080 theDomains: list of groups of volumes
7081 createJointElems: if True, create the elements
7082 onAllBoundaries: if True, the nodes and elements are also created on
7083 the boundary between *theDomains* and the rest mesh
7086 True if operation has been completed successfully, False otherwise
7089 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7091 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7093 Double nodes on some external faces and create flat elements.
7094 Flat elements are mainly used by some types of mechanic calculations.
7096 Each group of the list must be constituted of faces.
7097 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7100 theGroupsOfFaces: list of groups of faces
7103 True if operation has been completed successfully, False otherwise
7106 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7108 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7110 Identify all the elements around a geom shape, get the faces delimiting the hole
7112 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7114 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7116 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7117 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7118 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7119 If there are several paths connecting a pair of points, the shortest path is
7120 selected by the module. Position of the cutting plane is defined by the two
7121 points and an optional vector lying on the plane specified by a PolySegment.
7122 By default the vector is defined by Mesh module as following. A middle point
7123 of the two given points is computed. The middle point is projected to the mesh.
7124 The vector goes from the middle point to the projection point. In case of planar
7125 mesh, the vector is normal to the mesh.
7127 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7130 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7131 groupName: optional name of a group where created mesh segments will be added.
7134 editor = self.editor
7136 editor = self.mesh.GetMeshEditPreviewer()
7137 segmentsRes = editor.MakePolyLine( segments, groupName )
7138 for i, seg in enumerate( segmentsRes ):
7139 segments[i].vector = seg.vector
7141 return editor.GetPreviewData()
7144 def MakeSlot(self, segmentGroup, width ):
7146 Create a slot of given width around given 1D elements lying on a triangle mesh.
7147 The slot is constructed by cutting faces by cylindrical surfaces made
7148 around each segment. Segments are expected to be created by MakePolyLine().
7151 FaceEdge's located at the slot boundary
7153 return self.editor.MakeSlot( segmentGroup, width )
7155 def GetFunctor(self, funcType ):
7157 Return a cached numerical functor by its type.
7160 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7161 Note that not all items correspond to numerical functors.
7164 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7167 fn = self.functors[ funcType._v ]
7169 fn = self.smeshpyD.GetFunctor(funcType)
7170 fn.SetMesh(self.mesh)
7171 self.functors[ funcType._v ] = fn
7174 def FunctorValue(self, funcType, elemId, isElem=True):
7176 Return value of a functor for a given element
7179 funcType: an item of :class:`SMESH.FunctorType` enum.
7180 elemId: element or node ID
7181 isElem: *elemId* is ID of element or node
7184 the functor value or zero in case of invalid arguments
7187 fn = self.GetFunctor( funcType )
7188 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7189 val = fn.GetValue(elemId)
7194 def GetLength(self, elemId=None):
7196 Get length of given 1D elements or of all 1D mesh elements
7199 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.
7202 Sum of lengths of given elements
7207 length = self.smeshpyD.GetLength(self)
7208 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7209 length = self.smeshpyD.GetLength(elemId)
7212 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7214 length += self.smeshpyD.GetLength(obj)
7215 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7216 unRegister = genObjUnRegister()
7217 obj = self.GetIDSource( elemId )
7218 unRegister.set( obj )
7219 length = self.smeshpyD.GetLength( obj )
7221 length = self.FunctorValue(SMESH.FT_Length, elemId)
7224 def GetArea(self, elemId=None):
7226 Get area of given 2D elements or of all 2D mesh elements
7229 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.
7232 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7237 area = self.smeshpyD.GetArea(self)
7238 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7239 area = self.smeshpyD.GetArea(elemId)
7242 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7244 area += self.smeshpyD.GetArea(obj)
7245 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7246 unRegister = genObjUnRegister()
7247 obj = self.GetIDSource( elemId )
7248 unRegister.set( obj )
7249 area = self.smeshpyD.GetArea( obj )
7251 area = self.FunctorValue(SMESH.FT_Area, elemId)
7254 def GetVolume(self, elemId=None):
7256 Get volume of given 3D elements or of all 3D mesh elements
7259 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.
7262 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7267 volume= self.smeshpyD.GetVolume(self)
7268 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7269 volume= self.smeshpyD.GetVolume(elemId)
7272 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7274 volume+= self.smeshpyD.GetVolume(obj)
7275 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7276 unRegister = genObjUnRegister()
7277 obj = self.GetIDSource( elemId )
7278 unRegister.set( obj )
7279 volume= self.smeshpyD.GetVolume( obj )
7281 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7284 def GetAngle(self, node1, node2, node3 ):
7286 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7289 node1,node2,node3: IDs of the three nodes
7292 Angle in radians [0,PI]. -1 if failure case.
7294 p1 = self.GetNodeXYZ( node1 )
7295 p2 = self.GetNodeXYZ( node2 )
7296 p3 = self.GetNodeXYZ( node3 )
7297 if p1 and p2 and p3:
7298 return self.smeshpyD.GetAngle( p1,p2,p3 )
7302 def GetMaxElementLength(self, elemId):
7304 Get maximum element length.
7307 elemId: mesh element ID
7310 element's maximum length value
7313 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7314 ftype = SMESH.FT_MaxElementLength3D
7316 ftype = SMESH.FT_MaxElementLength2D
7317 return self.FunctorValue(ftype, elemId)
7319 def GetAspectRatio(self, elemId):
7321 Get aspect ratio of 2D or 3D element.
7324 elemId: mesh element ID
7327 element's aspect ratio value
7330 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7331 ftype = SMESH.FT_AspectRatio3D
7333 ftype = SMESH.FT_AspectRatio
7334 return self.FunctorValue(ftype, elemId)
7336 def GetWarping(self, elemId):
7338 Get warping angle of 2D element.
7341 elemId: mesh element ID
7344 element's warping angle value
7347 return self.FunctorValue(SMESH.FT_Warping, elemId)
7349 def GetMinimumAngle(self, elemId):
7351 Get minimum angle of 2D element.
7354 elemId: mesh element ID
7357 element's minimum angle value
7360 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7362 def GetTaper(self, elemId):
7364 Get taper of 2D element.
7367 elemId: mesh element ID
7370 element's taper value
7373 return self.FunctorValue(SMESH.FT_Taper, elemId)
7375 def GetSkew(self, elemId):
7377 Get skew of 2D element.
7380 elemId: mesh element ID
7383 element's skew value
7386 return self.FunctorValue(SMESH.FT_Skew, elemId)
7388 def GetMinMax(self, funType, meshPart=None):
7390 Return minimal and maximal value of a given functor.
7393 funType (SMESH.FunctorType): a functor type.
7394 Note that not all items of :class:`SMESH.FunctorType` corresponds
7395 to numerical functors.
7396 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7402 unRegister = genObjUnRegister()
7403 if isinstance( meshPart, list ):
7404 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7405 unRegister.set( meshPart )
7406 if isinstance( meshPart, Mesh ):
7407 meshPart = meshPart.mesh
7408 fun = self.GetFunctor( funType )
7411 if hasattr( meshPart, "SetMesh" ):
7412 meshPart.SetMesh( self.mesh ) # set mesh to filter
7413 hist = fun.GetLocalHistogram( 1, False, meshPart )
7415 hist = fun.GetHistogram( 1, False )
7417 return hist[0].min, hist[0].max
7420 pass # end of Mesh class
7423 class meshProxy(SMESH._objref_SMESH_Mesh):
7425 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7426 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7428 def __init__(self,*args):
7429 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7430 def __deepcopy__(self, memo=None):
7431 new = self.__class__(self)
7433 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7434 if len( args ) == 3:
7435 args += SMESH.ALL_NODES, True
7436 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7437 def ExportToMEDX(self, *args): # function removed
7438 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7439 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7440 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7441 def ExportToMED(self, *args): # function removed
7442 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7443 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7445 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7447 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7448 def ExportPartToMED(self, *args): # 'version' parameter removed
7449 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7450 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7451 def ExportMED(self, *args): # signature of method changed
7452 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7454 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7456 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7458 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7461 class submeshProxy(SMESH._objref_SMESH_subMesh):
7464 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7466 def __init__(self,*args):
7467 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7469 def __deepcopy__(self, memo=None):
7470 new = self.__class__(self)
7473 def Compute(self,refresh=False):
7475 Compute the sub-mesh and return the status of the computation
7478 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7483 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7484 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7488 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7490 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7492 if salome.sg.hasDesktop():
7493 if refresh: salome.sg.updateObjBrowser()
7498 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7501 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7503 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7504 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7507 def __init__(self,*args):
7508 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7510 def __getattr__(self, name ): # method called if an attribute not found
7511 if not self.mesh: # look for name() method in Mesh class
7512 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7513 if hasattr( self.mesh, name ):
7514 return getattr( self.mesh, name )
7515 if name == "ExtrusionAlongPathObjX":
7516 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7517 print("meshEditor: attribute '%s' NOT FOUND" % name)
7519 def __deepcopy__(self, memo=None):
7520 new = self.__class__(self)
7522 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7523 if len( args ) == 1: args += False,
7524 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7525 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7526 if len( args ) == 2: args += False,
7527 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7528 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7529 if len( args ) == 1:
7530 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7531 NodesToKeep = args[1]
7532 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7533 unRegister = genObjUnRegister()
7535 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7536 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7537 if not isinstance( NodesToKeep, list ):
7538 NodesToKeep = [ NodesToKeep ]
7539 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7541 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7543 class Pattern(SMESH._objref_SMESH_Pattern):
7545 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7546 variables in some methods
7549 def LoadFromFile(self, patternTextOrFile ):
7550 text = patternTextOrFile
7551 if os.path.exists( text ):
7552 text = open( patternTextOrFile ).read()
7554 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7556 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7557 decrFun = lambda i: i-1
7558 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7559 theMesh.SetParameters(Parameters)
7560 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7562 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7563 decrFun = lambda i: i-1
7564 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7565 theMesh.SetParameters(Parameters)
7566 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7568 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7569 if isinstance( mesh, Mesh ):
7570 mesh = mesh.GetMesh()
7571 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7573 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7575 Registering the new proxy for Pattern
7580 Private class used to bind methods creating algorithms to the class Mesh
7583 def __init__(self, method):
7585 self.defaultAlgoType = ""
7586 self.algoTypeToClass = {}
7587 self.method = method
7589 def add(self, algoClass):
7591 Store a python class of algorithm
7593 if inspect.isclass(algoClass) and \
7594 hasattr( algoClass, "algoType"):
7595 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7596 if not self.defaultAlgoType and \
7597 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7598 self.defaultAlgoType = algoClass.algoType
7599 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7601 def copy(self, mesh):
7603 Create a copy of self and assign mesh to the copy
7606 other = algoCreator( self.method )
7607 other.defaultAlgoType = self.defaultAlgoType
7608 other.algoTypeToClass = self.algoTypeToClass
7612 def __call__(self,algo="",geom=0,*args):
7614 Create an instance of algorithm
7618 if isinstance( algo, str ):
7620 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7621 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7626 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7628 elif not algoType and isinstance( geom, str ):
7633 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7635 elif isinstance( arg, str ) and not algoType:
7638 import traceback, sys
7639 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7640 sys.stderr.write( msg + '\n' )
7641 tb = traceback.extract_stack(None,2)
7642 traceback.print_list( [tb[0]] )
7644 algoType = self.defaultAlgoType
7645 if not algoType and self.algoTypeToClass:
7646 algoType = sorted( self.algoTypeToClass.keys() )[0]
7647 if algoType in self.algoTypeToClass:
7648 #print("Create algo",algoType)
7649 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7650 raise RuntimeError( "No class found for algo type %s" % algoType)
7653 class hypMethodWrapper:
7655 Private class used to substitute and store variable parameters of hypotheses.
7658 def __init__(self, hyp, method):
7660 self.method = method
7661 #print("REBIND:", method.__name__)
7664 def __call__(self,*args):
7666 call a method of hypothesis with calling SetVarParameter() before
7670 return self.method( self.hyp, *args ) # hypothesis method with no args
7672 #print("MethWrapper.__call__", self.method.__name__, args)
7674 parsed = ParseParameters(*args) # replace variables with their values
7675 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7676 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7677 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7678 # maybe there is a replaced string arg which is not variable
7679 result = self.method( self.hyp, *args )
7680 except ValueError as detail: # raised by ParseParameters()
7682 result = self.method( self.hyp, *args )
7683 except omniORB.CORBA.BAD_PARAM:
7684 raise ValueError(detail) # wrong variable name
7689 class genObjUnRegister:
7691 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7694 def __init__(self, genObj=None):
7695 self.genObjList = []
7699 def set(self, genObj):
7700 "Store one or a list of of SALOME.GenericObj'es"
7701 if isinstance( genObj, list ):
7702 self.genObjList.extend( genObj )
7704 self.genObjList.append( genObj )
7708 for genObj in self.genObjList:
7709 if genObj and hasattr( genObj, "UnRegister" ):
7712 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7714 Bind methods creating mesher plug-ins to the Mesh class
7717 # print("pluginName: ", pluginName)
7718 pluginBuilderName = pluginName + "Builder"
7720 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7721 except Exception as e:
7722 from salome_utils import verbose
7723 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7725 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7726 plugin = eval( pluginBuilderName )
7727 # print(" plugin:" , str(plugin))
7729 # add methods creating algorithms to Mesh
7730 for k in dir( plugin ):
7731 if k[0] == '_': continue
7732 algo = getattr( plugin, k )
7733 #print(" algo:", str(algo))
7734 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7735 #print(" meshMethod:" , str(algo.meshMethod))
7736 if not hasattr( Mesh, algo.meshMethod ):
7737 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7739 _mmethod = getattr( Mesh, algo.meshMethod )
7740 if hasattr( _mmethod, "add" ):