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 return self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension, fields, geomAssocFields, z_tolerance)
2360 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2362 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2363 return medcoupling.MEDFileMesh.New(dab)
2365 def ExportMED(self, *args, **kwargs):
2367 Export the mesh in a file in MED format
2368 allowing to overwrite the file if it exists or add the exported data to its contents
2371 fileName: is the file name
2372 auto_groups (boolean): parameter for creating/not creating
2373 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2374 the typical use is auto_groups=False.
2375 version (int): define the version (xy, where version is x.y.z) of MED file format.
2376 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2377 The rules of compatibility to write a mesh in an older version than
2378 the current version depend on the current version. For instance,
2379 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2380 or 3.2.1 or 3.3.1 formats.
2381 If the version is equal to -1, the version is not changed (default).
2382 overwrite (boolean): parameter for overwriting/not overwriting the file
2383 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2384 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2386 - 1D if all mesh nodes lie on OX coordinate axis, or
2387 - 2D if all mesh nodes lie on XOY coordinate plane, or
2388 - 3D in the rest cases.
2390 If *autoDimension* is *False*, the space dimension is always 3.
2391 fields: list of GEOM fields defined on the shape to mesh.
2392 geomAssocFields: each character of this string means a need to export a
2393 corresponding field; correspondence between fields and characters
2396 - 'v' stands for "_vertices_" field;
2397 - 'e' stands for "_edges_" field;
2398 - 'f' stands for "_faces_" field;
2399 - 's' stands for "_solids_" field.
2401 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2402 close to zero within a given tolerance, the coordinate is set to zero.
2403 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2405 # process positional arguments
2406 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2408 auto_groups = args[1] if len(args) > 1 else False
2409 version = args[2] if len(args) > 2 else -1
2410 overwrite = args[3] if len(args) > 3 else True
2411 meshPart = args[4] if len(args) > 4 else None
2412 autoDimension = args[5] if len(args) > 5 else True
2413 fields = args[6] if len(args) > 6 else []
2414 geomAssocFields = args[7] if len(args) > 7 else ''
2415 z_tolerance = args[8] if len(args) > 8 else -1.
2416 # process keywords arguments
2417 auto_groups = kwargs.get("auto_groups", auto_groups)
2418 version = kwargs.get("version", version)
2419 version = kwargs.get("minor", version)
2420 overwrite = kwargs.get("overwrite", overwrite)
2421 meshPart = kwargs.get("meshPart", meshPart)
2422 autoDimension = kwargs.get("autoDimension", autoDimension)
2423 fields = kwargs.get("fields", fields)
2424 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2425 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2427 # invoke engine's function
2428 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2429 unRegister = genObjUnRegister()
2430 if isinstance( meshPart, list ):
2431 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2432 unRegister.set( meshPart )
2434 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2435 self.mesh.SetParameters(Parameters)
2437 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2438 version, overwrite, autoDimension,
2439 fields, geomAssocFields, z_tolerance)
2441 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2443 def ExportSAUV(self, f, auto_groups=0):
2445 Export the mesh in a file in SAUV format
2450 auto_groups: boolean parameter for creating/not creating
2451 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2452 the typical use is auto_groups=False.
2455 self.mesh.ExportSAUV(f, auto_groups)
2457 def ExportDAT(self, f, meshPart=None):
2459 Export the mesh in a file in DAT format
2463 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2467 unRegister = genObjUnRegister()
2468 if isinstance( meshPart, list ):
2469 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2470 unRegister.set( meshPart )
2471 self.mesh.ExportPartToDAT( meshPart, f )
2473 self.mesh.ExportDAT(f)
2475 def ExportUNV(self, f, meshPart=None):
2477 Export the mesh in a file in UNV format
2481 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2485 unRegister = genObjUnRegister()
2486 if isinstance( meshPart, list ):
2487 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2488 unRegister.set( meshPart )
2489 self.mesh.ExportPartToUNV( meshPart, f )
2491 self.mesh.ExportUNV(f)
2493 def ExportSTL(self, f, ascii=1, meshPart=None):
2495 Export the mesh in a file in STL format
2499 ascii: defines the file encoding
2500 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2504 unRegister = genObjUnRegister()
2505 if isinstance( meshPart, list ):
2506 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2507 unRegister.set( meshPart )
2508 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2510 self.mesh.ExportSTL(f, ascii)
2512 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2514 Export the mesh in a file in CGNS format
2518 overwrite: boolean parameter for overwriting/not overwriting the file
2519 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2520 groupElemsByType: if True all elements of same entity type are exported at ones,
2521 else elements are exported in order of their IDs which can cause creation
2522 of multiple cgns sections
2525 unRegister = genObjUnRegister()
2526 if isinstance( meshPart, list ):
2527 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2528 unRegister.set( meshPart )
2529 if isinstance( meshPart, Mesh ):
2530 meshPart = meshPart.mesh
2532 meshPart = self.mesh
2533 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2535 def ExportGMF(self, f, meshPart=None):
2537 Export the mesh in a file in GMF format.
2538 GMF files must have .mesh extension for the ASCII format and .meshb for
2539 the bynary format. Other extensions are not allowed.
2543 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2546 unRegister = genObjUnRegister()
2547 if isinstance( meshPart, list ):
2548 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2549 unRegister.set( meshPart )
2550 if isinstance( meshPart, Mesh ):
2551 meshPart = meshPart.mesh
2553 meshPart = self.mesh
2554 self.mesh.ExportGMF(meshPart, f, True)
2556 def ExportToMED(self, *args, **kwargs):
2558 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2559 Export the mesh in a file in MED format
2560 allowing to overwrite the file if it exists or add the exported data to its contents
2563 fileName: the file name
2564 opt (boolean): parameter for creating/not creating
2565 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2566 overwrite: boolean parameter for overwriting/not overwriting the file
2567 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2569 - 1D if all mesh nodes lie on OX coordinate axis, or
2570 - 2D if all mesh nodes lie on XOY coordinate plane, or
2571 - 3D in the rest cases.
2573 If **autoDimension** is *False*, the space dimension is always 3.
2576 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2577 # process positional arguments
2578 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2580 auto_groups = args[1] if len(args) > 1 else False
2581 overwrite = args[2] if len(args) > 2 else True
2582 autoDimension = args[3] if len(args) > 3 else True
2583 # process keywords arguments
2584 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2585 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2586 overwrite = kwargs.get("overwrite", overwrite)
2587 autoDimension = kwargs.get("autoDimension", autoDimension)
2589 # invoke engine's function
2590 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2592 def ExportToMEDX(self, *args, **kwargs):
2594 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2595 Export the mesh in a file in MED format
2598 fileName: the file name
2599 opt (boolean): parameter for creating/not creating
2600 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2601 overwrite: boolean parameter for overwriting/not overwriting the file
2602 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2604 - 1D if all mesh nodes lie on OX coordinate axis, or
2605 - 2D if all mesh nodes lie on XOY coordinate plane, or
2606 - 3D in the rest cases.
2608 If **autoDimension** is *False*, the space dimension is always 3.
2611 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2612 # process positional arguments
2613 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2615 auto_groups = args[1] if len(args) > 1 else False
2616 overwrite = args[2] if len(args) > 2 else True
2617 autoDimension = args[3] if len(args) > 3 else True
2618 # process keywords arguments
2619 auto_groups = kwargs.get("auto_groups", auto_groups)
2620 overwrite = kwargs.get("overwrite", overwrite)
2621 autoDimension = kwargs.get("autoDimension", autoDimension)
2623 # invoke engine's function
2624 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2628 def Append(self, meshes, uniteIdenticalGroups = True,
2629 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2631 Append given meshes into this mesh.
2632 All groups of input meshes will be created in this mesh.
2635 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2636 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2637 mergeNodesAndElements: if True, equal nodes and elements are merged
2638 mergeTolerance: tolerance for merging nodes
2639 allGroups: forces creation of groups corresponding to every input mesh
2641 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2642 mergeNodesAndElements, mergeTolerance, allGroups,
2643 meshToAppendTo = self.GetMesh() )
2645 # Operations with groups:
2646 # ----------------------
2647 def CreateEmptyGroup(self, elementType, name):
2649 Create an empty standalone mesh group
2652 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2653 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2654 name: the name of the mesh group
2657 :class:`SMESH.SMESH_Group`
2660 return self.mesh.CreateGroup(elementType, name)
2662 def Group(self, grp, name=""):
2664 Create a mesh group based on the geometric object *grp*
2665 and give it a *name*.
2666 If *name* is not defined the name of the geometric group is used
2669 Works like :meth:`GroupOnGeom`.
2672 grp: a geometric group, a vertex, an edge, a face or a solid
2673 name: the name of the mesh group
2676 :class:`SMESH.SMESH_GroupOnGeom`
2679 return self.GroupOnGeom(grp, name)
2681 def GroupOnGeom(self, grp, name="", typ=None):
2683 Create a mesh group based on the geometrical object *grp*
2684 and give it a *name*.
2685 if *name* is not defined the name of the geometric group is used
2688 grp: a geometrical group, a vertex, an edge, a face or a solid
2689 name: the name of the mesh group
2690 typ: the type of elements in the group; either of
2691 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2692 automatically detected by the type of the geometry
2695 :class:`SMESH.SMESH_GroupOnGeom`
2698 AssureGeomPublished( self, grp, name )
2700 name = grp.GetName()
2702 typ = self._groupTypeFromShape( grp )
2703 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2705 def _groupTypeFromShape( self, shape ):
2707 Pivate method to get a type of group on geometry
2709 tgeo = str(shape.GetShapeType())
2710 if tgeo == "VERTEX":
2712 elif tgeo == "EDGE" or tgeo == "WIRE":
2714 elif tgeo == "FACE" or tgeo == "SHELL":
2716 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2718 elif tgeo == "COMPOUND":
2720 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2722 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2723 # simplification of access in geomBuilder: omniORB.registerObjref
2724 from SHAPERSTUDY_utils import getEngine
2727 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2729 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2730 return self._groupTypeFromShape( sub[0] )
2732 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2735 def GroupOnFilter(self, typ, name, filter):
2737 Create a mesh group with given *name* based on the *filter*.
2738 It is a special type of group dynamically updating it's contents during
2742 typ: the type of elements in the group; either of
2743 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2744 name: the name of the mesh group
2745 filter (SMESH.Filter): the filter defining group contents
2748 :class:`SMESH.SMESH_GroupOnFilter`
2751 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2753 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2755 Create a mesh group by the given ids of elements
2758 groupName: the name of the mesh group
2759 elementType: the type of elements in the group; either of
2760 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2761 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2764 :class:`SMESH.SMESH_Group`
2767 group = self.mesh.CreateGroup(elementType, groupName)
2768 if isinstance( elemIDs, Mesh ):
2769 elemIDs = elemIDs.GetMesh()
2770 if hasattr( elemIDs, "GetIDs" ):
2771 if hasattr( elemIDs, "SetMesh" ):
2772 elemIDs.SetMesh( self.GetMesh() )
2773 group.AddFrom( elemIDs )
2781 CritType=FT_Undefined,
2784 UnaryOp=FT_Undefined,
2787 Create a mesh group by the given conditions
2790 groupName: the name of the mesh group
2791 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2792 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2793 Note that the items starting from FT_LessThan are not suitable for CritType.
2794 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2795 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2796 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2797 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2798 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2801 :class:`SMESH.SMESH_GroupOnFilter`
2804 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2805 group = self.MakeGroupByCriterion(groupName, aCriterion)
2808 def MakeGroupByCriterion(self, groupName, Criterion):
2810 Create a mesh group by the given criterion
2813 groupName: the name of the mesh group
2814 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2817 :class:`SMESH.SMESH_GroupOnFilter`
2820 :meth:`smeshBuilder.GetCriterion`
2823 return self.MakeGroupByCriteria( groupName, [Criterion] )
2825 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2827 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2830 groupName: the name of the mesh group
2831 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2832 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2835 :class:`SMESH.SMESH_GroupOnFilter`
2838 :meth:`smeshBuilder.GetCriterion`
2841 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2842 group = self.MakeGroupByFilter(groupName, aFilter)
2845 def MakeGroupByFilter(self, groupName, theFilter):
2847 Create a mesh group by the given filter
2850 groupName (string): the name of the mesh group
2851 theFilter (SMESH.Filter): the filter
2854 :class:`SMESH.SMESH_GroupOnFilter`
2857 :meth:`smeshBuilder.GetFilter`
2860 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2861 #theFilter.SetMesh( self.mesh )
2862 #group.AddFrom( theFilter )
2863 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2866 def RemoveGroup(self, group):
2871 group (SMESH.SMESH_GroupBase): group to remove
2874 self.mesh.RemoveGroup(group)
2876 def RemoveGroupWithContents(self, group):
2878 Remove a group with its contents
2881 group (SMESH.SMESH_GroupBase): group to remove
2884 This operation can create gaps in numeration of nodes or elements.
2885 Call :meth:`RenumberElements` to remove the gaps.
2888 self.mesh.RemoveGroupWithContents(group)
2890 def GetGroups(self, elemType = SMESH.ALL):
2892 Get the list of groups existing in the mesh in the order of creation
2893 (starting from the oldest one)
2896 elemType (SMESH.ElementType): type of elements the groups contain;
2897 by default groups of elements of all types are returned
2900 a list of :class:`SMESH.SMESH_GroupBase`
2903 groups = self.mesh.GetGroups()
2904 if elemType == SMESH.ALL:
2908 if g.GetType() == elemType:
2909 typedGroups.append( g )
2916 Get the number of groups existing in the mesh
2919 the quantity of groups as an integer value
2922 return self.mesh.NbGroups()
2924 def GetGroupNames(self):
2926 Get the list of names of groups existing in the mesh
2932 groups = self.GetGroups()
2934 for group in groups:
2935 names.append(group.GetName())
2938 def GetGroupByName(self, name, elemType = None):
2940 Find groups by name and type
2943 name (string): name of the group of interest
2944 elemType (SMESH.ElementType): type of elements the groups contain;
2945 by default one group of any type is returned;
2946 if elemType == SMESH.ALL then all groups of any type are returned
2949 a list of :class:`SMESH.SMESH_GroupBase`
2953 for group in self.GetGroups():
2954 if group.GetName() == name:
2955 if elemType is None:
2957 if ( elemType == SMESH.ALL or
2958 group.GetType() == elemType ):
2959 groups.append( group )
2962 def UnionGroups(self, group1, group2, name):
2964 Produce a union of two groups.
2965 A new group is created. All mesh elements that are
2966 present in the initial groups are added to the new one
2969 group1 (SMESH.SMESH_GroupBase): a group
2970 group2 (SMESH.SMESH_GroupBase): another group
2973 instance of :class:`SMESH.SMESH_Group`
2976 return self.mesh.UnionGroups(group1, group2, name)
2978 def UnionListOfGroups(self, groups, name):
2980 Produce a union list of groups.
2981 New group is created. All mesh elements that are present in
2982 initial groups are added to the new one
2985 groups: list of :class:`SMESH.SMESH_GroupBase`
2988 instance of :class:`SMESH.SMESH_Group`
2990 return self.mesh.UnionListOfGroups(groups, name)
2992 def IntersectGroups(self, group1, group2, name):
2994 Prodice an intersection of two groups.
2995 A new group is created. All mesh elements that are common
2996 for the two initial groups are added to the new one.
2999 group1 (SMESH.SMESH_GroupBase): a group
3000 group2 (SMESH.SMESH_GroupBase): another group
3003 instance of :class:`SMESH.SMESH_Group`
3006 return self.mesh.IntersectGroups(group1, group2, name)
3008 def IntersectListOfGroups(self, groups, name):
3010 Produce an intersection of groups.
3011 New group is created. All mesh elements that are present in all
3012 initial groups simultaneously are added to the new one
3015 groups: a list of :class:`SMESH.SMESH_GroupBase`
3018 instance of :class:`SMESH.SMESH_Group`
3020 return self.mesh.IntersectListOfGroups(groups, name)
3022 def CutGroups(self, main_group, tool_group, name):
3024 Produce a cut of two groups.
3025 A new group is created. All mesh elements that are present in
3026 the main group but are not present in the tool group are added to the new one
3029 main_group (SMESH.SMESH_GroupBase): a group to cut from
3030 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3033 an instance of :class:`SMESH.SMESH_Group`
3036 return self.mesh.CutGroups(main_group, tool_group, name)
3038 def CutListOfGroups(self, main_groups, tool_groups, name):
3040 Produce a cut of groups.
3041 A new group is created. All mesh elements that are present in main groups
3042 but do not present in tool groups are added to the new one
3045 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3046 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3049 an instance of :class:`SMESH.SMESH_Group`
3052 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3054 def CreateDimGroup(self, groups, elemType, name,
3055 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3057 Create a standalone group of entities basing on nodes of other groups.
3060 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3061 elemType: a type of elements to include to the new group; either of
3062 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3063 name: a name of the new group.
3064 nbCommonNodes: a criterion of inclusion of an element to the new group
3065 basing on number of element nodes common with reference *groups*.
3066 Meaning of possible values are:
3068 - SMESH.ALL_NODES - include if all nodes are common,
3069 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3070 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3071 - SMEHS.MAJORITY - include if half of nodes or more are common.
3072 underlyingOnly: if *True* (default), an element is included to the
3073 new group provided that it is based on nodes of an element of *groups*;
3074 in this case the reference *groups* are supposed to be of higher dimension
3075 than *elemType*, which can be useful for example to get all faces lying on
3076 volumes of the reference *groups*.
3079 an instance of :class:`SMESH.SMESH_Group`
3082 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3084 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3086 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3088 Distribute all faces of the mesh among groups using sharp edges and optionally
3089 existing 1D elements as group boundaries.
3092 sharpAngle: edge is considered sharp if an angle between normals of
3093 adjacent faces is more than \a sharpAngle in degrees.
3094 createEdges (boolean): to create 1D elements for detected sharp edges.
3095 useExistingEdges (boolean): to use existing edges as group boundaries
3097 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3099 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3100 self.mesh.SetParameters(Parameters)
3101 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3103 def ConvertToStandalone(self, group):
3105 Convert group on geom into standalone group
3108 return self.mesh.ConvertToStandalone(group)
3110 # Get some info about mesh:
3111 # ------------------------
3113 def GetLog(self, clearAfterGet):
3115 Return the log of nodes and elements added or removed
3116 since the previous clear of the log.
3119 clearAfterGet: log is emptied after Get (safe if concurrents access)
3122 list of SMESH.log_block structures { commandType, number, coords, indexes }
3125 return self.mesh.GetLog(clearAfterGet)
3129 Clear the log of nodes and elements added or removed since the previous
3130 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3133 self.mesh.ClearLog()
3135 def SetAutoColor(self, theAutoColor):
3137 Toggle auto color mode on the object.
3138 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3141 theAutoColor (boolean): the flag which toggles auto color mode.
3144 self.mesh.SetAutoColor(theAutoColor)
3146 def GetAutoColor(self):
3148 Get flag of object auto color mode.
3154 return self.mesh.GetAutoColor()
3161 integer value, which is the internal Id of the mesh
3164 return self.mesh.GetId()
3166 def HasDuplicatedGroupNamesMED(self):
3168 Check the group names for duplications.
3169 Consider the maximum group name length stored in MED file.
3175 return self.mesh.HasDuplicatedGroupNamesMED()
3177 def GetMeshEditor(self):
3179 Obtain the mesh editor tool
3182 an instance of :class:`SMESH.SMESH_MeshEditor`
3187 def GetIDSource(self, ids, elemType = SMESH.ALL):
3189 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3190 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3194 elemType: type of elements; this parameter is used to distinguish
3195 IDs of nodes from IDs of elements; by default ids are treated as
3196 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3199 an instance of :class:`SMESH.SMESH_IDSource`
3202 call UnRegister() for the returned object as soon as it is no more useful::
3204 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3205 mesh.DoSomething( idSrc )
3209 if isinstance( ids, int ):
3211 return self.editor.MakeIDSource(ids, elemType)
3214 # Get information about mesh contents:
3215 # ------------------------------------
3217 def GetMeshInfo(self, obj = None):
3219 Get the mesh statistic.
3222 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3225 if not obj: obj = self.mesh
3226 return self.smeshpyD.GetMeshInfo(obj)
3230 Return the number of nodes in the mesh
3236 return self.mesh.NbNodes()
3238 def NbElements(self):
3240 Return the number of elements in the mesh
3246 return self.mesh.NbElements()
3248 def Nb0DElements(self):
3250 Return the number of 0d elements in the mesh
3256 return self.mesh.Nb0DElements()
3260 Return the number of ball discrete elements in the mesh
3266 return self.mesh.NbBalls()
3270 Return the number of edges in the mesh
3276 return self.mesh.NbEdges()
3278 def NbEdgesOfOrder(self, elementOrder):
3280 Return the number of edges with the given order in the mesh
3283 elementOrder: the order of elements
3284 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3290 return self.mesh.NbEdgesOfOrder(elementOrder)
3294 Return the number of faces in the mesh
3300 return self.mesh.NbFaces()
3302 def NbFacesOfOrder(self, elementOrder):
3304 Return the number of faces with the given order in the mesh
3307 elementOrder: the order of elements
3308 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3314 return self.mesh.NbFacesOfOrder(elementOrder)
3316 def NbTriangles(self):
3318 Return the number of triangles in the mesh
3324 return self.mesh.NbTriangles()
3326 def NbTrianglesOfOrder(self, elementOrder):
3328 Return the number of triangles with the given order in the mesh
3331 elementOrder: is the order of elements
3332 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3338 return self.mesh.NbTrianglesOfOrder(elementOrder)
3340 def NbBiQuadTriangles(self):
3342 Return the number of biquadratic triangles in the mesh
3348 return self.mesh.NbBiQuadTriangles()
3350 def NbQuadrangles(self):
3352 Return the number of quadrangles in the mesh
3358 return self.mesh.NbQuadrangles()
3360 def NbQuadranglesOfOrder(self, elementOrder):
3362 Return the number of quadrangles with the given order in the mesh
3365 elementOrder: the order of elements
3366 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3372 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3374 def NbBiQuadQuadrangles(self):
3376 Return the number of biquadratic quadrangles in the mesh
3382 return self.mesh.NbBiQuadQuadrangles()
3384 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3386 Return the number of polygons of given order in the mesh
3389 elementOrder: the order of elements
3390 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3396 return self.mesh.NbPolygonsOfOrder(elementOrder)
3398 def NbVolumes(self):
3400 Return the number of volumes in the mesh
3406 return self.mesh.NbVolumes()
3409 def NbVolumesOfOrder(self, elementOrder):
3411 Return the number of volumes with the given order in the mesh
3414 elementOrder: the order of elements
3415 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3421 return self.mesh.NbVolumesOfOrder(elementOrder)
3425 Return the number of tetrahedrons in the mesh
3431 return self.mesh.NbTetras()
3433 def NbTetrasOfOrder(self, elementOrder):
3435 Return the number of tetrahedrons with the given order in the mesh
3438 elementOrder: the order of elements
3439 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3445 return self.mesh.NbTetrasOfOrder(elementOrder)
3449 Return the number of hexahedrons in the mesh
3455 return self.mesh.NbHexas()
3457 def NbHexasOfOrder(self, elementOrder):
3459 Return the number of hexahedrons with the given order in the mesh
3462 elementOrder: the order of elements
3463 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3469 return self.mesh.NbHexasOfOrder(elementOrder)
3471 def NbTriQuadraticHexas(self):
3473 Return the number of triquadratic hexahedrons in the mesh
3479 return self.mesh.NbTriQuadraticHexas()
3481 def NbPyramids(self):
3483 Return the number of pyramids in the mesh
3489 return self.mesh.NbPyramids()
3491 def NbPyramidsOfOrder(self, elementOrder):
3493 Return the number of pyramids with the given order in the mesh
3496 elementOrder: the order of elements
3497 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3503 return self.mesh.NbPyramidsOfOrder(elementOrder)
3507 Return the number of prisms in the mesh
3513 return self.mesh.NbPrisms()
3515 def NbPrismsOfOrder(self, elementOrder):
3517 Return the number of prisms with the given order in the mesh
3520 elementOrder: the order of elements
3521 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3527 return self.mesh.NbPrismsOfOrder(elementOrder)
3529 def NbHexagonalPrisms(self):
3531 Return the number of hexagonal prisms in the mesh
3537 return self.mesh.NbHexagonalPrisms()
3539 def NbPolyhedrons(self):
3541 Return the number of polyhedrons in the mesh
3547 return self.mesh.NbPolyhedrons()
3549 def NbSubMesh(self):
3551 Return the number of submeshes in the mesh
3557 return self.mesh.NbSubMesh()
3559 def GetElementsId(self):
3561 Return the list of all mesh elements IDs
3564 the list of integer values
3567 :meth:`GetElementsByType`
3570 return self.mesh.GetElementsId()
3572 def GetElementsByType(self, elementType):
3574 Return the list of IDs of mesh elements with the given type
3577 elementType (SMESH.ElementType): the required type of elements
3580 list of integer values
3583 return self.mesh.GetElementsByType(elementType)
3585 def GetNodesId(self):
3587 Return the list of mesh nodes IDs
3590 the list of integer values
3593 return self.mesh.GetNodesId()
3595 # Get the information about mesh elements:
3596 # ------------------------------------
3598 def GetElementType(self, id, iselem=True):
3600 Return the type of mesh element or node
3603 the value from :class:`SMESH.ElementType` enumeration.
3604 Return SMESH.ALL if element or node with the given ID does not exist
3607 return self.mesh.GetElementType(id, iselem)
3609 def GetElementGeomType(self, id):
3611 Return the geometric type of mesh element
3614 the value from :class:`SMESH.EntityType` enumeration.
3617 return self.mesh.GetElementGeomType(id)
3619 def GetElementShape(self, id):
3621 Return the shape type of mesh element
3624 the value from :class:`SMESH.GeometryType` enumeration.
3627 return self.mesh.GetElementShape(id)
3629 def GetSubMeshElementsId(self, Shape):
3631 Return the list of sub-mesh elements IDs
3634 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3635 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3638 list of integer values
3641 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3642 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3645 return self.mesh.GetSubMeshElementsId(ShapeID)
3647 def GetSubMeshNodesId(self, Shape, all):
3649 Return the list of sub-mesh nodes IDs
3652 Shape: a geom object (sub-shape).
3653 *Shape* must be the sub-shape of a :meth:`GetShape`
3654 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3657 list of integer values
3660 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3661 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3664 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3666 def GetSubMeshElementType(self, Shape):
3668 Return type of elements on given shape
3671 Shape: a geom object (sub-shape).
3672 *Shape* must be a sub-shape of a ShapeToMesh()
3675 :class:`SMESH.ElementType`
3678 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3679 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3682 return self.mesh.GetSubMeshElementType(ShapeID)
3686 Get the mesh description
3692 return self.mesh.Dump()
3695 # Get the information about nodes and elements of a mesh by its IDs:
3696 # -----------------------------------------------------------
3698 def GetNodeXYZ(self, id):
3700 Get XYZ coordinates of a node.
3701 If there is no node for the given ID - return an empty list
3704 list of float values
3707 return self.mesh.GetNodeXYZ(id)
3709 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3711 Return list of IDs of inverse elements for the given node.
3712 If there is no node for the given ID - return an empty list
3716 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3719 list of integer values
3722 return self.mesh.GetNodeInverseElements(id,elemType)
3724 def GetNodePosition(self,NodeID):
3726 Return the position of a node on the shape
3729 :class:`SMESH.NodePosition`
3732 return self.mesh.GetNodePosition(NodeID)
3734 def GetElementPosition(self,ElemID):
3736 Return the position of an element on the shape
3739 :class:`SMESH.ElementPosition`
3742 return self.mesh.GetElementPosition(ElemID)
3744 def GetShapeID(self, id):
3746 Return the ID of the shape, on which the given node was generated.
3749 an integer value > 0 or -1 if there is no node for the given
3750 ID or the node is not assigned to any geometry
3753 return self.mesh.GetShapeID(id)
3755 def GetShapeIDForElem(self,id):
3757 Return the ID of the shape, on which the given element was generated.
3760 an integer value > 0 or -1 if there is no element for the given
3761 ID or the element is not assigned to any geometry
3764 return self.mesh.GetShapeIDForElem(id)
3766 def GetElemNbNodes(self, id):
3768 Return the number of nodes of the given element
3771 an integer value > 0 or -1 if there is no element for the given ID
3774 return self.mesh.GetElemNbNodes(id)
3776 def GetElemNode(self, id, index):
3778 Return the node ID the given (zero based) index for the given element.
3780 * If there is no element for the given ID - return -1.
3781 * If there is no node for the given index - return -2.
3784 id (int): element ID
3785 index (int): node index within the element
3788 an integer value (ID)
3791 :meth:`GetElemNodes`
3794 return self.mesh.GetElemNode(id, index)
3796 def GetElemNodes(self, id):
3798 Return the IDs of nodes of the given element
3801 a list of integer values
3804 return self.mesh.GetElemNodes(id)
3806 def IsMediumNode(self, elementID, nodeID):
3808 Return true if the given node is the medium node in the given quadratic element
3811 return self.mesh.IsMediumNode(elementID, nodeID)
3813 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3815 Return true if the given node is the medium node in one of quadratic elements
3818 nodeID: ID of the node
3819 elementType: the type of elements to check a state of the node, either of
3820 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3823 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3825 def ElemNbEdges(self, id):
3827 Return the number of edges for the given element
3830 return self.mesh.ElemNbEdges(id)
3832 def ElemNbFaces(self, id):
3834 Return the number of faces for the given element
3837 return self.mesh.ElemNbFaces(id)
3839 def GetElemFaceNodes(self,elemId, faceIndex):
3841 Return nodes of given face (counted from zero) for given volumic element.
3844 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3846 def GetFaceNormal(self, faceId, normalized=False):
3848 Return three components of normal of given mesh face
3849 (or an empty array in KO case)
3852 return self.mesh.GetFaceNormal(faceId,normalized)
3854 def FindElementByNodes(self, nodes):
3856 Return an element based on all given nodes.
3859 return self.mesh.FindElementByNodes(nodes)
3861 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3863 Return elements including all given nodes.
3866 return self.mesh.GetElementsByNodes( nodes, elemType )
3868 def IsPoly(self, id):
3870 Return true if the given element is a polygon
3873 return self.mesh.IsPoly(id)
3875 def IsQuadratic(self, id):
3877 Return true if the given element is quadratic
3880 return self.mesh.IsQuadratic(id)
3882 def GetBallDiameter(self, id):
3884 Return diameter of a ball discrete element or zero in case of an invalid *id*
3887 return self.mesh.GetBallDiameter(id)
3889 def BaryCenter(self, id):
3891 Return XYZ coordinates of the barycenter of the given element.
3892 If there is no element for the given ID - return an empty list
3895 a list of three double values
3898 :meth:`smeshBuilder.GetGravityCenter`
3901 return self.mesh.BaryCenter(id)
3903 def GetIdsFromFilter(self, filter, meshParts=[] ):
3905 Pass mesh elements through the given filter and return IDs of fitting elements
3908 filter: :class:`SMESH.Filter`
3909 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3915 :meth:`SMESH.Filter.GetIDs`
3916 :meth:`SMESH.Filter.GetElementsIdFromParts`
3919 filter.SetMesh( self.mesh )
3922 if isinstance( meshParts, Mesh ):
3923 filter.SetMesh( meshParts.GetMesh() )
3924 return theFilter.GetIDs()
3925 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3926 meshParts = [ meshParts ]
3927 return filter.GetElementsIdFromParts( meshParts )
3929 return filter.GetIDs()
3931 # Get mesh measurements information:
3932 # ------------------------------------
3934 def GetFreeBorders(self):
3936 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3937 Return a list of special structures (borders).
3940 a list of :class:`SMESH.FreeEdges.Border`
3943 aFilterMgr = self.smeshpyD.CreateFilterManager()
3944 aPredicate = aFilterMgr.CreateFreeEdges()
3945 aPredicate.SetMesh(self.mesh)
3946 aBorders = aPredicate.GetBorders()
3947 aFilterMgr.UnRegister()
3950 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3952 Get minimum distance between two nodes, elements or distance to the origin
3955 id1: first node/element id
3956 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3957 isElem1: *True* if *id1* is element id, *False* if it is node id
3958 isElem2: *True* if *id2* is element id, *False* if it is node id
3961 minimum distance value
3963 :meth:`GetMinDistance`
3966 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3967 return aMeasure.value
3969 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3971 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3974 id1: first node/element id
3975 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3976 isElem1: *True* if *id1* is element id, *False* if it is node id
3977 isElem2: *True* if *id2* is element id, *False* if it is node id
3980 :class:`SMESH.Measure` structure
3986 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3988 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3991 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3993 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3998 aMeasurements = self.smeshpyD.CreateMeasurements()
3999 aMeasure = aMeasurements.MinDistance(id1, id2)
4000 genObjUnRegister([aMeasurements,id1, id2])
4003 def BoundingBox(self, objects=None, isElem=False):
4005 Get bounding box of the specified object(s)
4008 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4009 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4010 *False* specifies that *objects* are nodes
4013 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4016 :meth:`GetBoundingBox()`
4019 result = self.GetBoundingBox(objects, isElem)
4023 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4026 def GetBoundingBox(self, objects=None, isElem=False):
4028 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4031 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4032 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4033 False means that *objects* are nodes
4036 :class:`SMESH.Measure` structure
4039 :meth:`BoundingBox()`
4043 objects = [self.mesh]
4044 elif isinstance(objects, tuple):
4045 objects = list(objects)
4046 if not isinstance(objects, list):
4048 if len(objects) > 0 and isinstance(objects[0], int):
4051 unRegister = genObjUnRegister()
4053 if isinstance(o, Mesh):
4054 srclist.append(o.mesh)
4055 elif hasattr(o, "_narrow"):
4056 src = o._narrow(SMESH.SMESH_IDSource)
4057 if src: srclist.append(src)
4059 elif isinstance(o, list):
4061 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4063 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4064 unRegister.set( srclist[-1] )
4067 aMeasurements = self.smeshpyD.CreateMeasurements()
4068 unRegister.set( aMeasurements )
4069 aMeasure = aMeasurements.BoundingBox(srclist)
4072 # Mesh edition (SMESH_MeshEditor functionality):
4073 # ---------------------------------------------
4075 def RemoveElements(self, IDsOfElements):
4077 Remove the elements from the mesh by ids
4080 IDsOfElements: is a list of ids of elements to remove
4086 This operation can create gaps in numeration of elements.
4087 Call :meth:`RenumberElements` to remove the gaps.
4090 return self.editor.RemoveElements(IDsOfElements)
4092 def RemoveNodes(self, IDsOfNodes):
4094 Remove nodes from mesh by ids
4097 IDsOfNodes: is a list of ids of nodes to remove
4103 This operation can create gaps in numeration of nodes.
4104 Call :meth:`RenumberElements` to remove the gaps.
4107 return self.editor.RemoveNodes(IDsOfNodes)
4109 def RemoveOrphanNodes(self):
4111 Remove all orphan (free) nodes from mesh
4114 number of the removed nodes
4117 This operation can create gaps in numeration of nodes.
4118 Call :meth:`RenumberElements` to remove the gaps.
4121 return self.editor.RemoveOrphanNodes()
4123 def AddNode(self, x, y, z):
4125 Add a node to the mesh by coordinates
4131 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4132 if hasVars: self.mesh.SetParameters(Parameters)
4133 return self.editor.AddNode( x, y, z)
4135 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4137 Create a 0D element on a node with given number.
4140 IDOfNode: the ID of node for creation of the element.
4141 DuplicateElements: to add one more 0D element to a node or not
4144 ID of the new 0D element
4147 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4149 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4151 Create 0D elements on all nodes of the given elements except those
4152 nodes on which a 0D element already exists.
4155 theObject: an object on whose nodes 0D elements will be created.
4156 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4157 theGroupName: optional name of a group to add 0D elements created
4158 and/or found on nodes of *theObject*.
4159 DuplicateElements: to add one more 0D element to a node or not
4162 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4163 IDs of new and/or found 0D elements. IDs of 0D elements
4164 can be retrieved from the returned object by
4165 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4168 unRegister = genObjUnRegister()
4169 if isinstance( theObject, Mesh ):
4170 theObject = theObject.GetMesh()
4171 elif isinstance( theObject, list ):
4172 theObject = self.GetIDSource( theObject, SMESH.ALL )
4173 unRegister.set( theObject )
4174 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4176 def AddBall(self, IDOfNode, diameter):
4178 Create a ball element on a node with given ID.
4181 IDOfNode: the ID of node for creation of the element.
4182 diameter: the bal diameter.
4185 ID of the new ball element
4188 return self.editor.AddBall( IDOfNode, diameter )
4190 def AddEdge(self, IDsOfNodes):
4192 Create a linear or quadratic edge (this is determined
4193 by the number of given nodes).
4196 IDsOfNodes: list of node IDs for creation of the element.
4197 The order of nodes in this list should correspond to
4198 the :ref:`connectivity convention <connectivity_page>`.
4204 return self.editor.AddEdge(IDsOfNodes)
4206 def AddFace(self, IDsOfNodes):
4208 Create a linear or quadratic face (this is determined
4209 by the number of given nodes).
4212 IDsOfNodes: list of node IDs for creation of the element.
4213 The order of nodes in this list should correspond to
4214 the :ref:`connectivity convention <connectivity_page>`.
4220 return self.editor.AddFace(IDsOfNodes)
4222 def AddPolygonalFace(self, IdsOfNodes):
4224 Add a polygonal face defined by a list of node IDs
4227 IdsOfNodes: the list of node IDs for creation of the element.
4233 return self.editor.AddPolygonalFace(IdsOfNodes)
4235 def AddQuadPolygonalFace(self, IdsOfNodes):
4237 Add a quadratic polygonal face defined by a list of node IDs
4240 IdsOfNodes: the list of node IDs for creation of the element;
4241 corner nodes follow first.
4247 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4249 def AddVolume(self, IDsOfNodes):
4251 Create both simple and quadratic volume (this is determined
4252 by the number of given nodes).
4255 IDsOfNodes: list of node IDs for creation of the element.
4256 The order of nodes in this list should correspond to
4257 the :ref:`connectivity convention <connectivity_page>`.
4260 ID of the new volumic element
4263 return self.editor.AddVolume(IDsOfNodes)
4265 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4267 Create a volume of many faces, giving nodes for each face.
4270 IdsOfNodes: list of node IDs for volume creation, face by face.
4271 Quantities: list of integer values, Quantities[i]
4272 gives the quantity of nodes in face number i.
4275 ID of the new volumic element
4278 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4280 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4282 Create a volume of many faces, giving the IDs of the existing faces.
4285 The created volume will refer only to the nodes
4286 of the given faces, not to the faces themselves.
4289 IdsOfFaces: the list of face IDs for volume creation.
4292 ID of the new volumic element
4295 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4298 def SetNodeOnVertex(self, NodeID, Vertex):
4300 Bind a node to a vertex
4304 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4307 True if succeed else raises an exception
4310 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4311 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4315 self.editor.SetNodeOnVertex(NodeID, VertexID)
4316 except SALOME.SALOME_Exception as inst:
4317 raise ValueError(inst.details.text)
4321 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4323 Store the node position on an edge
4327 Edge: an edge (GEOM.GEOM_Object) or edge ID
4328 paramOnEdge: a parameter on the edge where the node is located
4331 True if succeed else raises an exception
4334 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4335 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4339 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4340 except SALOME.SALOME_Exception as inst:
4341 raise ValueError(inst.details.text)
4344 def SetNodeOnFace(self, NodeID, Face, u, v):
4346 Store node position on a face
4350 Face: a face (GEOM.GEOM_Object) or face ID
4351 u: U parameter on the face where the node is located
4352 v: V parameter on the face where the node is located
4355 True if succeed else raises an exception
4358 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4359 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4363 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4364 except SALOME.SALOME_Exception as inst:
4365 raise ValueError(inst.details.text)
4368 def SetNodeInVolume(self, NodeID, Solid):
4370 Bind a node to a solid
4374 Solid: a solid (GEOM.GEOM_Object) or solid ID
4377 True if succeed else raises an exception
4380 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4381 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4385 self.editor.SetNodeInVolume(NodeID, SolidID)
4386 except SALOME.SALOME_Exception as inst:
4387 raise ValueError(inst.details.text)
4390 def SetMeshElementOnShape(self, ElementID, Shape):
4392 Bind an element to a shape
4395 ElementID: an element ID
4396 Shape: a shape (GEOM.GEOM_Object) or shape ID
4399 True if succeed else raises an exception
4402 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4403 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4407 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4408 except SALOME.SALOME_Exception as inst:
4409 raise ValueError(inst.details.text)
4413 def MoveNode(self, NodeID, x, y, z):
4415 Move the node with the given id
4418 NodeID: the id of the node
4419 x: a new X coordinate
4420 y: a new Y coordinate
4421 z: a new Z coordinate
4424 True if succeed else False
4427 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4428 if hasVars: self.mesh.SetParameters(Parameters)
4429 return self.editor.MoveNode(NodeID, x, y, z)
4431 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4433 Find the node closest to a point and moves it to a point location
4436 x: the X coordinate of a point
4437 y: the Y coordinate of a point
4438 z: the Z coordinate of a point
4439 NodeID: if specified (>0), the node with this ID is moved,
4440 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4443 the ID of a moved node
4446 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4447 if hasVars: self.mesh.SetParameters(Parameters)
4448 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4450 def FindNodeClosestTo(self, x, y, z):
4452 Find the node closest to a point
4455 x: the X coordinate of a point
4456 y: the Y coordinate of a point
4457 z: the Z coordinate of a point
4463 return self.editor.FindNodeClosestTo(x, y, z)
4465 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4467 Find the elements where a point lays IN or ON
4470 x,y,z (float): coordinates of the point
4471 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4472 means elements of any type excluding nodes, discrete and 0D elements.
4473 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4476 list of IDs of found elements
4479 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4481 return self.editor.FindElementsByPoint(x, y, z, elementType)
4483 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4485 Project a point to a mesh object.
4486 Return ID of an element of given type where the given point is projected
4487 and coordinates of the projection point.
4488 In the case if nothing found, return -1 and []
4490 if isinstance( meshObject, Mesh ):
4491 meshObject = meshObject.GetMesh()
4493 meshObject = self.GetMesh()
4494 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4496 def GetPointState(self, x, y, z):
4498 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4499 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4500 UNKNOWN state means that either mesh is wrong or the analysis fails.
4503 return self.editor.GetPointState(x, y, z)
4505 def IsManifold(self):
4507 Check if a 2D mesh is manifold
4510 return self.editor.IsManifold()
4512 def IsCoherentOrientation2D(self):
4514 Check if orientation of 2D elements is coherent
4517 return self.editor.IsCoherentOrientation2D()
4519 def Get1DBranches( self, edges, startNode = 0 ):
4521 Partition given 1D elements into groups of contiguous edges.
4522 A node where number of meeting edges != 2 is a group end.
4523 An optional startNode is used to orient groups it belongs to.
4526 A list of edge groups and a list of corresponding node groups,
4527 where the group is a list of IDs of edges or nodes, like follows
4528 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4529 If a group is closed, the first and last nodes of the group are same.
4531 if isinstance( edges, Mesh ):
4532 edges = edges.GetMesh()
4533 unRegister = genObjUnRegister()
4534 if isinstance( edges, list ):
4535 edges = self.GetIDSource( edges, SMESH.EDGE )
4536 unRegister.set( edges )
4537 return self.editor.Get1DBranches( edges, startNode )
4539 def FindSharpEdges( self, angle, addExisting=False ):
4541 Return sharp edges of faces and non-manifold ones.
4542 Optionally add existing edges.
4545 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4546 addExisting: to return existing edges (1D elements) as well
4549 list of FaceEdge structures
4551 angle = ParseParameters( angle )[0]
4552 return self.editor.FindSharpEdges( angle, addExisting )
4554 def MeshToPassThroughAPoint(self, x, y, z):
4556 Find the node closest to a point and moves it to a point location
4559 x: the X coordinate of a point
4560 y: the Y coordinate of a point
4561 z: the Z coordinate of a point
4564 the ID of a moved node
4567 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4569 def InverseDiag(self, NodeID1, NodeID2):
4571 Replace two neighbour triangles sharing Node1-Node2 link
4572 with the triangles built on the same 4 nodes but having other common link.
4575 NodeID1: the ID of the first node
4576 NodeID2: the ID of the second node
4579 False if proper faces were not found
4581 return self.editor.InverseDiag(NodeID1, NodeID2)
4583 def DeleteDiag(self, NodeID1, NodeID2):
4585 Replace two neighbour triangles sharing *Node1-Node2* link
4586 with a quadrangle built on the same 4 nodes.
4589 NodeID1: ID of the first node
4590 NodeID2: ID of the second node
4593 False if proper faces were not found
4596 This operation can create gaps in numeration of elements.
4597 Call :meth:`RenumberElements` to remove the gaps.
4600 return self.editor.DeleteDiag(NodeID1, NodeID2)
4602 def Reorient(self, IDsOfElements=None):
4604 Reorient elements by ids
4607 IDsOfElements: if undefined reorients all mesh elements
4610 True if succeed else False
4613 if IDsOfElements == None:
4614 IDsOfElements = self.GetElementsId()
4615 return self.editor.Reorient(IDsOfElements)
4617 def ReorientObject(self, theObject):
4619 Reorient all elements of the object
4622 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4625 True if succeed else False
4628 if ( isinstance( theObject, Mesh )):
4629 theObject = theObject.GetMesh()
4630 return self.editor.ReorientObject(theObject)
4632 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4634 Reorient faces contained in *the2DObject*.
4637 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4638 theDirection: a desired direction of normal of *theFace*.
4639 It can be either a GEOM vector or a list of coordinates [x,y,z].
4640 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4641 compared with theDirection. It can be either ID of face or a point
4642 by which the face will be found. The point can be given as either
4643 a GEOM vertex or a list of point coordinates.
4646 number of reoriented faces
4649 unRegister = genObjUnRegister()
4651 if isinstance( the2DObject, Mesh ):
4652 the2DObject = the2DObject.GetMesh()
4653 if isinstance( the2DObject, list ):
4654 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4655 unRegister.set( the2DObject )
4656 # check theDirection
4657 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4658 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4659 if isinstance( theDirection, list ):
4660 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4661 # prepare theFace and thePoint
4662 theFace = theFaceOrPoint
4663 thePoint = PointStruct(0,0,0)
4664 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4665 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4667 if isinstance( theFaceOrPoint, list ):
4668 thePoint = PointStruct( *theFaceOrPoint )
4670 if isinstance( theFaceOrPoint, PointStruct ):
4671 thePoint = theFaceOrPoint
4673 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4675 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4677 Reorient faces according to adjacent volumes.
4680 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4681 either IDs of faces or face groups.
4682 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4683 theOutsideNormal: to orient faces to have their normals
4684 pointing either *outside* or *inside* the adjacent volumes.
4687 number of reoriented faces.
4690 unRegister = genObjUnRegister()
4692 if not isinstance( the2DObject, list ):
4693 the2DObject = [ the2DObject ]
4694 elif the2DObject and isinstance( the2DObject[0], int ):
4695 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4696 unRegister.set( the2DObject )
4697 the2DObject = [ the2DObject ]
4698 for i,obj2D in enumerate( the2DObject ):
4699 if isinstance( obj2D, Mesh ):
4700 the2DObject[i] = obj2D.GetMesh()
4701 if isinstance( obj2D, list ):
4702 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4703 unRegister.set( the2DObject[i] )
4705 if isinstance( the3DObject, Mesh ):
4706 the3DObject = the3DObject.GetMesh()
4707 if isinstance( the3DObject, list ):
4708 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4709 unRegister.set( the3DObject )
4710 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4712 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4714 Fuse the neighbouring triangles into quadrangles.
4717 IDsOfElements: The triangles to be fused.
4718 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4719 applied to possible quadrangles to choose a neighbour to fuse with.
4720 Note that not all items of :class:`SMESH.FunctorType` corresponds
4721 to numerical functors.
4722 MaxAngle: is the maximum angle between element normals at which the fusion
4723 is still performed; theMaxAngle is measured in radians.
4724 Also it could be a name of variable which defines angle in degrees.
4727 True in case of success, False otherwise.
4730 This operation can create gaps in numeration of elements.
4731 Call :meth:`RenumberElements` to remove the gaps.
4734 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4735 self.mesh.SetParameters(Parameters)
4736 if not IDsOfElements:
4737 IDsOfElements = self.GetElementsId()
4738 Functor = self.smeshpyD.GetFunctor(theCriterion)
4739 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4741 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4743 Fuse the neighbouring triangles of the object into quadrangles
4746 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4747 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4748 applied to possible quadrangles to choose a neighbour to fuse with.
4749 Note that not all items of :class:`SMESH.FunctorType` corresponds
4750 to numerical functors.
4751 MaxAngle: a max angle between element normals at which the fusion
4752 is still performed; theMaxAngle is measured in radians.
4755 True in case of success, False otherwise.
4758 This operation can create gaps in numeration of elements.
4759 Call :meth:`RenumberElements` to remove the gaps.
4762 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4763 self.mesh.SetParameters(Parameters)
4764 if isinstance( theObject, Mesh ):
4765 theObject = theObject.GetMesh()
4766 Functor = self.smeshpyD.GetFunctor(theCriterion)
4767 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4769 def QuadToTri (self, IDsOfElements, theCriterion = None):
4771 Split quadrangles into triangles.
4774 IDsOfElements: the faces to be splitted.
4775 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4776 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4777 value, then quadrangles will be split by the smallest diagonal.
4778 Note that not all items of :class:`SMESH.FunctorType` corresponds
4779 to numerical functors.
4782 True in case of success, False otherwise.
4785 This operation can create gaps in numeration of elements.
4786 Call :meth:`RenumberElements` to remove the gaps.
4788 if IDsOfElements == []:
4789 IDsOfElements = self.GetElementsId()
4790 if theCriterion is None:
4791 theCriterion = FT_MaxElementLength2D
4792 Functor = self.smeshpyD.GetFunctor(theCriterion)
4793 return self.editor.QuadToTri(IDsOfElements, Functor)
4795 def QuadToTriObject (self, theObject, theCriterion = None):
4797 Split quadrangles into triangles.
4800 theObject: the object from which the list of elements is taken,
4801 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4802 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4803 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4804 value, then quadrangles will be split by the smallest diagonal.
4805 Note that not all items of :class:`SMESH.FunctorType` corresponds
4806 to numerical functors.
4809 True in case of success, False otherwise.
4812 This operation can create gaps in numeration of elements.
4813 Call :meth:`RenumberElements` to remove the gaps.
4815 if ( isinstance( theObject, Mesh )):
4816 theObject = theObject.GetMesh()
4817 if theCriterion is None:
4818 theCriterion = FT_MaxElementLength2D
4819 Functor = self.smeshpyD.GetFunctor(theCriterion)
4820 return self.editor.QuadToTriObject(theObject, Functor)
4822 def QuadTo4Tri (self, theElements=[]):
4824 Split each of given quadrangles into 4 triangles. A node is added at the center of
4828 theElements: the faces to be splitted. This can be either
4829 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4830 or a list of face IDs. By default all quadrangles are split
4833 This operation can create gaps in numeration of elements.
4834 Call :meth:`RenumberElements` to remove the gaps.
4836 unRegister = genObjUnRegister()
4837 if isinstance( theElements, Mesh ):
4838 theElements = theElements.mesh
4839 elif not theElements:
4840 theElements = self.mesh
4841 elif isinstance( theElements, list ):
4842 theElements = self.GetIDSource( theElements, SMESH.FACE )
4843 unRegister.set( theElements )
4844 return self.editor.QuadTo4Tri( theElements )
4846 def SplitQuad (self, IDsOfElements, Diag13):
4848 Split quadrangles into triangles.
4851 IDsOfElements: the faces to be splitted
4852 Diag13 (boolean): is used to choose a diagonal for splitting.
4855 True in case of success, False otherwise.
4858 This operation can create gaps in numeration of elements.
4859 Call :meth:`RenumberElements` to remove the gaps.
4861 if IDsOfElements == []:
4862 IDsOfElements = self.GetElementsId()
4863 return self.editor.SplitQuad(IDsOfElements, Diag13)
4865 def SplitQuadObject (self, theObject, Diag13):
4867 Split quadrangles into triangles.
4870 theObject: the object from which the list of elements is taken,
4871 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4872 Diag13 (boolean): is used to choose a diagonal for splitting.
4875 True in case of success, False otherwise.
4878 This operation can create gaps in numeration of elements.
4879 Call :meth:`RenumberElements` to remove the gaps.
4881 if ( isinstance( theObject, Mesh )):
4882 theObject = theObject.GetMesh()
4883 return self.editor.SplitQuadObject(theObject, Diag13)
4885 def BestSplit (self, IDOfQuad, theCriterion):
4887 Find a better splitting of the given quadrangle.
4890 IDOfQuad: the ID of the quadrangle to be splitted.
4891 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4892 choose a diagonal for splitting.
4893 Note that not all items of :class:`SMESH.FunctorType` corresponds
4894 to numerical functors.
4897 * 1 if 1-3 diagonal is better,
4898 * 2 if 2-4 diagonal is better,
4899 * 0 if error occurs.
4902 This operation can create gaps in numeration of elements.
4903 Call :meth:`RenumberElements` to remove the gaps.
4905 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4907 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4909 Split volumic elements into tetrahedrons
4912 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4913 method: flags passing splitting method:
4914 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4915 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4918 This operation can create gaps in numeration of elements.
4919 Call :meth:`RenumberElements` to remove the gaps.
4921 unRegister = genObjUnRegister()
4922 if isinstance( elems, Mesh ):
4923 elems = elems.GetMesh()
4924 if ( isinstance( elems, list )):
4925 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4926 unRegister.set( elems )
4927 self.editor.SplitVolumesIntoTetra(elems, method)
4930 def SplitBiQuadraticIntoLinear(self, elems=None):
4932 Split bi-quadratic elements into linear ones without creation of additional nodes:
4934 - bi-quadratic triangle will be split into 3 linear quadrangles;
4935 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4936 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4938 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4939 will be split in order to keep the mesh conformal.
4942 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4943 if None (default), all bi-quadratic elements will be split
4946 This operation can create gaps in numeration of elements.
4947 Call :meth:`RenumberElements` to remove the gaps.
4949 unRegister = genObjUnRegister()
4950 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4951 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4952 unRegister.set( elems )
4954 elems = [ self.GetMesh() ]
4955 if isinstance( elems, Mesh ):
4956 elems = [ elems.GetMesh() ]
4957 if not isinstance( elems, list ):
4959 self.editor.SplitBiQuadraticIntoLinear( elems )
4961 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4962 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4964 Split hexahedra into prisms
4967 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4968 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4969 gives a normal vector defining facets to split into triangles.
4970 *startHexPoint* can be either a triple of coordinates or a vertex.
4971 facetNormal: a normal to a facet to split into triangles of a
4972 hexahedron found by *startHexPoint*.
4973 *facetNormal* can be either a triple of coordinates or an edge.
4974 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4975 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4976 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4977 to *startHexPoint* are split, else *startHexPoint*
4978 is used to find the facet to split in all domains present in *elems*.
4981 This operation can create gaps in numeration of elements.
4982 Call :meth:`RenumberElements` to remove the gaps.
4985 unRegister = genObjUnRegister()
4986 if isinstance( elems, Mesh ):
4987 elems = elems.GetMesh()
4988 if ( isinstance( elems, list )):
4989 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4990 unRegister.set( elems )
4993 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4994 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4995 elif isinstance( startHexPoint, list ):
4996 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4999 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5000 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5001 elif isinstance( facetNormal, list ):
5002 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5005 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5007 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5009 def SplitQuadsNearTriangularFacets(self):
5011 Split quadrangle faces near triangular facets of volumes
5014 This operation can create gaps in numeration of elements.
5015 Call :meth:`RenumberElements` to remove the gaps.
5017 faces_array = self.GetElementsByType(SMESH.FACE)
5018 for face_id in faces_array:
5019 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5020 quad_nodes = self.mesh.GetElemNodes(face_id)
5021 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5022 isVolumeFound = False
5023 for node1_elem in node1_elems:
5024 if not isVolumeFound:
5025 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5026 nb_nodes = self.GetElemNbNodes(node1_elem)
5027 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5028 volume_elem = node1_elem
5029 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5030 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5031 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5032 isVolumeFound = True
5033 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5034 self.SplitQuad([face_id], False) # diagonal 2-4
5035 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5036 isVolumeFound = True
5037 self.SplitQuad([face_id], True) # diagonal 1-3
5038 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5039 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5040 isVolumeFound = True
5041 self.SplitQuad([face_id], True) # diagonal 1-3
5043 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5045 Split hexahedrons into tetrahedrons.
5047 This operation uses :doc:`pattern_mapping` functionality for splitting.
5050 theObject: the object from which the list of hexahedrons is taken;
5051 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5052 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5053 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5054 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5055 key-point will be mapped into *theNode001*-th node of each volume.
5056 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5059 True in case of success, False otherwise.
5062 This operation can create gaps in numeration of elements.
5063 Call :meth:`RenumberElements` to remove the gaps.
5071 # (0,0,1) 4.---------.7 * |
5078 # (0,0,0) 0.---------.3
5079 pattern_tetra = "!!! Nb of points: \n 8 \n\
5089 !!! Indices of points of 6 tetras: \n\
5097 pattern = self.smeshpyD.GetPattern()
5098 isDone = pattern.LoadFromFile(pattern_tetra)
5100 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5103 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5104 isDone = pattern.MakeMesh(self.mesh, False, False)
5105 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5107 # split quafrangle faces near triangular facets of volumes
5108 self.SplitQuadsNearTriangularFacets()
5112 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5114 Split hexahedrons into prisms.
5116 Uses the :doc:`pattern_mapping` functionality for splitting.
5119 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5120 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5121 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5122 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5123 will be mapped into the *theNode001* -th node of each volume.
5124 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5127 True in case of success, False otherwise.
5130 This operation can create gaps in numeration of elements.
5131 Call :meth:`RenumberElements` to remove the gaps.
5133 # Pattern: 5.---------.6
5138 # (0,0,1) 4.---------.7 |
5145 # (0,0,0) 0.---------.3
5146 pattern_prism = "!!! Nb of points: \n 8 \n\
5156 !!! Indices of points of 2 prisms: \n\
5160 pattern = self.smeshpyD.GetPattern()
5161 isDone = pattern.LoadFromFile(pattern_prism)
5163 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5166 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5167 isDone = pattern.MakeMesh(self.mesh, False, False)
5168 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5170 # Split quafrangle faces near triangular facets of volumes
5171 self.SplitQuadsNearTriangularFacets()
5175 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5176 MaxNbOfIterations, MaxAspectRatio, Method):
5181 IDsOfElements: the list if ids of elements to smooth
5182 IDsOfFixedNodes: the list of ids of fixed nodes.
5183 Note that nodes built on edges and boundary nodes are always fixed.
5184 MaxNbOfIterations: the maximum number of iterations
5185 MaxAspectRatio: varies in range [1.0, inf]
5186 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5187 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5190 True in case of success, False otherwise.
5193 if IDsOfElements == []:
5194 IDsOfElements = self.GetElementsId()
5195 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5196 self.mesh.SetParameters(Parameters)
5197 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5198 MaxNbOfIterations, MaxAspectRatio, Method)
5200 def SmoothObject(self, theObject, IDsOfFixedNodes,
5201 MaxNbOfIterations, MaxAspectRatio, Method):
5203 Smooth elements which belong to the given object
5206 theObject: the object to smooth
5207 IDsOfFixedNodes: the list of ids of fixed nodes.
5208 Note that nodes built on edges and boundary nodes are always fixed.
5209 MaxNbOfIterations: the maximum number of iterations
5210 MaxAspectRatio: varies in range [1.0, inf]
5211 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5212 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5215 True in case of success, False otherwise.
5218 if ( isinstance( theObject, Mesh )):
5219 theObject = theObject.GetMesh()
5220 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5221 MaxNbOfIterations, MaxAspectRatio, Method)
5223 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5224 MaxNbOfIterations, MaxAspectRatio, Method):
5226 Parametrically smooth the given elements
5229 IDsOfElements: the list if ids of elements to smooth
5230 IDsOfFixedNodes: the list of ids of fixed nodes.
5231 Note that nodes built on edges and boundary nodes are always fixed.
5232 MaxNbOfIterations: the maximum number of iterations
5233 MaxAspectRatio: varies in range [1.0, inf]
5234 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5235 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5238 True in case of success, False otherwise.
5241 if IDsOfElements == []:
5242 IDsOfElements = self.GetElementsId()
5243 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5244 self.mesh.SetParameters(Parameters)
5245 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5246 MaxNbOfIterations, MaxAspectRatio, Method)
5248 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5249 MaxNbOfIterations, MaxAspectRatio, Method):
5251 Parametrically smooth the elements which belong to the given object
5254 theObject: the object to smooth
5255 IDsOfFixedNodes: the list of ids of fixed nodes.
5256 Note that nodes built on edges and boundary nodes are always fixed.
5257 MaxNbOfIterations: the maximum number of iterations
5258 MaxAspectRatio: varies in range [1.0, inf]
5259 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5260 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5263 True in case of success, False otherwise.
5266 if ( isinstance( theObject, Mesh )):
5267 theObject = theObject.GetMesh()
5268 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5269 MaxNbOfIterations, MaxAspectRatio, Method)
5271 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5273 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5274 them with quadratic with the same id.
5277 theForce3d: method of new node creation:
5279 * False - the medium node lies at the geometrical entity from which the mesh element is built
5280 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5281 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5282 theToBiQuad: If True, converts the mesh to bi-quadratic
5285 :class:`SMESH.ComputeError` which can hold a warning
5288 If *theSubMesh* is provided, the mesh can become non-conformal
5291 This operation can create gaps in numeration of nodes or elements.
5292 Call :meth:`RenumberElements` to remove the gaps.
5295 if isinstance( theSubMesh, Mesh ):
5296 theSubMesh = theSubMesh.mesh
5298 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5301 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5303 self.editor.ConvertToQuadratic(theForce3d)
5304 error = self.editor.GetLastError()
5305 if error and error.comment:
5306 print(error.comment)
5309 def ConvertFromQuadratic(self, theSubMesh=None):
5311 Convert the mesh from quadratic to ordinary,
5312 deletes old quadratic elements,
5313 replacing them with ordinary mesh elements with the same id.
5316 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5319 If *theSubMesh* is provided, the mesh can become non-conformal
5322 This operation can create gaps in numeration of nodes or elements.
5323 Call :meth:`RenumberElements` to remove the gaps.
5327 self.editor.ConvertFromQuadraticObject(theSubMesh)
5329 return self.editor.ConvertFromQuadratic()
5331 def Make2DMeshFrom3D(self):
5333 Create 2D mesh as skin on boundary faces of a 3D mesh
5336 True if operation has been completed successfully, False otherwise
5339 return self.editor.Make2DMeshFrom3D()
5341 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5342 toCopyElements=False, toCopyExistingBondary=False):
5344 Create missing boundary elements
5347 elements: elements whose boundary is to be checked:
5348 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5349 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5350 dimension: defines type of boundary elements to create, either of
5351 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5352 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5353 groupName: a name of group to store created boundary elements in,
5354 "" means not to create the group
5355 meshName: a name of new mesh to store created boundary elements in,
5356 "" means not to create the new mesh
5357 toCopyElements: if True, the checked elements will be copied into
5358 the new mesh else only boundary elements will be copied into the new mesh
5359 toCopyExistingBondary: if True, not only new but also pre-existing
5360 boundary elements will be copied into the new mesh
5363 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5366 unRegister = genObjUnRegister()
5367 if isinstance( elements, Mesh ):
5368 elements = elements.GetMesh()
5369 if ( isinstance( elements, list )):
5370 elemType = SMESH.ALL
5371 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5372 elements = self.editor.MakeIDSource(elements, elemType)
5373 unRegister.set( elements )
5374 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5375 toCopyElements,toCopyExistingBondary)
5376 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5379 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5380 toCopyAll=False, groups=[]):
5382 Create missing boundary elements around either the whole mesh or
5386 dimension: defines type of boundary elements to create, either of
5387 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5388 groupName: a name of group to store all boundary elements in,
5389 "" means not to create the group
5390 meshName: a name of a new mesh, which is a copy of the initial
5391 mesh + created boundary elements; "" means not to create the new mesh
5392 toCopyAll: if True, the whole initial mesh will be copied into
5393 the new mesh else only boundary elements will be copied into the new mesh
5394 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5397 tuple( long, mesh, group )
5398 - long - number of added boundary elements
5399 - mesh - the :class:`Mesh` where elements were added to
5400 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5403 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5405 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5406 return nb, mesh, group
5408 def RenumberNodes(self):
5410 Renumber mesh nodes to remove unused node IDs
5412 self.editor.RenumberNodes()
5414 def RenumberElements(self):
5416 Renumber mesh elements to remove unused element IDs
5418 self.editor.RenumberElements()
5420 def _getIdSourceList(self, arg, idType, unRegister):
5422 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5424 if arg and isinstance( arg, list ):
5425 if isinstance( arg[0], int ):
5426 arg = self.GetIDSource( arg, idType )
5427 unRegister.set( arg )
5428 elif isinstance( arg[0], Mesh ):
5429 arg[0] = arg[0].GetMesh()
5430 elif isinstance( arg, Mesh ):
5432 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5436 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5437 MakeGroups=False, TotalAngle=False):
5439 Generate new elements by rotation of the given elements and nodes around the axis
5442 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5443 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5444 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5445 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5446 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5447 which defines angle in degrees
5448 NbOfSteps: the number of steps
5449 Tolerance: tolerance
5450 MakeGroups: forces the generation of new groups from existing ones
5451 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5452 of all steps, else - size of each step
5455 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5458 unRegister = genObjUnRegister()
5459 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5460 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5461 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5463 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5464 Axis = self.smeshpyD.GetAxisStruct( Axis )
5465 if isinstance( Axis, list ):
5466 Axis = SMESH.AxisStruct( *Axis )
5468 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5469 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5470 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5471 self.mesh.SetParameters(Parameters)
5472 if TotalAngle and NbOfSteps:
5473 AngleInRadians /= NbOfSteps
5474 return self.editor.RotationSweepObjects( nodes, edges, faces,
5475 Axis, AngleInRadians,
5476 NbOfSteps, Tolerance, MakeGroups)
5478 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5479 MakeGroups=False, TotalAngle=False):
5481 Generate new elements by rotation of the elements around the axis
5484 IDsOfElements: the list of ids of elements to sweep
5485 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5486 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5487 NbOfSteps: the number of steps
5488 Tolerance: tolerance
5489 MakeGroups: forces the generation of new groups from existing ones
5490 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5491 of all steps, else - size of each step
5494 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5497 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5498 AngleInRadians, NbOfSteps, Tolerance,
5499 MakeGroups, TotalAngle)
5501 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5502 MakeGroups=False, TotalAngle=False):
5504 Generate new elements by rotation of the elements of object around the axis
5505 theObject object which elements should be sweeped.
5506 It can be a mesh, a sub mesh or a group.
5509 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5510 AngleInRadians: the angle of Rotation
5511 NbOfSteps: number of steps
5512 Tolerance: tolerance
5513 MakeGroups: forces the generation of new groups from existing ones
5514 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5515 of all steps, else - size of each step
5518 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5521 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5522 AngleInRadians, NbOfSteps, Tolerance,
5523 MakeGroups, TotalAngle )
5525 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5526 MakeGroups=False, TotalAngle=False):
5528 Generate new elements by rotation of the elements of object around the axis
5529 theObject object which elements should be sweeped.
5530 It can be a mesh, a sub mesh or a group.
5533 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5534 AngleInRadians: the angle of Rotation
5535 NbOfSteps: number of steps
5536 Tolerance: tolerance
5537 MakeGroups: forces the generation of new groups from existing ones
5538 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5539 of all steps, else - size of each step
5542 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5543 empty list otherwise
5546 return self.RotationSweepObjects([],theObject,[], Axis,
5547 AngleInRadians, NbOfSteps, Tolerance,
5548 MakeGroups, TotalAngle)
5550 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5551 MakeGroups=False, TotalAngle=False):
5553 Generate new elements by rotation of the elements of object around the axis
5554 theObject object which elements should be sweeped.
5555 It can be a mesh, a sub mesh or a group.
5558 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5559 AngleInRadians: the angle of Rotation
5560 NbOfSteps: number of steps
5561 Tolerance: tolerance
5562 MakeGroups: forces the generation of new groups from existing ones
5563 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5564 of all steps, else - size of each step
5567 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5570 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5571 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5573 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5574 scaleFactors=[], linearVariation=False, basePoint=[],
5575 angles=[], anglesVariation=False):
5577 Generate new elements by extrusion of the given elements and nodes
5580 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5581 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5582 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5583 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5584 the direction and value of extrusion for one step (the total extrusion
5585 length will be NbOfSteps * ||StepVector||)
5586 NbOfSteps: the number of steps
5587 MakeGroups: forces the generation of new groups from existing ones
5588 scaleFactors: optional scale factors to apply during extrusion
5589 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5590 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5591 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5592 nodes and elements being extruded is used as the scaling center.
5595 - a list of tree components of the point or
5598 angles: list of angles in radians. Nodes at each extrusion step are rotated
5599 around *basePoint*, additionally to previous steps.
5600 anglesVariation: forces the computation of rotation angles as linear
5601 variation of the given *angles* along path steps
5603 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5605 Example: :ref:`tui_extrusion`
5607 unRegister = genObjUnRegister()
5608 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5609 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5610 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5612 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5613 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5614 if isinstance( StepVector, list ):
5615 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5617 if isinstance( basePoint, int):
5618 xyz = self.GetNodeXYZ( basePoint )
5620 raise RuntimeError("Invalid node ID: %s" % basePoint)
5622 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5623 basePoint = self.geompyD.PointCoordinates( basePoint )
5625 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5626 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5627 angles,angleParameters,hasVars = ParseAngles(angles)
5628 Parameters = StepVector.PS.parameters + var_separator + \
5629 Parameters + var_separator + \
5630 scaleParameters + var_separator + angleParameters
5631 self.mesh.SetParameters(Parameters)
5633 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5634 StepVector, NbOfSteps, MakeGroups,
5635 scaleFactors, linearVariation, basePoint,
5636 angles, anglesVariation )
5639 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5641 Generate new elements by extrusion of the elements with given ids
5644 IDsOfElements: the list of ids of elements or nodes for extrusion
5645 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5646 the direction and value of extrusion for one step (the total extrusion
5647 length will be NbOfSteps * ||StepVector||)
5648 NbOfSteps: the number of steps
5649 MakeGroups: forces the generation of new groups from existing ones
5650 IsNodes: is True if elements with given ids are nodes
5653 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5655 Example: :ref:`tui_extrusion`
5658 if IsNodes: n = IDsOfElements
5659 else : e,f, = IDsOfElements,IDsOfElements
5660 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5662 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5663 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5665 Generate new elements by extrusion along the normal to a discretized surface or wire
5668 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5669 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5670 StepSize: length of one extrusion step (the total extrusion
5671 length will be *NbOfSteps* *StepSize*).
5672 NbOfSteps: number of extrusion steps.
5673 ByAverageNormal: if True each node is translated by *StepSize*
5674 along the average of the normal vectors to the faces sharing the node;
5675 else each node is translated along the same average normal till
5676 intersection with the plane got by translation of the face sharing
5677 the node along its own normal by *StepSize*.
5678 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5679 for every node of *Elements*.
5680 MakeGroups: forces generation of new groups from existing ones.
5681 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5682 is not yet implemented. This parameter is used if *Elements* contains
5683 both faces and edges, i.e. *Elements* is a Mesh.
5686 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5687 empty list otherwise.
5688 Example: :ref:`tui_extrusion`
5691 unRegister = genObjUnRegister()
5692 if isinstance( Elements, Mesh ):
5693 Elements = [ Elements.GetMesh() ]
5694 if isinstance( Elements, list ):
5696 raise RuntimeError("Elements empty!")
5697 if isinstance( Elements[0], Mesh ):
5698 Elements = [ Elements[0].GetMesh() ]
5699 if isinstance( Elements[0], int ):
5700 Elements = self.GetIDSource( Elements, SMESH.ALL )
5701 unRegister.set( Elements )
5702 if not isinstance( Elements, list ):
5703 Elements = [ Elements ]
5704 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5705 self.mesh.SetParameters(Parameters)
5706 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5707 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5709 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5711 Generate new elements by extrusion of the elements or nodes which belong to the object
5714 theObject: the object whose elements or nodes should be processed.
5715 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5716 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5717 the direction and value of extrusion for one step (the total extrusion
5718 length will be NbOfSteps * ||StepVector||)
5719 NbOfSteps: the number of steps
5720 MakeGroups: forces the generation of new groups from existing ones
5721 IsNodes: is True if elements to extrude are nodes
5724 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5725 Example: :ref:`tui_extrusion`
5729 if IsNodes: n = theObject
5730 else : e,f, = theObject,theObject
5731 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5733 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5735 Generate new elements by extrusion of edges which belong to the object
5738 theObject: object whose 1D elements should be processed.
5739 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5740 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5741 the direction and value of extrusion for one step (the total extrusion
5742 length will be NbOfSteps * ||StepVector||)
5743 NbOfSteps: the number of steps
5744 MakeGroups: to generate new groups from existing ones
5747 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5748 Example: :ref:`tui_extrusion`
5751 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5753 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5755 Generate new elements by extrusion of faces which belong to the object
5758 theObject: object whose 2D elements should be processed.
5759 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5760 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5761 the direction and value of extrusion for one step (the total extrusion
5762 length will be NbOfSteps * ||StepVector||)
5763 NbOfSteps: the number of steps
5764 MakeGroups: forces the generation of new groups from existing ones
5767 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5768 Example: :ref:`tui_extrusion`
5771 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5773 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5774 ExtrFlags, SewTolerance, MakeGroups=False):
5776 Generate new elements by extrusion of the elements with given ids
5779 IDsOfElements: is ids of elements
5780 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5781 the direction and value of extrusion for one step (the total extrusion
5782 length will be NbOfSteps * ||StepVector||)
5783 NbOfSteps: the number of steps
5784 ExtrFlags: sets flags for extrusion
5785 SewTolerance: uses for comparing locations of nodes if flag
5786 EXTRUSION_FLAG_SEW is set
5787 MakeGroups: forces the generation of new groups from existing ones
5790 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5793 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5794 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5795 if isinstance( StepVector, list ):
5796 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5797 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5798 ExtrFlags, SewTolerance, MakeGroups)
5800 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5801 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5802 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5803 ScaleFactors=[], ScalesVariation=False):
5805 Generate new elements by extrusion of the given elements and nodes along the path.
5806 The path of extrusion must be a meshed edge.
5809 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5810 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5811 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5812 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5813 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
5814 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5815 HasAngles: not used obsolete
5816 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5817 around *basePoint*, additionally to previous steps.
5818 LinearVariation: forces the computation of rotation angles as linear
5819 variation of the given Angles along path steps
5820 HasRefPoint: allows using the reference point
5821 RefPoint: optional scaling and rotation center (mass center of the extruded
5822 elements by default). The User can specify any point as the Reference Point.
5823 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5824 MakeGroups: forces the generation of new groups from existing ones
5825 ScaleFactors: optional scale factors to apply during extrusion
5826 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5827 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5830 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5831 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5832 Example: :ref:`tui_extrusion_along_path`
5835 unRegister = genObjUnRegister()
5836 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5837 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5838 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5840 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5841 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5842 if isinstance( RefPoint, list ):
5843 if not RefPoint: RefPoint = [0,0,0]
5844 RefPoint = SMESH.PointStruct( *RefPoint )
5845 if isinstance( PathObject, Mesh ):
5846 PathObject = PathObject.GetMesh()
5847 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5848 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5849 Parameters = AnglesParameters + var_separator + \
5850 RefPoint.parameters + var_separator + ScalesParameters
5851 self.mesh.SetParameters(Parameters)
5852 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5853 PathObject, PathShape, NodeStart,
5854 HasAngles, Angles, LinearVariation,
5855 HasRefPoint, RefPoint, MakeGroups,
5856 ScaleFactors, ScalesVariation)
5858 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5859 HasAngles=False, Angles=[], LinearVariation=False,
5860 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5861 ElemType=SMESH.FACE):
5863 Generate new elements by extrusion of the given elements.
5864 The path of extrusion must be a meshed edge.
5867 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5868 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5869 NodeStart: the start node from Path. Defines the direction of extrusion
5870 HasAngles: not used obsolete
5871 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5872 around *basePoint*, additionally to previous steps.
5873 LinearVariation: forces the computation of rotation angles as linear
5874 variation of the given Angles along path steps
5875 HasRefPoint: allows using the reference point
5876 RefPoint: the reference point around which the elements are rotated (the mass
5877 center of the elements by default).
5878 The User can specify any point as the Reference Point.
5879 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5880 MakeGroups: forces the generation of new groups from existing ones
5881 ElemType: type of elements for extrusion (if param Base is a mesh)
5884 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5885 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5886 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5888 Example: :ref:`tui_extrusion_along_path`
5892 if ElemType == SMESH.NODE: n = Base
5893 if ElemType == SMESH.EDGE: e = Base
5894 if ElemType == SMESH.FACE: f = Base
5895 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5896 HasAngles, Angles, LinearVariation,
5897 HasRefPoint, RefPoint, MakeGroups)
5898 if MakeGroups: return gr,er
5901 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5902 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5903 MakeGroups=False, LinearVariation=False):
5905 Generate new elements by extrusion of the given elements.
5906 The path of extrusion must be a meshed edge.
5909 IDsOfElements: ids of elements
5910 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5911 PathShape: shape (edge) defines the sub-mesh for the path
5912 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5913 HasAngles: not used obsolete
5914 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5915 around *basePoint*, additionally to previous steps.
5916 HasRefPoint: allows using the reference point
5917 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5918 The User can specify any point as the Reference Point.
5919 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5920 MakeGroups: forces the generation of new groups from existing ones
5921 LinearVariation: forces the computation of rotation angles as linear
5922 variation of the given Angles along path steps
5925 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5926 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5927 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5928 Example: :ref:`tui_extrusion_along_path`
5931 if not IDsOfElements:
5932 IDsOfElements = [ self.GetMesh() ]
5933 n,e,f = [],IDsOfElements,IDsOfElements
5934 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5935 NodeStart, HasAngles, Angles,
5937 HasRefPoint, RefPoint, MakeGroups)
5938 if MakeGroups: return gr,er
5941 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5942 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5943 MakeGroups=False, LinearVariation=False):
5945 Generate new elements by extrusion of the elements which belong to the object.
5946 The path of extrusion must be a meshed edge.
5949 theObject: the object whose elements should be processed.
5950 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5951 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5952 PathShape: shape (edge) defines the sub-mesh for the path
5953 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5954 HasAngles: not used obsolete
5955 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5956 around *basePoint*, additionally to previous steps.
5957 HasRefPoint: allows using the reference point
5958 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5959 The User can specify any point as the Reference Point.
5960 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5961 MakeGroups: forces the generation of new groups from existing ones
5962 LinearVariation: forces the computation of rotation angles as linear
5963 variation of the given Angles along path steps
5966 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5967 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5968 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5969 Example: :ref:`tui_extrusion_along_path`
5972 n,e,f = [],theObject,theObject
5973 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5974 HasAngles, Angles, LinearVariation,
5975 HasRefPoint, RefPoint, MakeGroups)
5976 if MakeGroups: return gr,er
5979 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5980 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5981 MakeGroups=False, LinearVariation=False):
5983 Generate new elements by extrusion of mesh segments which belong to the object.
5984 The path of extrusion must be a meshed edge.
5987 theObject: the object whose 1D elements should be processed.
5988 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5989 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5990 PathShape: shape (edge) defines the sub-mesh for the path
5991 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5992 HasAngles: not used obsolete
5993 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5994 around *basePoint*, additionally to previous steps.
5995 HasRefPoint: allows using the reference point
5996 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5997 The User can specify any point as the Reference Point.
5998 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5999 MakeGroups: forces the generation of new groups from existing ones
6000 LinearVariation: forces the computation of rotation angles as linear
6001 variation of the given Angles along path steps
6004 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6005 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6006 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6007 Example: :ref:`tui_extrusion_along_path`
6010 n,e,f = [],theObject,[]
6011 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6012 HasAngles, Angles, LinearVariation,
6013 HasRefPoint, RefPoint, MakeGroups)
6014 if MakeGroups: return gr,er
6017 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6018 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6019 MakeGroups=False, LinearVariation=False):
6021 Generate new elements by extrusion of faces which belong to the object.
6022 The path of extrusion must be a meshed edge.
6025 theObject: the object whose 2D elements should be processed.
6026 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6027 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6028 PathShape: shape (edge) defines the sub-mesh for the path
6029 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6030 HasAngles: not used obsolete
6031 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6032 around *basePoint*, additionally to previous steps.
6033 HasRefPoint: allows using the reference point
6034 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6035 The User can specify any point as the Reference Point.
6036 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6037 MakeGroups: forces the generation of new groups from existing ones
6038 LinearVariation: forces the computation of rotation angles as linear
6039 variation of the given Angles along path steps
6042 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6043 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6044 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6045 Example: :ref:`tui_extrusion_along_path`
6048 n,e,f = [],[],theObject
6049 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6050 HasAngles, Angles, LinearVariation,
6051 HasRefPoint, RefPoint, MakeGroups)
6052 if MakeGroups: return gr,er
6055 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6057 Create a symmetrical copy of mesh elements
6060 IDsOfElements: list of elements ids
6061 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6062 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6063 If the *Mirror* is a geom object this parameter is unnecessary
6064 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6065 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6068 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6071 if IDsOfElements == []:
6072 IDsOfElements = self.GetElementsId()
6073 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6074 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6075 theMirrorType = Mirror._mirrorType
6077 self.mesh.SetParameters(Mirror.parameters)
6078 if Copy and MakeGroups:
6079 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6080 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6083 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6085 Create a new mesh by a symmetrical copy of mesh elements
6088 IDsOfElements: the list of elements ids
6089 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6090 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6091 If the *Mirror* is a geom object this parameter is unnecessary
6092 MakeGroups: to generate new groups from existing ones
6093 NewMeshName: a name of the new mesh to create
6096 instance of class :class:`Mesh`
6099 if IDsOfElements == []:
6100 IDsOfElements = self.GetElementsId()
6101 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6102 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6103 theMirrorType = Mirror._mirrorType
6105 self.mesh.SetParameters(Mirror.parameters)
6106 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6107 MakeGroups, NewMeshName)
6108 return Mesh(self.smeshpyD,self.geompyD,mesh)
6110 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6112 Create a symmetrical copy of the object
6115 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6116 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6117 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6118 If the *Mirror* is a geom object this parameter is unnecessary
6119 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6120 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6123 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6126 if ( isinstance( theObject, Mesh )):
6127 theObject = theObject.GetMesh()
6128 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6129 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6130 theMirrorType = Mirror._mirrorType
6132 self.mesh.SetParameters(Mirror.parameters)
6133 if Copy and MakeGroups:
6134 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6135 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6138 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6140 Create a new mesh by a symmetrical copy of the object
6143 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6144 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6145 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6146 If the *Mirror* is a geom object this parameter is unnecessary
6147 MakeGroups: forces the generation of new groups from existing ones
6148 NewMeshName: the name of the new mesh to create
6151 instance of class :class:`Mesh`
6154 if ( isinstance( theObject, Mesh )):
6155 theObject = theObject.GetMesh()
6156 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6157 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6158 theMirrorType = Mirror._mirrorType
6160 self.mesh.SetParameters(Mirror.parameters)
6161 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6162 MakeGroups, NewMeshName)
6163 return Mesh( self.smeshpyD,self.geompyD,mesh )
6165 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6167 Translate the elements
6170 IDsOfElements: list of elements ids
6171 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6172 Copy: allows copying the translated elements
6173 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6176 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6179 if IDsOfElements == []:
6180 IDsOfElements = self.GetElementsId()
6181 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6182 Vector = self.smeshpyD.GetDirStruct(Vector)
6183 if isinstance( Vector, list ):
6184 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6185 self.mesh.SetParameters(Vector.PS.parameters)
6186 if Copy and MakeGroups:
6187 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6188 self.editor.Translate(IDsOfElements, Vector, Copy)
6191 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6193 Create a new mesh of translated elements
6196 IDsOfElements: list of elements ids
6197 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6198 MakeGroups: forces the generation of new groups from existing ones
6199 NewMeshName: the name of the newly created mesh
6202 instance of class :class:`Mesh`
6205 if IDsOfElements == []:
6206 IDsOfElements = self.GetElementsId()
6207 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6208 Vector = self.smeshpyD.GetDirStruct(Vector)
6209 if isinstance( Vector, list ):
6210 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6211 self.mesh.SetParameters(Vector.PS.parameters)
6212 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6213 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6215 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6217 Translate the object
6220 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6221 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6222 Copy: allows copying the translated elements
6223 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6226 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6229 if ( isinstance( theObject, Mesh )):
6230 theObject = theObject.GetMesh()
6231 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6232 Vector = self.smeshpyD.GetDirStruct(Vector)
6233 if isinstance( Vector, list ):
6234 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6235 self.mesh.SetParameters(Vector.PS.parameters)
6236 if Copy and MakeGroups:
6237 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6238 self.editor.TranslateObject(theObject, Vector, Copy)
6241 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6243 Create a new mesh from the translated object
6246 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6247 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6248 MakeGroups: forces the generation of new groups from existing ones
6249 NewMeshName: the name of the newly created mesh
6252 instance of class :class:`Mesh`
6255 if isinstance( theObject, Mesh ):
6256 theObject = theObject.GetMesh()
6257 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6258 Vector = self.smeshpyD.GetDirStruct(Vector)
6259 if isinstance( Vector, list ):
6260 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6261 self.mesh.SetParameters(Vector.PS.parameters)
6262 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6263 return Mesh( self.smeshpyD, self.geompyD, mesh )
6267 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6272 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6273 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6274 theScaleFact: list of 1-3 scale factors for axises
6275 Copy: allows copying the translated elements
6276 MakeGroups: forces the generation of new groups from existing
6280 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6281 empty list otherwise
6283 unRegister = genObjUnRegister()
6284 if ( isinstance( theObject, Mesh )):
6285 theObject = theObject.GetMesh()
6286 if ( isinstance( theObject, list )):
6287 theObject = self.GetIDSource(theObject, SMESH.ALL)
6288 unRegister.set( theObject )
6289 if ( isinstance( thePoint, list )):
6290 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6291 if ( isinstance( theScaleFact, float )):
6292 theScaleFact = [theScaleFact]
6293 if ( isinstance( theScaleFact, int )):
6294 theScaleFact = [ float(theScaleFact)]
6296 self.mesh.SetParameters(thePoint.parameters)
6298 if Copy and MakeGroups:
6299 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6300 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6303 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6305 Create a new mesh from the translated object
6308 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6309 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6310 theScaleFact: list of 1-3 scale factors for axises
6311 MakeGroups: forces the generation of new groups from existing ones
6312 NewMeshName: the name of the newly created mesh
6315 instance of class :class:`Mesh`
6317 unRegister = genObjUnRegister()
6318 if (isinstance(theObject, Mesh)):
6319 theObject = theObject.GetMesh()
6320 if ( isinstance( theObject, list )):
6321 theObject = self.GetIDSource(theObject,SMESH.ALL)
6322 unRegister.set( theObject )
6323 if ( isinstance( thePoint, list )):
6324 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6325 if ( isinstance( theScaleFact, float )):
6326 theScaleFact = [theScaleFact]
6327 if ( isinstance( theScaleFact, int )):
6328 theScaleFact = [ float(theScaleFact)]
6330 self.mesh.SetParameters(thePoint.parameters)
6331 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6332 MakeGroups, NewMeshName)
6333 return Mesh( self.smeshpyD, self.geompyD, mesh )
6337 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6342 IDsOfElements: list of elements ids
6343 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6344 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6345 Copy: allows copying the rotated elements
6346 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6349 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6353 if IDsOfElements == []:
6354 IDsOfElements = self.GetElementsId()
6355 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6356 Axis = self.smeshpyD.GetAxisStruct(Axis)
6357 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6358 Parameters = Axis.parameters + var_separator + Parameters
6359 self.mesh.SetParameters(Parameters)
6360 if Copy and MakeGroups:
6361 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6362 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6365 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6367 Create a new mesh of rotated elements
6370 IDsOfElements: list of element ids
6371 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6372 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6373 MakeGroups: forces the generation of new groups from existing ones
6374 NewMeshName: the name of the newly created mesh
6377 instance of class :class:`Mesh`
6380 if IDsOfElements == []:
6381 IDsOfElements = self.GetElementsId()
6382 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6383 Axis = self.smeshpyD.GetAxisStruct(Axis)
6384 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6385 Parameters = Axis.parameters + var_separator + Parameters
6386 self.mesh.SetParameters(Parameters)
6387 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6388 MakeGroups, NewMeshName)
6389 return Mesh( self.smeshpyD, self.geompyD, mesh )
6391 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6396 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6397 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6398 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6399 Copy: allows copying the rotated elements
6400 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6403 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6406 if (isinstance(theObject, Mesh)):
6407 theObject = theObject.GetMesh()
6408 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6409 Axis = self.smeshpyD.GetAxisStruct(Axis)
6410 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6411 Parameters = Axis.parameters + ":" + Parameters
6412 self.mesh.SetParameters(Parameters)
6413 if Copy and MakeGroups:
6414 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6415 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6418 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6420 Create a new mesh from the rotated object
6423 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6424 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6425 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6426 MakeGroups: forces the generation of new groups from existing ones
6427 NewMeshName: the name of the newly created mesh
6430 instance of class :class:`Mesh`
6433 if (isinstance( theObject, Mesh )):
6434 theObject = theObject.GetMesh()
6435 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6436 Axis = self.smeshpyD.GetAxisStruct(Axis)
6437 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6438 Parameters = Axis.parameters + ":" + Parameters
6439 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6440 MakeGroups, NewMeshName)
6441 self.mesh.SetParameters(Parameters)
6442 return Mesh( self.smeshpyD, self.geompyD, mesh )
6444 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6446 Create an offset mesh from the given 2D object
6449 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6450 theValue (float): signed offset size
6451 MakeGroups (boolean): forces the generation of new groups from existing ones
6452 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6453 False means to remove original elements.
6454 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6457 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6460 if isinstance( theObject, Mesh ):
6461 theObject = theObject.GetMesh()
6462 theValue,Parameters,hasVars = ParseParameters(Value)
6463 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6464 self.mesh.SetParameters(Parameters)
6466 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6469 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6471 Find groups of adjacent nodes within Tolerance.
6474 Tolerance (float): the value of tolerance
6475 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6476 corner and medium nodes in separate groups thus preventing
6477 their further merge.
6480 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6483 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6485 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6486 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6488 Find groups of adjacent nodes within Tolerance.
6491 Tolerance: the value of tolerance
6492 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6493 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6494 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6495 corner and medium nodes in separate groups thus preventing
6496 their further merge.
6499 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6502 unRegister = genObjUnRegister()
6503 if not isinstance( SubMeshOrGroup, list ):
6504 SubMeshOrGroup = [ SubMeshOrGroup ]
6505 for i,obj in enumerate( SubMeshOrGroup ):
6506 if isinstance( obj, Mesh ):
6507 SubMeshOrGroup = [ obj.GetMesh() ]
6509 if isinstance( obj, int ):
6510 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6511 unRegister.set( SubMeshOrGroup )
6514 if not isinstance( exceptNodes, list ):
6515 exceptNodes = [ exceptNodes ]
6516 if exceptNodes and isinstance( exceptNodes[0], int ):
6517 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6518 unRegister.set( exceptNodes )
6520 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6521 exceptNodes, SeparateCornerAndMediumNodes)
6523 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6528 GroupsOfNodes: a list of groups of nodes IDs for merging.
6529 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6530 in all elements and mesh groups by nodes 1 and 25 correspondingly
6531 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6532 If *NodesToKeep* does not include a node to keep for some group to merge,
6533 then the first node in the group is kept.
6534 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6538 This operation can create gaps in numeration of nodes or elements.
6539 Call :meth:`RenumberElements` to remove the gaps.
6541 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6543 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6545 Find the elements built on the same nodes.
6548 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6549 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6553 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6556 unRegister = genObjUnRegister()
6557 if MeshOrSubMeshOrGroup is None:
6558 MeshOrSubMeshOrGroup = [ self.mesh ]
6559 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6560 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6561 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6562 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6563 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6564 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6565 unRegister.set( MeshOrSubMeshOrGroup )
6566 for item in MeshOrSubMeshOrGroup:
6567 if isinstance( item, Mesh ):
6568 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6570 if not isinstance( exceptElements, list ):
6571 exceptElements = [ exceptElements ]
6572 if exceptElements and isinstance( exceptElements[0], int ):
6573 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6574 unRegister.set( exceptElements )
6576 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6578 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6580 Merge elements in each given group.
6583 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6584 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6585 replaced in all mesh groups by elements 1 and 25)
6586 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6587 If *ElementsToKeep* does not include an element to keep for some group to merge,
6588 then the first element in the group is kept.
6591 This operation can create gaps in numeration of elements.
6592 Call :meth:`RenumberElements` to remove the gaps.
6595 unRegister = genObjUnRegister()
6597 if not isinstance( ElementsToKeep, list ):
6598 ElementsToKeep = [ ElementsToKeep ]
6599 if isinstance( ElementsToKeep[0], int ):
6600 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6601 unRegister.set( ElementsToKeep )
6603 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6605 def MergeEqualElements(self):
6607 Leave one element and remove all other elements built on the same nodes.
6610 This operation can create gaps in numeration of elements.
6611 Call :meth:`RenumberElements` to remove the gaps.
6614 self.editor.MergeEqualElements()
6616 def FindFreeBorders(self, ClosedOnly=True):
6618 Returns all or only closed free borders
6621 list of SMESH.FreeBorder's
6624 return self.editor.FindFreeBorders( ClosedOnly )
6626 def FillHole(self, holeNodes, groupName=""):
6628 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6631 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6632 must describe all sequential nodes of the hole border. The first and the last
6633 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6634 groupName (string): name of a group to add new faces
6636 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6640 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6641 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6642 if not isinstance( holeNodes, SMESH.FreeBorder ):
6643 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6644 return self.editor.FillHole( holeNodes, groupName )
6646 def FindCoincidentFreeBorders (self, tolerance=0.):
6648 Return groups of FreeBorder's coincident within the given tolerance.
6651 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6652 size of elements adjacent to free borders being compared is used.
6655 SMESH.CoincidentFreeBorders structure
6658 return self.editor.FindCoincidentFreeBorders( tolerance )
6660 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6662 Sew FreeBorder's of each group
6665 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6666 where each enclosed list contains node IDs of a group of coincident free
6667 borders such that each consequent triple of IDs within a group describes
6668 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6669 last node of a border.
6670 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6671 groups of coincident free borders, each group including two borders.
6672 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6673 polygons if a node of opposite border falls on a face edge, else such
6674 faces are split into several ones.
6675 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6676 polyhedra if a node of opposite border falls on a volume edge, else such
6677 volumes, if any, remain intact and the mesh becomes non-conformal.
6680 a number of successfully sewed groups
6683 This operation can create gaps in numeration of nodes or elements.
6684 Call :meth:`RenumberElements` to remove the gaps.
6687 if freeBorders and isinstance( freeBorders, list ):
6688 # construct SMESH.CoincidentFreeBorders
6689 if isinstance( freeBorders[0], int ):
6690 freeBorders = [freeBorders]
6692 coincidentGroups = []
6693 for nodeList in freeBorders:
6694 if not nodeList or len( nodeList ) % 3:
6695 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6698 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6699 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6700 nodeList = nodeList[3:]
6702 coincidentGroups.append( group )
6704 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6706 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6708 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6709 FirstNodeID2, SecondNodeID2, LastNodeID2,
6710 CreatePolygons, CreatePolyedrs):
6715 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6718 This operation can create gaps in numeration of nodes or elements.
6719 Call :meth:`RenumberElements` to remove the gaps.
6722 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6723 FirstNodeID2, SecondNodeID2, LastNodeID2,
6724 CreatePolygons, CreatePolyedrs)
6726 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6727 FirstNodeID2, SecondNodeID2):
6729 Sew conform free borders
6732 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6735 This operation can create gaps in numeration of elements.
6736 Call :meth:`RenumberElements` to remove the gaps.
6739 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6740 FirstNodeID2, SecondNodeID2)
6742 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6743 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6748 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6751 This operation can create gaps in numeration of elements.
6752 Call :meth:`RenumberElements` to remove the gaps.
6755 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6756 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6758 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6759 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6760 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6762 Sew two sides of a mesh. The nodes belonging to Side1 are
6763 merged with the nodes of elements of Side2.
6764 The number of elements in theSide1 and in theSide2 must be
6765 equal and they should have similar nodal connectivity.
6766 The nodes to merge should belong to side borders and
6767 the first node should be linked to the second.
6770 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6773 This operation can create gaps in numeration of nodes.
6774 Call :meth:`RenumberElements` to remove the gaps.
6777 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6778 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6779 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6781 def ChangeElemNodes(self, ide, newIDs):
6783 Set new nodes for the given element. Number of nodes should be kept.
6790 False if the number of nodes does not correspond to the type of element
6793 return self.editor.ChangeElemNodes(ide, newIDs)
6795 def GetLastCreatedNodes(self):
6797 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6798 created, this method return the list of their IDs.
6799 If new nodes were not created - return empty list
6802 the list of integer values (can be empty)
6805 return self.editor.GetLastCreatedNodes()
6807 def GetLastCreatedElems(self):
6809 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6810 created this method return the list of their IDs.
6811 If new elements were not created - return empty list
6814 the list of integer values (can be empty)
6817 return self.editor.GetLastCreatedElems()
6819 def ClearLastCreated(self):
6821 Forget what nodes and elements were created by the last mesh edition operation
6824 self.editor.ClearLastCreated()
6826 def DoubleElements(self, theElements, theGroupName=""):
6828 Create duplicates of given elements, i.e. create new elements based on the
6829 same nodes as the given ones.
6832 theElements: container of elements to duplicate. It can be a
6833 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6834 or a list of element IDs. If *theElements* is
6835 a :class:`Mesh`, elements of highest dimension are duplicated
6836 theGroupName: a name of group to contain the generated elements.
6837 If a group with such a name already exists, the new elements
6838 are added to the existing group, else a new group is created.
6839 If *theGroupName* is empty, new elements are not added
6843 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6844 None if *theGroupName* == "".
6847 unRegister = genObjUnRegister()
6848 if isinstance( theElements, Mesh ):
6849 theElements = theElements.mesh
6850 elif isinstance( theElements, list ):
6851 theElements = self.GetIDSource( theElements, SMESH.ALL )
6852 unRegister.set( theElements )
6853 return self.editor.DoubleElements(theElements, theGroupName)
6855 def DoubleNodes(self, theNodes, theModifiedElems):
6857 Create a hole in a mesh by doubling the nodes of some particular elements
6860 theNodes: IDs of nodes to be doubled
6861 theModifiedElems: IDs of elements to be updated by the new (doubled)
6862 nodes. If list of element identifiers is empty then nodes are doubled but
6863 they not assigned to elements
6866 True if operation has been completed successfully, False otherwise
6869 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6871 def DoubleNode(self, theNodeId, theModifiedElems):
6873 Create a hole in a mesh by doubling the nodes of some particular elements.
6874 This method provided for convenience works as :meth:`DoubleNodes`.
6877 theNodeId: IDs of node to double
6878 theModifiedElems: IDs of elements to update
6881 True if operation has been completed successfully, False otherwise
6884 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6886 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6888 Create a hole in a mesh by doubling the nodes of some particular elements.
6889 This method provided for convenience works as :meth:`DoubleNodes`.
6892 theNodes: group of nodes to double.
6893 theModifiedElems: group of elements to update.
6894 theMakeGroup: forces the generation of a group containing new nodes.
6897 True or a created group if operation has been completed successfully,
6898 False or None otherwise
6902 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6903 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6905 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6907 Create a hole in a mesh by doubling the nodes of some particular elements.
6908 This method provided for convenience works as :meth:`DoubleNodes`.
6911 theNodes: list of groups of nodes to double.
6912 theModifiedElems: list of groups of elements to update.
6913 theMakeGroup: forces the generation of a group containing new nodes.
6916 True if operation has been completed successfully, False otherwise
6920 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6921 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6923 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6925 Create a hole in a mesh by doubling the nodes of some particular elements
6928 theElems: the list of elements (edges or faces) to replicate.
6929 The nodes for duplication could be found from these elements
6930 theNodesNot: list of nodes NOT to replicate
6931 theAffectedElems: the list of elements (cells and edges) to which the
6932 replicated nodes should be associated to
6935 True if operation has been completed successfully, False otherwise
6938 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6940 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6942 Create a hole in a mesh by doubling the nodes of some particular elements
6945 theElems: the list of elements (edges or faces) to replicate.
6946 The nodes for duplication could be found from these elements
6947 theNodesNot: list of nodes NOT to replicate
6948 theShape: shape to detect affected elements (element which geometric center
6949 located on or inside shape).
6950 The replicated nodes should be associated to affected elements.
6953 True if operation has been completed successfully, False otherwise
6956 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6958 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6959 theMakeGroup=False, theMakeNodeGroup=False):
6961 Create a hole in a mesh by doubling the nodes of some particular elements.
6962 This method provided for convenience works as :meth:`DoubleNodes`.
6965 theElems: group of of elements (edges or faces) to replicate.
6966 theNodesNot: group of nodes NOT to replicate.
6967 theAffectedElems: group of elements to which the replicated nodes
6968 should be associated to.
6969 theMakeGroup: forces the generation of a group containing new elements.
6970 theMakeNodeGroup: forces the generation of a group containing new nodes.
6973 True or created groups (one or two) if operation has been completed successfully,
6974 False or None otherwise
6977 if theMakeGroup or theMakeNodeGroup:
6978 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6980 theMakeGroup, theMakeNodeGroup)
6981 if theMakeGroup and theMakeNodeGroup:
6984 return twoGroups[ int(theMakeNodeGroup) ]
6985 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6987 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6989 Create a hole in a mesh by doubling the nodes of some particular elements.
6990 This method provided for convenience works as :meth:`DoubleNodes`.
6993 theElems: group of of elements (edges or faces) to replicate
6994 theNodesNot: group of nodes not to replicate
6995 theShape: shape to detect affected elements (element which geometric center
6996 located on or inside shape).
6997 The replicated nodes should be associated to affected elements
7000 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7002 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7003 theMakeGroup=False, theMakeNodeGroup=False):
7005 Create a hole in a mesh by doubling the nodes of some particular elements.
7006 This method provided for convenience works as :meth:`DoubleNodes`.
7009 theElems: list of groups of elements (edges or faces) to replicate
7010 theNodesNot: list of groups of nodes NOT to replicate
7011 theAffectedElems: group of elements to which the replicated nodes
7012 should be associated to
7013 theMakeGroup: forces generation of a group containing new elements.
7014 theMakeNodeGroup: forces generation of a group containing new nodes
7017 True or created groups (one or two) if operation has been completed successfully,
7018 False or None otherwise
7021 if theMakeGroup or theMakeNodeGroup:
7022 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7024 theMakeGroup, theMakeNodeGroup)
7025 if theMakeGroup and theMakeNodeGroup:
7028 return twoGroups[ int(theMakeNodeGroup) ]
7029 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7031 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7033 Create a hole in a mesh by doubling the nodes of some particular elements.
7034 This method provided for convenience works as :meth:`DoubleNodes`.
7037 theElems: list of groups of elements (edges or faces) to replicate
7038 theNodesNot: list of groups of nodes NOT to replicate
7039 theShape: shape to detect affected elements (element which geometric center
7040 located on or inside shape).
7041 The replicated nodes should be associated to affected elements
7044 True if operation has been completed successfully, False otherwise
7047 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7049 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7051 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7052 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7055 theElems: list of groups of nodes or elements (edges or faces) to replicate
7056 theNodesNot: list of groups of nodes NOT to replicate
7057 theShape: shape to detect affected elements (element which geometric center
7058 located on or inside shape).
7059 The replicated nodes should be associated to affected elements
7062 groups of affected elements in order: volumes, faces, edges
7065 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7067 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7070 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7071 The list of groups must describe a partition of the mesh volumes.
7072 The nodes of the internal faces at the boundaries of the groups are doubled.
7073 In option, the internal faces are replaced by flat elements.
7074 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7077 theDomains: list of groups of volumes
7078 createJointElems: if True, create the elements
7079 onAllBoundaries: if True, the nodes and elements are also created on
7080 the boundary between *theDomains* and the rest mesh
7083 True if operation has been completed successfully, False otherwise
7086 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7088 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7090 Double nodes on some external faces and create flat elements.
7091 Flat elements are mainly used by some types of mechanic calculations.
7093 Each group of the list must be constituted of faces.
7094 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7097 theGroupsOfFaces: list of groups of faces
7100 True if operation has been completed successfully, False otherwise
7103 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7105 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7107 Identify all the elements around a geom shape, get the faces delimiting the hole
7109 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7111 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7113 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7114 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7115 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7116 If there are several paths connecting a pair of points, the shortest path is
7117 selected by the module. Position of the cutting plane is defined by the two
7118 points and an optional vector lying on the plane specified by a PolySegment.
7119 By default the vector is defined by Mesh module as following. A middle point
7120 of the two given points is computed. The middle point is projected to the mesh.
7121 The vector goes from the middle point to the projection point. In case of planar
7122 mesh, the vector is normal to the mesh.
7124 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7127 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7128 groupName: optional name of a group where created mesh segments will be added.
7131 editor = self.editor
7133 editor = self.mesh.GetMeshEditPreviewer()
7134 segmentsRes = editor.MakePolyLine( segments, groupName )
7135 for i, seg in enumerate( segmentsRes ):
7136 segments[i].vector = seg.vector
7138 return editor.GetPreviewData()
7141 def MakeSlot(self, segmentGroup, width ):
7143 Create a slot of given width around given 1D elements lying on a triangle mesh.
7144 The slot is constructed by cutting faces by cylindrical surfaces made
7145 around each segment. Segments are expected to be created by MakePolyLine().
7148 FaceEdge's located at the slot boundary
7150 return self.editor.MakeSlot( segmentGroup, width )
7152 def GetFunctor(self, funcType ):
7154 Return a cached numerical functor by its type.
7157 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7158 Note that not all items correspond to numerical functors.
7161 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7164 fn = self.functors[ funcType._v ]
7166 fn = self.smeshpyD.GetFunctor(funcType)
7167 fn.SetMesh(self.mesh)
7168 self.functors[ funcType._v ] = fn
7171 def FunctorValue(self, funcType, elemId, isElem=True):
7173 Return value of a functor for a given element
7176 funcType: an item of :class:`SMESH.FunctorType` enum.
7177 elemId: element or node ID
7178 isElem: *elemId* is ID of element or node
7181 the functor value or zero in case of invalid arguments
7184 fn = self.GetFunctor( funcType )
7185 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7186 val = fn.GetValue(elemId)
7191 def GetLength(self, elemId=None):
7193 Get length of given 1D elements or of all 1D mesh elements
7196 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.
7199 Sum of lengths of given elements
7204 length = self.smeshpyD.GetLength(self)
7205 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7206 length = self.smeshpyD.GetLength(elemId)
7209 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7211 length += self.smeshpyD.GetLength(obj)
7212 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7213 unRegister = genObjUnRegister()
7214 obj = self.GetIDSource( elemId )
7215 unRegister.set( obj )
7216 length = self.smeshpyD.GetLength( obj )
7218 length = self.FunctorValue(SMESH.FT_Length, elemId)
7221 def GetArea(self, elemId=None):
7223 Get area of given 2D elements or of all 2D mesh elements
7226 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.
7229 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7234 area = self.smeshpyD.GetArea(self)
7235 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7236 area = self.smeshpyD.GetArea(elemId)
7239 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7241 area += self.smeshpyD.GetArea(obj)
7242 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7243 unRegister = genObjUnRegister()
7244 obj = self.GetIDSource( elemId )
7245 unRegister.set( obj )
7246 area = self.smeshpyD.GetArea( obj )
7248 area = self.FunctorValue(SMESH.FT_Area, elemId)
7251 def GetVolume(self, elemId=None):
7253 Get volume of given 3D elements or of all 3D mesh elements
7256 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.
7259 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7264 volume= self.smeshpyD.GetVolume(self)
7265 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7266 volume= self.smeshpyD.GetVolume(elemId)
7269 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7271 volume+= self.smeshpyD.GetVolume(obj)
7272 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7273 unRegister = genObjUnRegister()
7274 obj = self.GetIDSource( elemId )
7275 unRegister.set( obj )
7276 volume= self.smeshpyD.GetVolume( obj )
7278 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7281 def GetAngle(self, node1, node2, node3 ):
7283 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7286 node1,node2,node3: IDs of the three nodes
7289 Angle in radians [0,PI]. -1 if failure case.
7291 p1 = self.GetNodeXYZ( node1 )
7292 p2 = self.GetNodeXYZ( node2 )
7293 p3 = self.GetNodeXYZ( node3 )
7294 if p1 and p2 and p3:
7295 return self.smeshpyD.GetAngle( p1,p2,p3 )
7299 def GetMaxElementLength(self, elemId):
7301 Get maximum element length.
7304 elemId: mesh element ID
7307 element's maximum length value
7310 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7311 ftype = SMESH.FT_MaxElementLength3D
7313 ftype = SMESH.FT_MaxElementLength2D
7314 return self.FunctorValue(ftype, elemId)
7316 def GetAspectRatio(self, elemId):
7318 Get aspect ratio of 2D or 3D element.
7321 elemId: mesh element ID
7324 element's aspect ratio value
7327 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7328 ftype = SMESH.FT_AspectRatio3D
7330 ftype = SMESH.FT_AspectRatio
7331 return self.FunctorValue(ftype, elemId)
7333 def GetWarping(self, elemId):
7335 Get warping angle of 2D element.
7338 elemId: mesh element ID
7341 element's warping angle value
7344 return self.FunctorValue(SMESH.FT_Warping, elemId)
7346 def GetMinimumAngle(self, elemId):
7348 Get minimum angle of 2D element.
7351 elemId: mesh element ID
7354 element's minimum angle value
7357 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7359 def GetTaper(self, elemId):
7361 Get taper of 2D element.
7364 elemId: mesh element ID
7367 element's taper value
7370 return self.FunctorValue(SMESH.FT_Taper, elemId)
7372 def GetSkew(self, elemId):
7374 Get skew of 2D element.
7377 elemId: mesh element ID
7380 element's skew value
7383 return self.FunctorValue(SMESH.FT_Skew, elemId)
7385 def GetMinMax(self, funType, meshPart=None):
7387 Return minimal and maximal value of a given functor.
7390 funType (SMESH.FunctorType): a functor type.
7391 Note that not all items of :class:`SMESH.FunctorType` corresponds
7392 to numerical functors.
7393 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7399 unRegister = genObjUnRegister()
7400 if isinstance( meshPart, list ):
7401 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7402 unRegister.set( meshPart )
7403 if isinstance( meshPart, Mesh ):
7404 meshPart = meshPart.mesh
7405 fun = self.GetFunctor( funType )
7408 if hasattr( meshPart, "SetMesh" ):
7409 meshPart.SetMesh( self.mesh ) # set mesh to filter
7410 hist = fun.GetLocalHistogram( 1, False, meshPart )
7412 hist = fun.GetHistogram( 1, False )
7414 return hist[0].min, hist[0].max
7417 pass # end of Mesh class
7420 class meshProxy(SMESH._objref_SMESH_Mesh):
7422 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7423 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7425 def __init__(self,*args):
7426 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7427 def __deepcopy__(self, memo=None):
7428 new = self.__class__(self)
7430 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7431 if len( args ) == 3:
7432 args += SMESH.ALL_NODES, True
7433 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7434 def ExportToMEDX(self, *args): # function removed
7435 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7436 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7437 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7438 def ExportToMED(self, *args): # function removed
7439 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7440 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7442 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7444 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7445 def ExportPartToMED(self, *args): # 'version' parameter removed
7446 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7447 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7448 def ExportMED(self, *args): # signature of method changed
7449 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7451 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7453 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7455 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7458 class submeshProxy(SMESH._objref_SMESH_subMesh):
7461 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7463 def __init__(self,*args):
7464 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7466 def __deepcopy__(self, memo=None):
7467 new = self.__class__(self)
7470 def Compute(self,refresh=False):
7472 Compute the sub-mesh and return the status of the computation
7475 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7480 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7481 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7485 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7487 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7489 if salome.sg.hasDesktop():
7490 if refresh: salome.sg.updateObjBrowser()
7495 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7498 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7500 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7501 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7504 def __init__(self,*args):
7505 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7507 def __getattr__(self, name ): # method called if an attribute not found
7508 if not self.mesh: # look for name() method in Mesh class
7509 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7510 if hasattr( self.mesh, name ):
7511 return getattr( self.mesh, name )
7512 if name == "ExtrusionAlongPathObjX":
7513 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7514 print("meshEditor: attribute '%s' NOT FOUND" % name)
7516 def __deepcopy__(self, memo=None):
7517 new = self.__class__(self)
7519 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7520 if len( args ) == 1: args += False,
7521 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7522 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7523 if len( args ) == 2: args += False,
7524 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7525 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7526 if len( args ) == 1:
7527 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7528 NodesToKeep = args[1]
7529 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7530 unRegister = genObjUnRegister()
7532 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7533 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7534 if not isinstance( NodesToKeep, list ):
7535 NodesToKeep = [ NodesToKeep ]
7536 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7538 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7540 class Pattern(SMESH._objref_SMESH_Pattern):
7542 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7543 variables in some methods
7546 def LoadFromFile(self, patternTextOrFile ):
7547 text = patternTextOrFile
7548 if os.path.exists( text ):
7549 text = open( patternTextOrFile ).read()
7551 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7553 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7554 decrFun = lambda i: i-1
7555 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7556 theMesh.SetParameters(Parameters)
7557 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7559 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7560 decrFun = lambda i: i-1
7561 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7562 theMesh.SetParameters(Parameters)
7563 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7565 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7566 if isinstance( mesh, Mesh ):
7567 mesh = mesh.GetMesh()
7568 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7570 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7572 Registering the new proxy for Pattern
7577 Private class used to bind methods creating algorithms to the class Mesh
7580 def __init__(self, method):
7582 self.defaultAlgoType = ""
7583 self.algoTypeToClass = {}
7584 self.method = method
7586 def add(self, algoClass):
7588 Store a python class of algorithm
7590 if inspect.isclass(algoClass) and \
7591 hasattr( algoClass, "algoType"):
7592 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7593 if not self.defaultAlgoType and \
7594 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7595 self.defaultAlgoType = algoClass.algoType
7596 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7598 def copy(self, mesh):
7600 Create a copy of self and assign mesh to the copy
7603 other = algoCreator( self.method )
7604 other.defaultAlgoType = self.defaultAlgoType
7605 other.algoTypeToClass = self.algoTypeToClass
7609 def __call__(self,algo="",geom=0,*args):
7611 Create an instance of algorithm
7615 if isinstance( algo, str ):
7617 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7618 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7623 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7625 elif not algoType and isinstance( geom, str ):
7630 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7632 elif isinstance( arg, str ) and not algoType:
7635 import traceback, sys
7636 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7637 sys.stderr.write( msg + '\n' )
7638 tb = traceback.extract_stack(None,2)
7639 traceback.print_list( [tb[0]] )
7641 algoType = self.defaultAlgoType
7642 if not algoType and self.algoTypeToClass:
7643 algoType = sorted( self.algoTypeToClass.keys() )[0]
7644 if algoType in self.algoTypeToClass:
7645 #print("Create algo",algoType)
7646 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7647 raise RuntimeError( "No class found for algo type %s" % algoType)
7650 class hypMethodWrapper:
7652 Private class used to substitute and store variable parameters of hypotheses.
7655 def __init__(self, hyp, method):
7657 self.method = method
7658 #print("REBIND:", method.__name__)
7661 def __call__(self,*args):
7663 call a method of hypothesis with calling SetVarParameter() before
7667 return self.method( self.hyp, *args ) # hypothesis method with no args
7669 #print("MethWrapper.__call__", self.method.__name__, args)
7671 parsed = ParseParameters(*args) # replace variables with their values
7672 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7673 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7674 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7675 # maybe there is a replaced string arg which is not variable
7676 result = self.method( self.hyp, *args )
7677 except ValueError as detail: # raised by ParseParameters()
7679 result = self.method( self.hyp, *args )
7680 except omniORB.CORBA.BAD_PARAM:
7681 raise ValueError(detail) # wrong variable name
7686 class genObjUnRegister:
7688 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7691 def __init__(self, genObj=None):
7692 self.genObjList = []
7696 def set(self, genObj):
7697 "Store one or a list of of SALOME.GenericObj'es"
7698 if isinstance( genObj, list ):
7699 self.genObjList.extend( genObj )
7701 self.genObjList.append( genObj )
7705 for genObj in self.genObjList:
7706 if genObj and hasattr( genObj, "UnRegister" ):
7709 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7711 Bind methods creating mesher plug-ins to the Mesh class
7714 # print("pluginName: ", pluginName)
7715 pluginBuilderName = pluginName + "Builder"
7717 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7718 except Exception as e:
7719 from salome_utils import verbose
7720 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7722 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7723 plugin = eval( pluginBuilderName )
7724 # print(" plugin:" , str(plugin))
7726 # add methods creating algorithms to Mesh
7727 for k in dir( plugin ):
7728 if k[0] == '_': continue
7729 algo = getattr( plugin, k )
7730 #print(" algo:", str(algo))
7731 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7732 #print(" meshMethod:" , str(algo.meshMethod))
7733 if not hasattr( Mesh, algo.meshMethod ):
7734 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7736 _mmethod = getattr( Mesh, algo.meshMethod )
7737 if hasattr( _mmethod, "add" ):