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 CreateMeshesFromSTL( self, theFileName ):
690 Create a Mesh object importing data from the given STL file
693 an instance of class :class:`Mesh`
696 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
697 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
700 def CreateMeshesFromCGNS( self, theFileName ):
702 Create Mesh objects importing data from the given CGNS file
705 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
708 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
709 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
710 return aMeshes, aStatus
712 def CreateMeshesFromGMF( self, theFileName ):
714 Create a Mesh object importing data from the given GMF file.
715 GMF files must have .mesh extension for the ASCII format and .meshb for
719 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
722 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
725 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
726 return Mesh(self, self.geompyD, aSmeshMesh), error
728 def Concatenate( self, meshes, uniteIdenticalGroups,
729 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
730 name = "", meshToAppendTo = None):
732 Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
733 All groups of input meshes will be present in the new mesh.
736 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
737 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
738 mergeNodesAndElements: if True, equal nodes and elements are merged
739 mergeTolerance: tolerance for merging nodes
740 allGroups: forces creation of groups corresponding to every input mesh
741 name: name of a new mesh
742 meshToAppendTo: a mesh to append all given meshes
745 an instance of class :class:`Mesh`
751 if not meshes: return None
752 if not isinstance( meshes, list ):
754 for i,m in enumerate( meshes ):
755 if isinstance( m, Mesh ):
756 meshes[i] = m.GetMesh()
757 mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
758 if hasattr(meshes[0], "SetParameters"):
759 meshes[0].SetParameters( Parameters )
761 meshes[0].GetMesh().SetParameters( Parameters )
762 if isinstance( meshToAppendTo, Mesh ):
763 meshToAppendTo = meshToAppendTo.GetMesh()
765 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
766 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
767 mergeTolerance,meshToAppendTo )
769 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
770 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
771 mergeTolerance,meshToAppendTo )
773 aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
776 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
778 Create a mesh by copying a part of another mesh.
781 meshPart: a part of mesh to copy, either
782 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
783 To copy nodes or elements not forming any mesh object,
784 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
785 meshName: a name of the new mesh
786 toCopyGroups: to create in the new mesh groups the copied elements belongs to
787 toKeepIDs: to preserve order of the copied elements or not
790 an instance of class :class:`Mesh`
793 if isinstance( meshPart, Mesh ):
794 meshPart = meshPart.GetMesh()
795 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
796 return Mesh(self, self.geompyD, mesh)
798 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
799 toReuseHypotheses=True, toCopyElements=True):
801 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
802 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
803 To facilitate and speed up the operation, consider using
804 "Set presentation parameters and sub-shapes from arguments" option in
805 a dialog of geometrical operation used to create the new geometry.
808 sourceMesh: the mesh to copy definition of.
809 newGeom: the new geometry.
810 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
811 toCopyGroups: to create groups in the new mesh.
812 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
813 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
816 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
817 *invalidEntries* are study entries of objects whose
818 counterparts are not found in the *newGeom*, followed by entries
819 of mesh sub-objects that are invalid because they depend on a not found
822 if isinstance( sourceMesh, Mesh ):
823 sourceMesh = sourceMesh.GetMesh()
825 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
826 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
830 return ( ok, Mesh(self, self.geompyD, newMesh),
831 newGroups, newSubMeshes, newHypotheses, invalidEntries )
833 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
835 Return IDs of sub-shapes
838 theMainObject (GEOM.GEOM_Object): a shape
839 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
841 the list of integer values
844 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
846 def GetPattern(self):
848 Create a pattern mapper.
851 an instance of :class:`SMESH.SMESH_Pattern`
853 :ref:`Example of Patterns usage <tui_pattern_mapping>`
856 return SMESH._objref_SMESH_Gen.GetPattern(self)
858 def SetBoundaryBoxSegmentation(self, nbSegments):
860 Set number of segments per diagonal of boundary box of geometry, by which
861 default segment length of appropriate 1D hypotheses is defined in GUI.
865 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
867 # Filtering. Auxiliary functions:
868 # ------------------------------
870 def GetEmptyCriterion(self):
872 Create an empty criterion
875 :class:`SMESH.Filter.Criterion`
878 Type = self.EnumToLong(FT_Undefined)
879 Compare = self.EnumToLong(FT_Undefined)
883 UnaryOp = self.EnumToLong(FT_Undefined)
884 BinaryOp = self.EnumToLong(FT_Undefined)
887 Precision = -1 ##@1e-07
888 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
889 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
891 def GetCriterion(self,elementType,
893 Compare = FT_EqualTo,
895 UnaryOp=FT_Undefined,
896 BinaryOp=FT_Undefined,
899 Create a criterion by the given parameters
900 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
903 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
904 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
905 Note that the items starting from FT_LessThan are not suitable for *CritType*.
906 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
907 Threshold: the threshold value (range of ids as string, shape, numeric)
908 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
909 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
911 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
912 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
915 :class:`SMESH.Filter.Criterion`
917 Example: :ref:`combining_filters`
920 if not CritType in SMESH.FunctorType._items:
921 raise TypeError("CritType should be of SMESH.FunctorType")
922 aCriterion = self.GetEmptyCriterion()
923 aCriterion.TypeOfElement = elementType
924 aCriterion.Type = self.EnumToLong(CritType)
925 aCriterion.Tolerance = Tolerance
927 aThreshold = Threshold
929 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
930 aCriterion.Compare = self.EnumToLong(Compare)
931 elif Compare == "=" or Compare == "==":
932 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
934 aCriterion.Compare = self.EnumToLong(FT_LessThan)
936 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
937 elif Compare != FT_Undefined:
938 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
941 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
942 FT_BelongToCylinder, FT_LyingOnGeom]:
943 # Check that Threshold is GEOM object
944 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
945 aCriterion.ThresholdStr = GetName(aThreshold)
946 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
947 if not aCriterion.ThresholdID:
948 name = aCriterion.ThresholdStr
950 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
951 geompyD = aThreshold.GetGen()
952 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
953 # or a name of GEOM object
954 elif isinstance( aThreshold, str ):
955 aCriterion.ThresholdStr = aThreshold
957 raise TypeError("The Threshold should be a shape.")
958 if isinstance(UnaryOp,float):
959 aCriterion.Tolerance = UnaryOp
960 UnaryOp = FT_Undefined
962 elif CritType == FT_BelongToMeshGroup:
963 # Check that Threshold is a group
964 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
965 if aThreshold.GetType() != elementType:
966 raise ValueError("Group type mismatches Element type")
967 aCriterion.ThresholdStr = aThreshold.GetName()
968 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
969 study = salome.myStudy
971 so = study.FindObjectIOR( aCriterion.ThresholdID )
975 aCriterion.ThresholdID = entry
977 raise TypeError("The Threshold should be a Mesh Group")
978 elif CritType == FT_RangeOfIds:
979 # Check that Threshold is string
980 if isinstance(aThreshold, str):
981 aCriterion.ThresholdStr = aThreshold
983 raise TypeError("The Threshold should be a string.")
984 elif CritType == FT_CoplanarFaces:
985 # Check the Threshold
986 if isinstance(aThreshold, int):
987 aCriterion.ThresholdID = str(aThreshold)
988 elif isinstance(aThreshold, str):
991 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
992 aCriterion.ThresholdID = aThreshold
994 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
995 elif CritType == FT_ConnectedElements:
996 # Check the Threshold
997 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
998 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
999 if not aCriterion.ThresholdID:
1000 name = aThreshold.GetName()
1002 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1003 geompyD = aThreshold.GetGen()
1004 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
1005 elif isinstance(aThreshold, int): # node id
1006 aCriterion.Threshold = aThreshold
1007 elif isinstance(aThreshold, list): # 3 point coordinates
1008 if len( aThreshold ) < 3:
1009 raise ValueError("too few point coordinates, must be 3")
1010 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1011 elif isinstance(aThreshold, str):
1012 if aThreshold.isdigit():
1013 aCriterion.Threshold = aThreshold # node id
1015 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1017 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1018 "or a list of point coordinates and not '%s'"%aThreshold)
1019 elif CritType == FT_ElemGeomType:
1020 # Check the Threshold
1022 aCriterion.Threshold = self.EnumToLong(aThreshold)
1023 assert( aThreshold in SMESH.GeometryType._items )
1025 if isinstance(aThreshold, int):
1026 aCriterion.Threshold = aThreshold
1028 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1031 elif CritType == FT_EntityType:
1032 # Check the Threshold
1034 aCriterion.Threshold = self.EnumToLong(aThreshold)
1035 assert( aThreshold in SMESH.EntityType._items )
1037 if isinstance(aThreshold, int):
1038 aCriterion.Threshold = aThreshold
1040 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1044 elif CritType == FT_GroupColor:
1045 # Check the Threshold
1047 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1049 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1051 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1052 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1053 FT_BareBorderFace, FT_BareBorderVolume,
1054 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1055 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1056 # At this point the Threshold is unnecessary
1057 if aThreshold == FT_LogicalNOT:
1058 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1059 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1060 aCriterion.BinaryOp = aThreshold
1064 aThreshold = float(aThreshold)
1065 aCriterion.Threshold = aThreshold
1067 raise TypeError("The Threshold should be a number.")
1070 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1071 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1073 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1074 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1076 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1077 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1079 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1080 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1084 def GetFilter(self,elementType,
1085 CritType=FT_Undefined,
1088 UnaryOp=FT_Undefined,
1092 Create a filter with the given parameters
1095 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1096 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1097 Note that the items starting from FT_LessThan are not suitable for CritType.
1098 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1099 Threshold: the threshold value (range of ids as string, shape, numeric)
1100 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1101 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1102 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1103 mesh: the mesh to initialize the filter with
1106 :class:`SMESH.Filter`
1109 See :doc:`Filters usage examples <tui_filters>`
1112 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1113 aFilterMgr = self.CreateFilterManager()
1114 aFilter = aFilterMgr.CreateFilter()
1116 aCriteria.append(aCriterion)
1117 aFilter.SetCriteria(aCriteria)
1119 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1120 else : aFilter.SetMesh( mesh )
1121 aFilterMgr.UnRegister()
1124 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1126 Create a filter from criteria
1129 criteria: a list of :class:`SMESH.Filter.Criterion`
1130 binOp: binary operator used when binary operator of criteria is undefined
1133 :class:`SMESH.Filter`
1136 See :doc:`Filters usage examples <tui_filters>`
1139 for i in range( len( criteria ) - 1 ):
1140 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1141 criteria[i].BinaryOp = self.EnumToLong( binOp )
1142 aFilterMgr = self.CreateFilterManager()
1143 aFilter = aFilterMgr.CreateFilter()
1144 aFilter.SetCriteria(criteria)
1145 aFilterMgr.UnRegister()
1148 def GetFunctor(self,theCriterion):
1150 Create a numerical functor by its type
1153 theCriterion (SMESH.FunctorType): functor type.
1154 Note that not all items correspond to numerical functors.
1157 :class:`SMESH.NumericalFunctor`
1160 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1162 aFilterMgr = self.CreateFilterManager()
1164 if theCriterion == FT_AspectRatio:
1165 functor = aFilterMgr.CreateAspectRatio()
1166 elif theCriterion == FT_AspectRatio3D:
1167 functor = aFilterMgr.CreateAspectRatio3D()
1168 elif theCriterion == FT_Warping:
1169 functor = aFilterMgr.CreateWarping()
1170 elif theCriterion == FT_MinimumAngle:
1171 functor = aFilterMgr.CreateMinimumAngle()
1172 elif theCriterion == FT_Taper:
1173 functor = aFilterMgr.CreateTaper()
1174 elif theCriterion == FT_Skew:
1175 functor = aFilterMgr.CreateSkew()
1176 elif theCriterion == FT_Area:
1177 functor = aFilterMgr.CreateArea()
1178 elif theCriterion == FT_Volume3D:
1179 functor = aFilterMgr.CreateVolume3D()
1180 elif theCriterion == FT_MaxElementLength2D:
1181 functor = aFilterMgr.CreateMaxElementLength2D()
1182 elif theCriterion == FT_MaxElementLength3D:
1183 functor = aFilterMgr.CreateMaxElementLength3D()
1184 elif theCriterion == FT_MultiConnection:
1185 functor = aFilterMgr.CreateMultiConnection()
1186 elif theCriterion == FT_MultiConnection2D:
1187 functor = aFilterMgr.CreateMultiConnection2D()
1188 elif theCriterion == FT_Length:
1189 functor = aFilterMgr.CreateLength()
1190 elif theCriterion == FT_Length2D:
1191 functor = aFilterMgr.CreateLength2D()
1192 elif theCriterion == FT_Length3D:
1193 functor = aFilterMgr.CreateLength3D()
1194 elif theCriterion == FT_Deflection2D:
1195 functor = aFilterMgr.CreateDeflection2D()
1196 elif theCriterion == FT_NodeConnectivityNumber:
1197 functor = aFilterMgr.CreateNodeConnectivityNumber()
1198 elif theCriterion == FT_BallDiameter:
1199 functor = aFilterMgr.CreateBallDiameter()
1201 print("Error: given parameter is not numerical functor type.")
1202 aFilterMgr.UnRegister()
1205 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1210 theHType (string): mesh hypothesis type
1211 theLibName (string): mesh plug-in library name
1214 created hypothesis instance
1216 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1218 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1221 # wrap hypothesis methods
1222 for meth_name in dir( hyp.__class__ ):
1223 if not meth_name.startswith("Get") and \
1224 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1225 method = getattr ( hyp.__class__, meth_name )
1226 if callable(method):
1227 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1231 def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1233 Create hypothesis initialized according to parameters
1236 hypType (string): hypothesis type
1237 libName (string): plug-in library name
1238 mesh: optional mesh by which a hypotheses can initialize self
1239 shape: optional geometry by size of which a hypotheses can initialize self
1240 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1243 created hypothesis instance
1245 if isinstance( mesh, Mesh ):
1246 mesh = mesh.GetMesh()
1247 if isinstance( initParams, (bool,int)):
1248 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1249 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1250 mesh, shape, initParams )
1252 def GetMeshInfo(self, obj):
1254 Get the mesh statistic.
1257 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1260 if isinstance( obj, Mesh ):
1263 if hasattr(obj, "GetMeshInfo"):
1264 values = obj.GetMeshInfo()
1265 for i in range(SMESH.Entity_Last._v):
1266 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1270 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1272 Get minimum distance between two objects
1274 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1275 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1278 src1 (SMESH.SMESH_IDSource): first source object
1279 src2 (SMESH.SMESH_IDSource): second source object
1280 id1 (int): node/element id from the first source
1281 id2 (int): node/element id from the second (or first) source
1282 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1283 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1286 minimum distance value
1289 :meth:`GetMinDistance`
1292 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1296 result = result.value
1299 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1301 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1303 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1304 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1307 src1 (SMESH.SMESH_IDSource): first source object
1308 src2 (SMESH.SMESH_IDSource): second source object
1309 id1 (int): node/element id from the first source
1310 id2 (int): node/element id from the second (or first) source
1311 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1312 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1315 :class:`SMESH.Measure` structure or None if input data is invalid
1320 if isinstance(src1, Mesh): src1 = src1.mesh
1321 if isinstance(src2, Mesh): src2 = src2.mesh
1322 if src2 is None and id2 != 0: src2 = src1
1323 if not hasattr(src1, "_narrow"): return None
1324 src1 = src1._narrow(SMESH.SMESH_IDSource)
1325 if not src1: return None
1326 unRegister = genObjUnRegister()
1329 e = m.GetMeshEditor()
1331 src1 = e.MakeIDSource([id1], SMESH.FACE)
1333 src1 = e.MakeIDSource([id1], SMESH.NODE)
1334 unRegister.set( src1 )
1336 if hasattr(src2, "_narrow"):
1337 src2 = src2._narrow(SMESH.SMESH_IDSource)
1338 if src2 and id2 != 0:
1340 e = m.GetMeshEditor()
1342 src2 = e.MakeIDSource([id2], SMESH.FACE)
1344 src2 = e.MakeIDSource([id2], SMESH.NODE)
1345 unRegister.set( src2 )
1348 aMeasurements = self.CreateMeasurements()
1349 unRegister.set( aMeasurements )
1350 result = aMeasurements.MinDistance(src1, src2)
1353 def BoundingBox(self, objects):
1355 Get bounding box of the specified object(s)
1358 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1361 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1364 :meth:`GetBoundingBox`
1367 result = self.GetBoundingBox(objects)
1371 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1374 def GetBoundingBox(self, objects):
1376 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1379 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1382 :class:`SMESH.Measure` structure
1388 if isinstance(objects, tuple):
1389 objects = list(objects)
1390 if not isinstance(objects, list):
1394 if isinstance(o, Mesh):
1395 srclist.append(o.mesh)
1396 elif hasattr(o, "_narrow"):
1397 src = o._narrow(SMESH.SMESH_IDSource)
1398 if src: srclist.append(src)
1401 aMeasurements = self.CreateMeasurements()
1402 result = aMeasurements.BoundingBox(srclist)
1403 aMeasurements.UnRegister()
1406 def GetLength(self, obj):
1408 Get sum of lengths of all 1D elements in the mesh object.
1411 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1414 sum of lengths of all 1D elements
1417 if isinstance(obj, Mesh): obj = obj.mesh
1418 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1419 aMeasurements = self.CreateMeasurements()
1420 value = aMeasurements.Length(obj)
1421 aMeasurements.UnRegister()
1424 def GetArea(self, obj):
1426 Get sum of areas of all 2D elements in the mesh object.
1429 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1432 sum of areas of all 2D elements
1435 if isinstance(obj, Mesh): obj = obj.mesh
1436 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1437 aMeasurements = self.CreateMeasurements()
1438 value = aMeasurements.Area(obj)
1439 aMeasurements.UnRegister()
1442 def GetVolume(self, obj):
1444 Get sum of volumes of all 3D elements in the mesh object.
1447 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1450 sum of volumes of all 3D elements
1453 if isinstance(obj, Mesh): obj = obj.mesh
1454 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1455 aMeasurements = self.CreateMeasurements()
1456 value = aMeasurements.Volume(obj)
1457 aMeasurements.UnRegister()
1460 def GetGravityCenter(self, obj):
1462 Get gravity center of all nodes of a mesh object.
1465 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1468 Three components of the gravity center (x,y,z)
1471 :meth:`Mesh.BaryCenter`
1473 if isinstance(obj, Mesh): obj = obj.mesh
1474 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1475 aMeasurements = self.CreateMeasurements()
1476 pointStruct = aMeasurements.GravityCenter(obj)
1477 aMeasurements.UnRegister()
1478 return pointStruct.x, pointStruct.y, pointStruct.z
1480 def GetAngle(self, p1, p2, p3 ):
1482 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1485 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1491 if isinstance( p1, list ): p1 = PointStruct(*p1)
1492 if isinstance( p2, list ): p2 = PointStruct(*p2)
1493 if isinstance( p3, list ): p3 = PointStruct(*p3)
1495 aMeasurements = self.CreateMeasurements()
1496 angle = aMeasurements.Angle(p1,p2,p3)
1497 aMeasurements.UnRegister()
1502 pass # end of class smeshBuilder
1505 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1506 """Registering the new proxy for SMESH.SMESH_Gen"""
1509 def New( instance=None, instanceGeom=None):
1511 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1512 interface to create or load meshes.
1517 salome.salome_init()
1518 from salome.smesh import smeshBuilder
1519 smesh = smeshBuilder.New()
1522 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1523 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1525 :class:`smeshBuilder` instance
1530 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1532 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1537 smeshInst = smeshBuilder()
1538 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1539 smeshInst.init_smesh(instanceGeom)
1543 # Public class: Mesh
1544 # ==================
1547 class Mesh(metaclass = MeshMeta):
1549 This class allows defining and managing a mesh.
1550 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1551 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1552 new nodes and elements and by changing the existing entities), to get information
1553 about a mesh and to export a mesh in different formats.
1560 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1565 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1566 sets the GUI name of this mesh to *name*.
1569 smeshpyD: an instance of smeshBuilder class
1570 geompyD: an instance of geomBuilder class
1571 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1572 name: Study name of the mesh
1575 self.smeshpyD = smeshpyD
1576 self.geompyD = geompyD
1581 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1584 # publish geom of mesh (issue 0021122)
1585 if not self.geom.GetStudyEntry():
1589 geo_name = name + " shape"
1591 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1592 geompyD.addToStudy( self.geom, geo_name )
1593 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1595 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1598 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1600 self.smeshpyD.SetName(self.mesh, name)
1602 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1605 self.geom = self.mesh.GetShapeToMesh()
1607 self.editor = self.mesh.GetMeshEditor()
1608 self.functors = [None] * SMESH.FT_Undefined._v
1610 # set self to algoCreator's
1611 for attrName in dir(self):
1612 attr = getattr( self, attrName )
1613 if isinstance( attr, algoCreator ):
1614 setattr( self, attrName, attr.copy( self ))
1621 Destructor. Clean-up resources
1624 #self.mesh.UnRegister()
1628 def SetMesh(self, theMesh):
1630 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1633 theMesh: a :class:`SMESH.SMESH_Mesh` object
1635 # do not call Register() as this prevents mesh servant deletion at closing study
1636 #if self.mesh: self.mesh.UnRegister()
1639 #self.mesh.Register()
1640 self.geom = self.mesh.GetShapeToMesh()
1644 if salome.sg.hasDesktop():
1645 so = salome.ObjectToSObject( self.geom )
1646 comp = so.GetFatherComponent()
1647 if comp.ComponentDataType() == "SHAPERSTUDY":
1648 import shaperBuilder
1649 self.geompyD = shaperBuilder.New()
1652 if not self.geompyD:
1653 self.geompyD = self.geom.GetGen()
1658 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1661 a :class:`SMESH.SMESH_Mesh` object
1666 def GetEngine(self):
1668 Return a smeshBuilder instance created this mesh
1670 return self.smeshpyD
1672 def GetGeomEngine(self):
1674 Return a geomBuilder instance
1680 Get the name of the mesh
1683 the name of the mesh as a string
1686 name = GetName(self.GetMesh())
1689 def SetName(self, name):
1691 Set a name to the mesh
1694 name: a new name of the mesh
1697 self.smeshpyD.SetName(self.GetMesh(), name)
1699 def GetSubMesh(self, geom, name):
1701 Get a sub-mesh object associated to a *geom* geometrical object.
1704 geom: a geometrical object (shape)
1705 name: a name for the sub-mesh in the Object Browser
1708 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1709 which lies on the given shape
1712 A sub-mesh is implicitly created when a sub-shape is specified at
1713 creating an algorithm, for example::
1715 algo1D = mesh.Segment(geom=Edge_1)
1717 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1718 The created sub-mesh can be retrieved from the algorithm::
1720 submesh = algo1D.GetSubMesh()
1723 AssureGeomPublished( self, geom, name )
1724 submesh = self.mesh.GetSubMesh( geom, name )
1729 Return the shape associated to the mesh
1737 def SetShape(self, geom):
1739 Associate the given shape to the mesh (entails the recreation of the mesh)
1742 geom: the shape to be meshed (GEOM_Object)
1745 self.mesh = self.smeshpyD.CreateMesh(geom)
1747 def HasShapeToMesh(self):
1749 Return ``True`` if this mesh is based on geometry
1751 return self.mesh.HasShapeToMesh()
1755 Load mesh from the study after opening the study
1759 def IsReadyToCompute(self, theSubObject):
1761 Return true if the hypotheses are defined well
1764 theSubObject: a sub-shape of a mesh shape
1770 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1772 def GetAlgoState(self, theSubObject):
1774 Return errors of hypotheses definition.
1775 The list of errors is empty if everything is OK.
1778 theSubObject: a sub-shape of a mesh shape
1784 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1786 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1788 Return a geometrical object on which the given element was built.
1789 The returned geometrical object, if not nil, is either found in the
1790 study or published by this method with the given name
1793 theElementID: the id of the mesh element
1794 theGeomName: the user-defined name of the geometrical object
1797 GEOM.GEOM_Object instance
1800 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1802 def MeshDimension(self):
1804 Return the mesh dimension depending on the dimension of the underlying shape
1805 or, if the mesh is not based on any shape, basing on deimension of elements
1808 mesh dimension as an integer value [0,3]
1811 if self.mesh.HasShapeToMesh():
1812 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1813 if len( shells ) > 0 :
1815 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1817 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1822 if self.NbVolumes() > 0: return 3
1823 if self.NbFaces() > 0: return 2
1824 if self.NbEdges() > 0: return 1
1827 def Evaluate(self, geom=0):
1829 Evaluate size of prospective mesh on a shape
1832 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1833 To know predicted number of e.g. edges, inquire it this way::
1835 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1838 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1840 geom = self.mesh.GetShapeToMesh()
1843 return self.smeshpyD.Evaluate(self.mesh, geom)
1846 def Compute(self, geom=0, discardModifs=False, refresh=False):
1848 Compute the mesh and return the status of the computation
1851 geom: geomtrical shape on which mesh data should be computed
1852 discardModifs: if True and the mesh has been edited since
1853 a last total re-compute and that may prevent successful partial re-compute,
1854 then the mesh is cleaned before Compute()
1855 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1861 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1862 geom = self.mesh.GetShapeToMesh()
1865 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1867 ok = self.smeshpyD.Compute(self.mesh, geom)
1868 except SALOME.SALOME_Exception as ex:
1869 print("Mesh computation failed, exception caught:")
1870 print(" ", ex.details.text)
1873 print("Mesh computation failed, exception caught:")
1874 traceback.print_exc()
1878 # Treat compute errors
1879 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1881 for err in computeErrors:
1882 if self.mesh.HasShapeToMesh():
1883 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1885 stdErrors = ["OK", #COMPERR_OK
1886 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1887 "std::exception", #COMPERR_STD_EXCEPTION
1888 "OCC exception", #COMPERR_OCC_EXCEPTION
1889 "..", #COMPERR_SLM_EXCEPTION
1890 "Unknown exception", #COMPERR_EXCEPTION
1891 "Memory allocation problem", #COMPERR_MEMORY_PB
1892 "Algorithm failed", #COMPERR_ALGO_FAILED
1893 "Unexpected geometry", #COMPERR_BAD_SHAPE
1894 "Warning", #COMPERR_WARNING
1895 "Computation cancelled",#COMPERR_CANCELED
1896 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1898 if err.code < len(stdErrors): errText = stdErrors[err.code]
1900 errText = "code %s" % -err.code
1901 if errText: errText += ". "
1902 errText += err.comment
1903 if allReasons: allReasons += "\n"
1905 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1907 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1911 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1913 if err.isGlobalAlgo:
1921 reason = '%s %sD algorithm is missing' % (glob, dim)
1922 elif err.state == HYP_MISSING:
1923 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1924 % (glob, dim, name, dim))
1925 elif err.state == HYP_NOTCONFORM:
1926 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1927 elif err.state == HYP_BAD_PARAMETER:
1928 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1929 % ( glob, dim, name ))
1930 elif err.state == HYP_BAD_GEOMETRY:
1931 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1932 'geometry' % ( glob, dim, name ))
1933 elif err.state == HYP_HIDDEN_ALGO:
1934 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1935 'algorithm of upper dimension generating %sD mesh'
1936 % ( glob, dim, name, glob, dim ))
1938 reason = ("For unknown reason. "
1939 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1941 if allReasons: allReasons += "\n"
1942 allReasons += "- " + reason
1944 if not ok or allReasons != "":
1945 msg = '"' + GetName(self.mesh) + '"'
1946 if ok: msg += " has been computed with warnings"
1947 else: msg += " has not been computed"
1948 if allReasons != "": msg += ":"
1954 if salome.sg.hasDesktop():
1955 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1956 if refresh: salome.sg.updateObjBrowser()
1960 def GetComputeErrors(self, shape=0 ):
1962 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1966 shape = self.mesh.GetShapeToMesh()
1967 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1969 def GetSubShapeName(self, subShapeID ):
1971 Return a name of a sub-shape by its ID.
1972 Possible variants (for *subShapeID* == 3):
1974 - **"Face_12"** - published sub-shape
1975 - **FACE #3** - not published sub-shape
1976 - **sub-shape #3** - invalid sub-shape ID
1977 - **#3** - error in this function
1980 subShapeID: a unique ID of a sub-shape
1983 a string describing the sub-shape
1987 if not self.mesh.HasShapeToMesh():
1991 mainIOR = salome.orb.object_to_string( self.GetShape() )
1993 mainSO = s.FindObjectIOR(mainIOR)
1996 shapeText = '"%s"' % mainSO.GetName()
1997 subIt = s.NewChildIterator(mainSO)
1999 subSO = subIt.Value()
2001 obj = subSO.GetObject()
2002 if not obj: continue
2003 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2006 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2009 if ids == subShapeID:
2010 shapeText = '"%s"' % subSO.GetName()
2013 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2015 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2017 shapeText = 'sub-shape #%s' % (subShapeID)
2019 shapeText = "#%s" % (subShapeID)
2022 def GetFailedShapes(self, publish=False):
2024 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2025 error of an algorithm
2028 publish: if *True*, the returned groups will be published in the study
2031 a list of GEOM groups each named after a failed algorithm
2036 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2037 for err in computeErrors:
2038 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2039 if not shape: continue
2040 if err.algoName in algo2shapes:
2041 algo2shapes[ err.algoName ].append( shape )
2043 algo2shapes[ err.algoName ] = [ shape ]
2047 for algoName, shapes in list(algo2shapes.items()):
2049 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2050 otherTypeShapes = []
2052 group = self.geompyD.CreateGroup( self.geom, groupType )
2053 for shape in shapes:
2054 if shape.GetShapeType() == shapes[0].GetShapeType():
2055 sameTypeShapes.append( shape )
2057 otherTypeShapes.append( shape )
2058 self.geompyD.UnionList( group, sameTypeShapes )
2060 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2062 group.SetName( algoName )
2063 groups.append( group )
2064 shapes = otherTypeShapes
2067 for group in groups:
2068 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2071 def GetMeshOrder(self):
2073 Return sub-mesh objects list in meshing order
2076 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2079 return self.mesh.GetMeshOrder()
2081 def SetMeshOrder(self, submeshes):
2083 Set priority of sub-meshes. It works in two ways:
2085 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2086 *several dimensions*, it sets the order in which the sub-meshes are computed.
2087 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2088 when looking for meshing parameters to apply to a sub-shape. To impose the
2089 order in which sub-meshes with uni-dimensional algorithms are computed,
2090 call **submesh.Compute()** in a desired order.
2093 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2095 Warning: the method is for setting the order for all sub-meshes at once:
2096 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2099 return self.mesh.SetMeshOrder(submeshes)
2101 def Clear(self, refresh=False):
2103 Remove all nodes and elements generated on geometry. Imported elements remain.
2106 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2110 if ( salome.sg.hasDesktop() ):
2111 if refresh: salome.sg.updateObjBrowser()
2113 def ClearSubMesh(self, geomId, refresh=False):
2115 Remove all nodes and elements of indicated shape
2118 geomId: the ID of a sub-shape to remove elements on
2119 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2122 self.mesh.ClearSubMesh(geomId)
2123 if salome.sg.hasDesktop():
2124 if refresh: salome.sg.updateObjBrowser()
2126 def AutomaticTetrahedralization(self, fineness=0):
2128 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2131 fineness: [0.0,1.0] defines mesh fineness
2137 dim = self.MeshDimension()
2139 self.RemoveGlobalHypotheses()
2140 self.Segment().AutomaticLength(fineness)
2142 self.Triangle().LengthFromEdges()
2147 return self.Compute()
2149 def AutomaticHexahedralization(self, fineness=0):
2151 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2154 fineness: [0.0, 1.0] defines mesh fineness
2160 dim = self.MeshDimension()
2161 # assign the hypotheses
2162 self.RemoveGlobalHypotheses()
2163 self.Segment().AutomaticLength(fineness)
2170 return self.Compute()
2172 def AddHypothesis(self, hyp, geom=0):
2177 hyp: a hypothesis to assign
2178 geom: a subhape of mesh geometry
2181 :class:`SMESH.Hypothesis_Status`
2184 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2185 hyp, geom = geom, hyp
2186 if isinstance( hyp, Mesh_Algorithm ):
2187 hyp = hyp.GetAlgorithm()
2192 geom = self.mesh.GetShapeToMesh()
2195 if self.mesh.HasShapeToMesh():
2196 hyp_type = hyp.GetName()
2197 lib_name = hyp.GetLibName()
2198 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2199 # if checkAll and geom:
2200 # checkAll = geom.GetType() == 37
2202 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2204 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2205 status = self.mesh.AddHypothesis(geom, hyp)
2207 status = HYP_BAD_GEOMETRY, ""
2208 hyp_name = GetName( hyp )
2211 geom_name = geom.GetName()
2212 isAlgo = hyp._narrow( SMESH_Algo )
2213 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2216 def IsUsedHypothesis(self, hyp, geom):
2218 Return True if an algorithm or hypothesis is assigned to a given shape
2221 hyp: an algorithm or hypothesis to check
2222 geom: a subhape of mesh geometry
2228 if not hyp: # or not geom
2230 if isinstance( hyp, Mesh_Algorithm ):
2231 hyp = hyp.GetAlgorithm()
2233 hyps = self.GetHypothesisList(geom)
2235 if h.GetId() == hyp.GetId():
2239 def RemoveHypothesis(self, hyp, geom=0):
2241 Unassign a hypothesis
2244 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2245 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2248 :class:`SMESH.Hypothesis_Status`
2253 if isinstance( hyp, Mesh_Algorithm ):
2254 hyp = hyp.GetAlgorithm()
2260 if self.IsUsedHypothesis( hyp, shape ):
2261 return self.mesh.RemoveHypothesis( shape, hyp )
2262 hypName = GetName( hyp )
2263 geoName = GetName( shape )
2264 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2267 def GetHypothesisList(self, geom):
2269 Get the list of hypotheses added on a geometry
2272 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2275 the sequence of :class:`SMESH.SMESH_Hypothesis`
2278 return self.mesh.GetHypothesisList( geom )
2280 def RemoveGlobalHypotheses(self):
2282 Remove all global hypotheses
2285 current_hyps = self.mesh.GetHypothesisList( self.geom )
2286 for hyp in current_hyps:
2287 self.mesh.RemoveHypothesis( self.geom, hyp )
2291 def ExportMEDCoupling(self, *args, **kwargs):
2293 Export the mesh in a memory representation.
2296 auto_groups (boolean): parameter for creating/not creating
2297 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2298 the typical use is auto_groups=False.
2299 overwrite (boolean): parameter for overwriting/not overwriting the file
2300 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2301 to export instead of the mesh
2302 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2304 - 1D if all mesh nodes lie on OX coordinate axis, or
2305 - 2D if all mesh nodes lie on XOY coordinate plane, or
2306 - 3D in the rest cases.
2308 If *autoDimension* is *False*, the space dimension is always 3.
2309 fields: list of GEOM fields defined on the shape to mesh.
2310 geomAssocFields: each character of this string means a need to export a
2311 corresponding field; correspondence between fields and characters
2314 - 'v' stands for "_vertices_" field;
2315 - 'e' stands for "_edges_" field;
2316 - 'f' stands for "_faces_" field;
2317 - 's' stands for "_solids_" field.
2319 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2320 close to zero within a given tolerance, the coordinate is set to zero.
2321 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2322 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2324 auto_groups = args[0] if len(args) > 0 else False
2325 meshPart = args[1] if len(args) > 1 else None
2326 autoDimension = args[2] if len(args) > 2 else True
2327 fields = args[3] if len(args) > 3 else []
2328 geomAssocFields = args[4] if len(args) > 4 else ''
2329 z_tolerance = args[5] if len(args) > 5 else -1.
2330 saveNumbers = args[6] if len(args) > 6 else True
2331 # process keywords arguments
2332 auto_groups = kwargs.get("auto_groups", auto_groups)
2333 meshPart = kwargs.get("meshPart", meshPart)
2334 autoDimension = kwargs.get("autoDimension", autoDimension)
2335 fields = kwargs.get("fields", fields)
2336 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2337 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2338 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2340 # invoke engine's function
2341 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2342 unRegister = genObjUnRegister()
2343 if isinstance( meshPart, list ):
2344 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2345 unRegister.set( meshPart )
2347 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2348 self.mesh.SetParameters(Parameters)
2350 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2351 fields, geomAssocFields, z_tolerance,
2354 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2355 return medcoupling.MEDFileData.New(dab)
2357 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2359 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2360 return medcoupling.MEDFileMesh.New(dab)
2362 def ExportMED(self, *args, **kwargs):
2364 Export the mesh in a file in MED format
2365 allowing to overwrite the file if it exists or add the exported data to its contents
2368 fileName: is the file name
2369 auto_groups (boolean): parameter for creating/not creating
2370 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2371 the typical use is auto_groups=False.
2372 version (int): define the version (xy, where version is x.y.z) of MED file format.
2373 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2374 The rules of compatibility to write a mesh in an older version than
2375 the current version depend on the current version. For instance,
2376 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2377 or 3.2.1 or 3.3.1 formats.
2378 If the version is equal to -1, the version is not changed (default).
2379 overwrite (boolean): parameter for overwriting/not overwriting the file
2380 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2381 to export instead of the mesh
2382 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2384 - 1D if all mesh nodes lie on OX coordinate axis, or
2385 - 2D if all mesh nodes lie on XOY coordinate plane, or
2386 - 3D in the rest cases.
2388 If *autoDimension* is *False*, the space dimension is always 3.
2389 fields: list of GEOM fields defined on the shape to mesh.
2390 geomAssocFields: each character of this string means a need to export a
2391 corresponding field; correspondence between fields and characters
2394 - 'v' stands for "_vertices_" field;
2395 - 'e' stands for "_edges_" field;
2396 - 'f' stands for "_faces_" field;
2397 - 's' stands for "_solids_" field.
2399 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2400 close to zero within a given tolerance, the coordinate is set to zero.
2401 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2402 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2404 # process positional arguments
2405 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2407 auto_groups = args[1] if len(args) > 1 else False
2408 version = args[2] if len(args) > 2 else -1
2409 overwrite = args[3] if len(args) > 3 else True
2410 meshPart = args[4] if len(args) > 4 else None
2411 autoDimension = args[5] if len(args) > 5 else True
2412 fields = args[6] if len(args) > 6 else []
2413 geomAssocFields = args[7] if len(args) > 7 else ''
2414 z_tolerance = args[8] if len(args) > 8 else -1.
2415 saveNumbers = args[9] if len(args) > 9 else True
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)
2426 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2428 if isinstance( meshPart, Mesh):
2429 meshPart = meshPart.GetMesh()
2431 # invoke engine's function
2432 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2433 unRegister = genObjUnRegister()
2434 if isinstance( meshPart, list ):
2435 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2436 unRegister.set( meshPart )
2438 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2439 self.mesh.SetParameters(Parameters)
2441 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2442 version, overwrite, autoDimension,
2443 fields, geomAssocFields, z_tolerance, saveNumbers )
2445 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2447 def ExportDAT(self, f, meshPart=None, renumber=True):
2449 Export the mesh in a file in DAT format
2453 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2454 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2457 if meshPart or not renumber:
2458 unRegister = genObjUnRegister()
2459 if isinstance( meshPart, list ):
2460 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2461 unRegister.set( meshPart )
2462 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2464 self.mesh.ExportDAT( f, renumber )
2466 def ExportUNV(self, f, meshPart=None, renumber=True):
2468 Export the mesh in a file in UNV format
2472 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2473 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2476 if meshPart or not renumber:
2477 unRegister = genObjUnRegister()
2478 if isinstance( meshPart, list ):
2479 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2480 unRegister.set( meshPart )
2481 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2483 self.mesh.ExportUNV( f, renumber )
2485 def ExportSTL(self, f, ascii=1, meshPart=None):
2487 Export the mesh in a file in STL format
2491 ascii: defines the file encoding
2492 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2496 unRegister = genObjUnRegister()
2497 if isinstance( meshPart, list ):
2498 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2499 unRegister.set( meshPart )
2500 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2502 self.mesh.ExportSTL(f, ascii)
2504 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2506 Export the mesh in a file in CGNS format
2510 overwrite: boolean parameter for overwriting/not overwriting the file
2511 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2512 groupElemsByType: if True all elements of same entity type are exported at ones,
2513 else elements are exported in order of their IDs which can cause creation
2514 of multiple cgns sections
2517 unRegister = genObjUnRegister()
2518 if isinstance( meshPart, list ):
2519 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2520 unRegister.set( meshPart )
2521 if isinstance( meshPart, Mesh ):
2522 meshPart = meshPart.mesh
2524 meshPart = self.mesh
2525 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2527 def ExportGMF(self, f, meshPart=None):
2529 Export the mesh in a file in GMF format.
2530 GMF files must have .mesh extension for the ASCII format and .meshb for
2531 the bynary format. Other extensions are not allowed.
2535 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2538 unRegister = genObjUnRegister()
2539 if isinstance( meshPart, list ):
2540 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2541 unRegister.set( meshPart )
2542 if isinstance( meshPart, Mesh ):
2543 meshPart = meshPart.mesh
2545 meshPart = self.mesh
2546 self.mesh.ExportGMF(meshPart, f, True)
2548 def ExportToMED(self, *args, **kwargs):
2550 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2551 Export the mesh in a file in MED format
2552 allowing to overwrite the file if it exists or add the exported data to its contents
2555 fileName: the file name
2556 opt (boolean): parameter for creating/not creating
2557 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2558 overwrite: boolean parameter for overwriting/not overwriting the file
2559 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2561 - 1D if all mesh nodes lie on OX coordinate axis, or
2562 - 2D if all mesh nodes lie on XOY coordinate plane, or
2563 - 3D in the rest cases.
2565 If **autoDimension** is *False*, the space dimension is always 3.
2568 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2569 # process positional arguments
2570 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2572 auto_groups = args[1] if len(args) > 1 else False
2573 overwrite = args[2] if len(args) > 2 else True
2574 autoDimension = args[3] if len(args) > 3 else True
2575 # process keywords arguments
2576 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2577 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2578 overwrite = kwargs.get("overwrite", overwrite)
2579 autoDimension = kwargs.get("autoDimension", autoDimension)
2581 # invoke engine's function
2582 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2584 def ExportToMEDX(self, *args, **kwargs):
2586 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2587 Export the mesh in a file in MED format
2590 fileName: the file name
2591 opt (boolean): parameter for creating/not creating
2592 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2593 overwrite: boolean parameter for overwriting/not overwriting the file
2594 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2596 - 1D if all mesh nodes lie on OX coordinate axis, or
2597 - 2D if all mesh nodes lie on XOY coordinate plane, or
2598 - 3D in the rest cases.
2600 If **autoDimension** is *False*, the space dimension is always 3.
2603 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2604 # process positional arguments
2605 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2607 auto_groups = args[1] if len(args) > 1 else False
2608 overwrite = args[2] if len(args) > 2 else True
2609 autoDimension = args[3] if len(args) > 3 else True
2610 # process keywords arguments
2611 auto_groups = kwargs.get("auto_groups", auto_groups)
2612 overwrite = kwargs.get("overwrite", overwrite)
2613 autoDimension = kwargs.get("autoDimension", autoDimension)
2615 # invoke engine's function
2616 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2620 def Append(self, meshes, uniteIdenticalGroups = True,
2621 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2623 Append given meshes into this mesh.
2624 All groups of input meshes will be created in this mesh.
2627 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2628 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2629 mergeNodesAndElements: if True, equal nodes and elements are merged
2630 mergeTolerance: tolerance for merging nodes
2631 allGroups: forces creation of groups corresponding to every input mesh
2633 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2634 mergeNodesAndElements, mergeTolerance, allGroups,
2635 meshToAppendTo = self.GetMesh() )
2637 # Operations with groups:
2638 # ----------------------
2639 def CreateEmptyGroup(self, elementType, name):
2641 Create an empty standalone mesh group
2644 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2645 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2646 name: the name of the mesh group
2649 :class:`SMESH.SMESH_Group`
2652 return self.mesh.CreateGroup(elementType, name)
2654 def Group(self, grp, name=""):
2656 Create a mesh group based on the geometric object *grp*
2657 and give it a *name*.
2658 If *name* is not defined the name of the geometric group is used
2661 Works like :meth:`GroupOnGeom`.
2664 grp: a geometric group, a vertex, an edge, a face or a solid
2665 name: the name of the mesh group
2668 :class:`SMESH.SMESH_GroupOnGeom`
2671 return self.GroupOnGeom(grp, name)
2673 def GroupOnGeom(self, grp, name="", typ=None):
2675 Create a mesh group based on the geometrical object *grp*
2676 and give it a *name*.
2677 if *name* is not defined the name of the geometric group is used
2680 grp: a geometrical group, a vertex, an edge, a face or a solid
2681 name: the name of the mesh group
2682 typ: the type of elements in the group; either of
2683 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2684 automatically detected by the type of the geometry
2687 :class:`SMESH.SMESH_GroupOnGeom`
2690 AssureGeomPublished( self, grp, name )
2692 name = grp.GetName()
2694 typ = self._groupTypeFromShape( grp )
2695 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2697 def _groupTypeFromShape( self, shape ):
2699 Pivate method to get a type of group on geometry
2701 tgeo = str(shape.GetShapeType())
2702 if tgeo == "VERTEX":
2704 elif tgeo == "EDGE" or tgeo == "WIRE":
2706 elif tgeo == "FACE" or tgeo == "SHELL":
2708 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2710 elif tgeo == "COMPOUND":
2712 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2714 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2715 # simplification of access in geomBuilder: omniORB.registerObjref
2716 from SHAPERSTUDY_utils import getEngine
2719 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2721 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2722 return self._groupTypeFromShape( sub[0] )
2724 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2727 def GroupOnFilter(self, typ, name, filter):
2729 Create a mesh group with given *name* based on the *filter*.
2730 It is a special type of group dynamically updating it's contents during
2734 typ: the type of elements in the group; either of
2735 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2736 name: the name of the mesh group
2737 filter (SMESH.Filter): the filter defining group contents
2740 :class:`SMESH.SMESH_GroupOnFilter`
2743 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2745 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2747 Create a mesh group by the given ids of elements
2750 groupName: the name of the mesh group
2751 elementType: the type of elements in the group; either of
2752 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2753 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2756 :class:`SMESH.SMESH_Group`
2759 group = self.mesh.CreateGroup(elementType, groupName)
2760 if isinstance( elemIDs, Mesh ):
2761 elemIDs = elemIDs.GetMesh()
2762 if hasattr( elemIDs, "GetIDs" ):
2763 if hasattr( elemIDs, "SetMesh" ):
2764 elemIDs.SetMesh( self.GetMesh() )
2765 group.AddFrom( elemIDs )
2773 CritType=FT_Undefined,
2776 UnaryOp=FT_Undefined,
2779 Create a mesh group by the given conditions
2782 groupName: the name of the mesh group
2783 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2784 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2785 Note that the items starting from FT_LessThan are not suitable for CritType.
2786 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2787 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2788 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2789 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2790 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2793 :class:`SMESH.SMESH_GroupOnFilter`
2796 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2797 group = self.MakeGroupByCriterion(groupName, aCriterion)
2800 def MakeGroupByCriterion(self, groupName, Criterion):
2802 Create a mesh group by the given criterion
2805 groupName: the name of the mesh group
2806 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2809 :class:`SMESH.SMESH_GroupOnFilter`
2812 :meth:`smeshBuilder.GetCriterion`
2815 return self.MakeGroupByCriteria( groupName, [Criterion] )
2817 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2819 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2822 groupName: the name of the mesh group
2823 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2824 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2827 :class:`SMESH.SMESH_GroupOnFilter`
2830 :meth:`smeshBuilder.GetCriterion`
2833 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2834 group = self.MakeGroupByFilter(groupName, aFilter)
2837 def MakeGroupByFilter(self, groupName, theFilter):
2839 Create a mesh group by the given filter
2842 groupName (string): the name of the mesh group
2843 theFilter (SMESH.Filter): the filter
2846 :class:`SMESH.SMESH_GroupOnFilter`
2849 :meth:`smeshBuilder.GetFilter`
2852 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2853 #theFilter.SetMesh( self.mesh )
2854 #group.AddFrom( theFilter )
2855 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2858 def RemoveGroup(self, group):
2863 group (SMESH.SMESH_GroupBase): group to remove
2866 self.mesh.RemoveGroup(group)
2868 def RemoveGroupWithContents(self, group):
2870 Remove a group with its contents
2873 group (SMESH.SMESH_GroupBase): group to remove
2876 This operation can create gaps in numeration of nodes or elements.
2877 Call :meth:`RenumberElements` to remove the gaps.
2880 self.mesh.RemoveGroupWithContents(group)
2882 def GetGroups(self, elemType = SMESH.ALL):
2884 Get the list of groups existing in the mesh in the order of creation
2885 (starting from the oldest one)
2888 elemType (SMESH.ElementType): type of elements the groups contain;
2889 by default groups of elements of all types are returned
2892 a list of :class:`SMESH.SMESH_GroupBase`
2895 groups = self.mesh.GetGroups()
2896 if elemType == SMESH.ALL:
2900 if g.GetType() == elemType:
2901 typedGroups.append( g )
2908 Get the number of groups existing in the mesh
2911 the quantity of groups as an integer value
2914 return self.mesh.NbGroups()
2916 def GetGroupNames(self):
2918 Get the list of names of groups existing in the mesh
2924 groups = self.GetGroups()
2926 for group in groups:
2927 names.append(group.GetName())
2930 def GetGroupByName(self, name, elemType = None):
2932 Find groups by name and type
2935 name (string): name of the group of interest
2936 elemType (SMESH.ElementType): type of elements the groups contain;
2937 by default one group of any type is returned;
2938 if elemType == SMESH.ALL then all groups of any type are returned
2941 a list of :class:`SMESH.SMESH_GroupBase`
2945 for group in self.GetGroups():
2946 if group.GetName() == name:
2947 if elemType is None:
2949 if ( elemType == SMESH.ALL or
2950 group.GetType() == elemType ):
2951 groups.append( group )
2954 def UnionGroups(self, group1, group2, name):
2956 Produce a union of two groups.
2957 A new group is created. All mesh elements that are
2958 present in the initial groups are added to the new one
2961 group1 (SMESH.SMESH_GroupBase): a group
2962 group2 (SMESH.SMESH_GroupBase): another group
2965 instance of :class:`SMESH.SMESH_Group`
2968 return self.mesh.UnionGroups(group1, group2, name)
2970 def UnionListOfGroups(self, groups, name):
2972 Produce a union list of groups.
2973 New group is created. All mesh elements that are present in
2974 initial groups are added to the new one
2977 groups: list of :class:`SMESH.SMESH_GroupBase`
2980 instance of :class:`SMESH.SMESH_Group`
2982 return self.mesh.UnionListOfGroups(groups, name)
2984 def IntersectGroups(self, group1, group2, name):
2986 Prodice an intersection of two groups.
2987 A new group is created. All mesh elements that are common
2988 for the two initial groups are added to the new one.
2991 group1 (SMESH.SMESH_GroupBase): a group
2992 group2 (SMESH.SMESH_GroupBase): another group
2995 instance of :class:`SMESH.SMESH_Group`
2998 return self.mesh.IntersectGroups(group1, group2, name)
3000 def IntersectListOfGroups(self, groups, name):
3002 Produce an intersection of groups.
3003 New group is created. All mesh elements that are present in all
3004 initial groups simultaneously are added to the new one
3007 groups: a list of :class:`SMESH.SMESH_GroupBase`
3010 instance of :class:`SMESH.SMESH_Group`
3012 return self.mesh.IntersectListOfGroups(groups, name)
3014 def CutGroups(self, main_group, tool_group, name):
3016 Produce a cut of two groups.
3017 A new group is created. All mesh elements that are present in
3018 the main group but are not present in the tool group are added to the new one
3021 main_group (SMESH.SMESH_GroupBase): a group to cut from
3022 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3025 an instance of :class:`SMESH.SMESH_Group`
3028 return self.mesh.CutGroups(main_group, tool_group, name)
3030 def CutListOfGroups(self, main_groups, tool_groups, name):
3032 Produce a cut of groups.
3033 A new group is created. All mesh elements that are present in main groups
3034 but do not present in tool groups are added to the new one
3037 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3038 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3041 an instance of :class:`SMESH.SMESH_Group`
3044 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3046 def CreateDimGroup(self, groups, elemType, name,
3047 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3049 Create a standalone group of entities basing on nodes of other groups.
3052 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3053 elemType: a type of elements to include to the new group; either of
3054 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3055 name: a name of the new group.
3056 nbCommonNodes: a criterion of inclusion of an element to the new group
3057 basing on number of element nodes common with reference *groups*.
3058 Meaning of possible values are:
3060 - SMESH.ALL_NODES - include if all nodes are common,
3061 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3062 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3063 - SMEHS.MAJORITY - include if half of nodes or more are common.
3064 underlyingOnly: if *True* (default), an element is included to the
3065 new group provided that it is based on nodes of an element of *groups*;
3066 in this case the reference *groups* are supposed to be of higher dimension
3067 than *elemType*, which can be useful for example to get all faces lying on
3068 volumes of the reference *groups*.
3071 an instance of :class:`SMESH.SMESH_Group`
3074 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3076 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3078 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3080 Distribute all faces of the mesh among groups using sharp edges and optionally
3081 existing 1D elements as group boundaries.
3084 sharpAngle: edge is considered sharp if an angle between normals of
3085 adjacent faces is more than \a sharpAngle in degrees.
3086 createEdges (boolean): to create 1D elements for detected sharp edges.
3087 useExistingEdges (boolean): to use existing edges as group boundaries
3089 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3091 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3092 self.mesh.SetParameters(Parameters)
3093 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3095 def ConvertToStandalone(self, group):
3097 Convert group on geom into standalone group
3100 return self.mesh.ConvertToStandalone(group)
3102 # Get some info about mesh:
3103 # ------------------------
3105 def GetLog(self, clearAfterGet):
3107 Return the log of nodes and elements added or removed
3108 since the previous clear of the log.
3111 clearAfterGet: log is emptied after Get (safe if concurrents access)
3114 list of SMESH.log_block structures { commandType, number, coords, indexes }
3117 return self.mesh.GetLog(clearAfterGet)
3121 Clear the log of nodes and elements added or removed since the previous
3122 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3125 self.mesh.ClearLog()
3127 def SetAutoColor(self, theAutoColor):
3129 Toggle auto color mode on the object.
3130 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3133 theAutoColor (boolean): the flag which toggles auto color mode.
3136 self.mesh.SetAutoColor(theAutoColor)
3138 def GetAutoColor(self):
3140 Get flag of object auto color mode.
3146 return self.mesh.GetAutoColor()
3153 integer value, which is the internal Id of the mesh
3156 return self.mesh.GetId()
3158 def HasDuplicatedGroupNamesMED(self):
3160 Check the group names for duplications.
3161 Consider the maximum group name length stored in MED file.
3167 return self.mesh.HasDuplicatedGroupNamesMED()
3169 def GetMeshEditor(self):
3171 Obtain the mesh editor tool
3174 an instance of :class:`SMESH.SMESH_MeshEditor`
3179 def GetIDSource(self, ids, elemType = SMESH.ALL):
3181 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3182 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3186 elemType: type of elements; this parameter is used to distinguish
3187 IDs of nodes from IDs of elements; by default ids are treated as
3188 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3191 an instance of :class:`SMESH.SMESH_IDSource`
3194 call UnRegister() for the returned object as soon as it is no more useful::
3196 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3197 mesh.DoSomething( idSrc )
3201 if isinstance( ids, int ):
3203 return self.editor.MakeIDSource(ids, elemType)
3206 # Get information about mesh contents:
3207 # ------------------------------------
3209 def GetMeshInfo(self, obj = None):
3211 Get the mesh statistic.
3214 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3217 if not obj: obj = self.mesh
3218 return self.smeshpyD.GetMeshInfo(obj)
3222 Return the number of nodes in the mesh
3228 return self.mesh.NbNodes()
3230 def NbElements(self):
3232 Return the number of elements in the mesh
3238 return self.mesh.NbElements()
3240 def Nb0DElements(self):
3242 Return the number of 0d elements in the mesh
3248 return self.mesh.Nb0DElements()
3252 Return the number of ball discrete elements in the mesh
3258 return self.mesh.NbBalls()
3262 Return the number of edges in the mesh
3268 return self.mesh.NbEdges()
3270 def NbEdgesOfOrder(self, elementOrder):
3272 Return the number of edges with the given order in the mesh
3275 elementOrder: the order of elements
3276 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3282 return self.mesh.NbEdgesOfOrder(elementOrder)
3286 Return the number of faces in the mesh
3292 return self.mesh.NbFaces()
3294 def NbFacesOfOrder(self, elementOrder):
3296 Return the number of faces with the given order in the mesh
3299 elementOrder: the order of elements
3300 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3306 return self.mesh.NbFacesOfOrder(elementOrder)
3308 def NbTriangles(self):
3310 Return the number of triangles in the mesh
3316 return self.mesh.NbTriangles()
3318 def NbTrianglesOfOrder(self, elementOrder):
3320 Return the number of triangles with the given order in the mesh
3323 elementOrder: is the order of elements
3324 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3330 return self.mesh.NbTrianglesOfOrder(elementOrder)
3332 def NbBiQuadTriangles(self):
3334 Return the number of biquadratic triangles in the mesh
3340 return self.mesh.NbBiQuadTriangles()
3342 def NbQuadrangles(self):
3344 Return the number of quadrangles in the mesh
3350 return self.mesh.NbQuadrangles()
3352 def NbQuadranglesOfOrder(self, elementOrder):
3354 Return the number of quadrangles with the given order in the mesh
3357 elementOrder: the order of elements
3358 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3364 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3366 def NbBiQuadQuadrangles(self):
3368 Return the number of biquadratic quadrangles in the mesh
3374 return self.mesh.NbBiQuadQuadrangles()
3376 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3378 Return the number of polygons of given order in the mesh
3381 elementOrder: the order of elements
3382 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3388 return self.mesh.NbPolygonsOfOrder(elementOrder)
3390 def NbVolumes(self):
3392 Return the number of volumes in the mesh
3398 return self.mesh.NbVolumes()
3401 def NbVolumesOfOrder(self, elementOrder):
3403 Return the number of volumes with the given order in the mesh
3406 elementOrder: the order of elements
3407 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3413 return self.mesh.NbVolumesOfOrder(elementOrder)
3417 Return the number of tetrahedrons in the mesh
3423 return self.mesh.NbTetras()
3425 def NbTetrasOfOrder(self, elementOrder):
3427 Return the number of tetrahedrons with the given order in the mesh
3430 elementOrder: the order of elements
3431 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3437 return self.mesh.NbTetrasOfOrder(elementOrder)
3441 Return the number of hexahedrons in the mesh
3447 return self.mesh.NbHexas()
3449 def NbHexasOfOrder(self, elementOrder):
3451 Return the number of hexahedrons with the given order in the mesh
3454 elementOrder: the order of elements
3455 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3461 return self.mesh.NbHexasOfOrder(elementOrder)
3463 def NbTriQuadraticHexas(self):
3465 Return the number of triquadratic hexahedrons in the mesh
3471 return self.mesh.NbTriQuadraticHexas()
3473 def NbPyramids(self):
3475 Return the number of pyramids in the mesh
3481 return self.mesh.NbPyramids()
3483 def NbPyramidsOfOrder(self, elementOrder):
3485 Return the number of pyramids with the given order in the mesh
3488 elementOrder: the order of elements
3489 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3495 return self.mesh.NbPyramidsOfOrder(elementOrder)
3499 Return the number of prisms in the mesh
3505 return self.mesh.NbPrisms()
3507 def NbPrismsOfOrder(self, elementOrder):
3509 Return the number of prisms with the given order in the mesh
3512 elementOrder: the order of elements
3513 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3519 return self.mesh.NbPrismsOfOrder(elementOrder)
3521 def NbHexagonalPrisms(self):
3523 Return the number of hexagonal prisms in the mesh
3529 return self.mesh.NbHexagonalPrisms()
3531 def NbPolyhedrons(self):
3533 Return the number of polyhedrons in the mesh
3539 return self.mesh.NbPolyhedrons()
3541 def NbSubMesh(self):
3543 Return the number of submeshes in the mesh
3549 return self.mesh.NbSubMesh()
3551 def GetElementsId(self):
3553 Return the list of all mesh elements IDs
3556 the list of integer values
3559 :meth:`GetElementsByType`
3562 return self.mesh.GetElementsId()
3564 def GetElementsByType(self, elementType):
3566 Return the list of IDs of mesh elements with the given type
3569 elementType (SMESH.ElementType): the required type of elements
3572 list of integer values
3575 return self.mesh.GetElementsByType(elementType)
3577 def GetNodesId(self):
3579 Return the list of mesh nodes IDs
3582 the list of integer values
3585 return self.mesh.GetNodesId()
3587 # Get the information about mesh elements:
3588 # ------------------------------------
3590 def GetElementType(self, id, iselem=True):
3592 Return the type of mesh element or node
3595 the value from :class:`SMESH.ElementType` enumeration.
3596 Return SMESH.ALL if element or node with the given ID does not exist
3599 return self.mesh.GetElementType(id, iselem)
3601 def GetElementGeomType(self, id):
3603 Return the geometric type of mesh element
3606 the value from :class:`SMESH.EntityType` enumeration.
3609 return self.mesh.GetElementGeomType(id)
3611 def GetElementShape(self, id):
3613 Return the shape type of mesh element
3616 the value from :class:`SMESH.GeometryType` enumeration.
3619 return self.mesh.GetElementShape(id)
3621 def GetSubMeshElementsId(self, Shape):
3623 Return the list of sub-mesh elements IDs
3626 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3627 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3630 list of integer values
3633 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3634 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3637 return self.mesh.GetSubMeshElementsId(ShapeID)
3639 def GetSubMeshNodesId(self, Shape, all):
3641 Return the list of sub-mesh nodes IDs
3644 Shape: a geom object (sub-shape).
3645 *Shape* must be the sub-shape of a :meth:`GetShape`
3646 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3649 list of integer values
3652 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3653 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3656 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3658 def GetSubMeshElementType(self, Shape):
3660 Return type of elements on given shape
3663 Shape: a geom object (sub-shape).
3664 *Shape* must be a sub-shape of a ShapeToMesh()
3667 :class:`SMESH.ElementType`
3670 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3671 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3674 return self.mesh.GetSubMeshElementType(ShapeID)
3678 Get the mesh description
3684 return self.mesh.Dump()
3687 # Get the information about nodes and elements of a mesh by its IDs:
3688 # -----------------------------------------------------------
3690 def GetNodeXYZ(self, id):
3692 Get XYZ coordinates of a node.
3693 If there is no node for the given ID - return an empty list
3696 list of float values
3699 return self.mesh.GetNodeXYZ(id)
3701 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3703 Return list of IDs of inverse elements for the given node.
3704 If there is no node for the given ID - return an empty list
3708 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3711 list of integer values
3714 return self.mesh.GetNodeInverseElements(id,elemType)
3716 def GetNodePosition(self,NodeID):
3718 Return the position of a node on the shape
3721 :class:`SMESH.NodePosition`
3724 return self.mesh.GetNodePosition(NodeID)
3726 def GetElementPosition(self,ElemID):
3728 Return the position of an element on the shape
3731 :class:`SMESH.ElementPosition`
3734 return self.mesh.GetElementPosition(ElemID)
3736 def GetShapeID(self, id):
3738 Return the ID of the shape, on which the given node was generated.
3741 an integer value > 0 or -1 if there is no node for the given
3742 ID or the node is not assigned to any geometry
3745 return self.mesh.GetShapeID(id)
3747 def GetShapeIDForElem(self,id):
3749 Return the ID of the shape, on which the given element was generated.
3752 an integer value > 0 or -1 if there is no element for the given
3753 ID or the element is not assigned to any geometry
3756 return self.mesh.GetShapeIDForElem(id)
3758 def GetElemNbNodes(self, id):
3760 Return the number of nodes of the given element
3763 an integer value > 0 or -1 if there is no element for the given ID
3766 return self.mesh.GetElemNbNodes(id)
3768 def GetElemNode(self, id, index):
3770 Return the node ID the given (zero based) index for the given element.
3772 * If there is no element for the given ID - return -1.
3773 * If there is no node for the given index - return -2.
3776 id (int): element ID
3777 index (int): node index within the element
3780 an integer value (ID)
3783 :meth:`GetElemNodes`
3786 return self.mesh.GetElemNode(id, index)
3788 def GetElemNodes(self, id):
3790 Return the IDs of nodes of the given element
3793 a list of integer values
3796 return self.mesh.GetElemNodes(id)
3798 def IsMediumNode(self, elementID, nodeID):
3800 Return true if the given node is the medium node in the given quadratic element
3803 return self.mesh.IsMediumNode(elementID, nodeID)
3805 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3807 Return true if the given node is the medium node in one of quadratic elements
3810 nodeID: ID of the node
3811 elementType: the type of elements to check a state of the node, either of
3812 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3815 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3817 def ElemNbEdges(self, id):
3819 Return the number of edges for the given element
3822 return self.mesh.ElemNbEdges(id)
3824 def ElemNbFaces(self, id):
3826 Return the number of faces for the given element
3829 return self.mesh.ElemNbFaces(id)
3831 def GetElemFaceNodes(self,elemId, faceIndex):
3833 Return nodes of given face (counted from zero) for given volumic element.
3836 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3838 def GetFaceNormal(self, faceId, normalized=False):
3840 Return three components of normal of given mesh face
3841 (or an empty array in KO case)
3844 return self.mesh.GetFaceNormal(faceId,normalized)
3846 def FindElementByNodes(self, nodes):
3848 Return an element based on all given nodes.
3851 return self.mesh.FindElementByNodes(nodes)
3853 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3855 Return elements including all given nodes.
3858 return self.mesh.GetElementsByNodes( nodes, elemType )
3860 def IsPoly(self, id):
3862 Return true if the given element is a polygon
3865 return self.mesh.IsPoly(id)
3867 def IsQuadratic(self, id):
3869 Return true if the given element is quadratic
3872 return self.mesh.IsQuadratic(id)
3874 def GetBallDiameter(self, id):
3876 Return diameter of a ball discrete element or zero in case of an invalid *id*
3879 return self.mesh.GetBallDiameter(id)
3881 def BaryCenter(self, id):
3883 Return XYZ coordinates of the barycenter of the given element.
3884 If there is no element for the given ID - return an empty list
3887 a list of three double values
3890 :meth:`smeshBuilder.GetGravityCenter`
3893 return self.mesh.BaryCenter(id)
3895 def GetIdsFromFilter(self, filter, meshParts=[] ):
3897 Pass mesh elements through the given filter and return IDs of fitting elements
3900 filter: :class:`SMESH.Filter`
3901 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3907 :meth:`SMESH.Filter.GetIDs`
3908 :meth:`SMESH.Filter.GetElementsIdFromParts`
3911 filter.SetMesh( self.mesh )
3914 if isinstance( meshParts, Mesh ):
3915 filter.SetMesh( meshParts.GetMesh() )
3916 return theFilter.GetIDs()
3917 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3918 meshParts = [ meshParts ]
3919 return filter.GetElementsIdFromParts( meshParts )
3921 return filter.GetIDs()
3923 # Get mesh measurements information:
3924 # ------------------------------------
3926 def GetFreeBorders(self):
3928 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3929 Return a list of special structures (borders).
3932 a list of :class:`SMESH.FreeEdges.Border`
3935 aFilterMgr = self.smeshpyD.CreateFilterManager()
3936 aPredicate = aFilterMgr.CreateFreeEdges()
3937 aPredicate.SetMesh(self.mesh)
3938 aBorders = aPredicate.GetBorders()
3939 aFilterMgr.UnRegister()
3942 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3944 Get minimum distance between two nodes, elements or distance to the origin
3947 id1: first node/element id
3948 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3949 isElem1: *True* if *id1* is element id, *False* if it is node id
3950 isElem2: *True* if *id2* is element id, *False* if it is node id
3953 minimum distance value
3955 :meth:`GetMinDistance`
3958 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3959 return aMeasure.value
3961 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3963 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3966 id1: first node/element id
3967 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3968 isElem1: *True* if *id1* is element id, *False* if it is node id
3969 isElem2: *True* if *id2* is element id, *False* if it is node id
3972 :class:`SMESH.Measure` structure
3978 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3980 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3983 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3985 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3990 aMeasurements = self.smeshpyD.CreateMeasurements()
3991 aMeasure = aMeasurements.MinDistance(id1, id2)
3992 genObjUnRegister([aMeasurements,id1, id2])
3995 def BoundingBox(self, objects=None, isElem=False):
3997 Get bounding box of the specified object(s)
4000 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4001 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4002 *False* specifies that *objects* are nodes
4005 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4008 :meth:`GetBoundingBox()`
4011 result = self.GetBoundingBox(objects, isElem)
4015 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4018 def GetBoundingBox(self, objects=None, isElem=False):
4020 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4023 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4024 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4025 False means that *objects* are nodes
4028 :class:`SMESH.Measure` structure
4031 :meth:`BoundingBox()`
4035 objects = [self.mesh]
4036 elif isinstance(objects, tuple):
4037 objects = list(objects)
4038 if not isinstance(objects, list):
4040 if len(objects) > 0 and isinstance(objects[0], int):
4043 unRegister = genObjUnRegister()
4045 if isinstance(o, Mesh):
4046 srclist.append(o.mesh)
4047 elif hasattr(o, "_narrow"):
4048 src = o._narrow(SMESH.SMESH_IDSource)
4049 if src: srclist.append(src)
4051 elif isinstance(o, list):
4053 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4055 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4056 unRegister.set( srclist[-1] )
4059 aMeasurements = self.smeshpyD.CreateMeasurements()
4060 unRegister.set( aMeasurements )
4061 aMeasure = aMeasurements.BoundingBox(srclist)
4064 # Mesh edition (SMESH_MeshEditor functionality):
4065 # ---------------------------------------------
4067 def RemoveElements(self, IDsOfElements):
4069 Remove the elements from the mesh by ids
4072 IDsOfElements: is a list of ids of elements to remove
4078 This operation can create gaps in numeration of elements.
4079 Call :meth:`RenumberElements` to remove the gaps.
4082 return self.editor.RemoveElements(IDsOfElements)
4084 def RemoveNodes(self, IDsOfNodes):
4086 Remove nodes from mesh by ids
4089 IDsOfNodes: is a list of ids of nodes to remove
4095 This operation can create gaps in numeration of nodes.
4096 Call :meth:`RenumberElements` to remove the gaps.
4099 return self.editor.RemoveNodes(IDsOfNodes)
4101 def RemoveOrphanNodes(self):
4103 Remove all orphan (free) nodes from mesh
4106 number of the removed nodes
4109 This operation can create gaps in numeration of nodes.
4110 Call :meth:`RenumberElements` to remove the gaps.
4113 return self.editor.RemoveOrphanNodes()
4115 def AddNode(self, x, y, z):
4117 Add a node to the mesh by coordinates
4123 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4124 if hasVars: self.mesh.SetParameters(Parameters)
4125 return self.editor.AddNode( x, y, z)
4127 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4129 Create a 0D element on a node with given number.
4132 IDOfNode: the ID of node for creation of the element.
4133 DuplicateElements: to add one more 0D element to a node or not
4136 ID of the new 0D element
4139 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4141 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4143 Create 0D elements on all nodes of the given elements except those
4144 nodes on which a 0D element already exists.
4147 theObject: an object on whose nodes 0D elements will be created.
4148 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4149 theGroupName: optional name of a group to add 0D elements created
4150 and/or found on nodes of *theObject*.
4151 DuplicateElements: to add one more 0D element to a node or not
4154 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4155 IDs of new and/or found 0D elements. IDs of 0D elements
4156 can be retrieved from the returned object by
4157 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4160 unRegister = genObjUnRegister()
4161 if isinstance( theObject, Mesh ):
4162 theObject = theObject.GetMesh()
4163 elif isinstance( theObject, list ):
4164 theObject = self.GetIDSource( theObject, SMESH.ALL )
4165 unRegister.set( theObject )
4166 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4168 def AddBall(self, IDOfNode, diameter):
4170 Create a ball element on a node with given ID.
4173 IDOfNode: the ID of node for creation of the element.
4174 diameter: the bal diameter.
4177 ID of the new ball element
4180 return self.editor.AddBall( IDOfNode, diameter )
4182 def AddEdge(self, IDsOfNodes):
4184 Create a linear or quadratic edge (this is determined
4185 by the number of given nodes).
4188 IDsOfNodes: list of node IDs for creation of the element.
4189 The order of nodes in this list should correspond to
4190 the :ref:`connectivity convention <connectivity_page>`.
4196 return self.editor.AddEdge(IDsOfNodes)
4198 def AddFace(self, IDsOfNodes):
4200 Create a linear or quadratic face (this is determined
4201 by the number of given nodes).
4204 IDsOfNodes: list of node IDs for creation of the element.
4205 The order of nodes in this list should correspond to
4206 the :ref:`connectivity convention <connectivity_page>`.
4212 return self.editor.AddFace(IDsOfNodes)
4214 def AddPolygonalFace(self, IdsOfNodes):
4216 Add a polygonal face defined by a list of node IDs
4219 IdsOfNodes: the list of node IDs for creation of the element.
4225 return self.editor.AddPolygonalFace(IdsOfNodes)
4227 def AddQuadPolygonalFace(self, IdsOfNodes):
4229 Add a quadratic polygonal face defined by a list of node IDs
4232 IdsOfNodes: the list of node IDs for creation of the element;
4233 corner nodes follow first.
4239 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4241 def AddVolume(self, IDsOfNodes):
4243 Create both simple and quadratic volume (this is determined
4244 by the number of given nodes).
4247 IDsOfNodes: list of node IDs for creation of the element.
4248 The order of nodes in this list should correspond to
4249 the :ref:`connectivity convention <connectivity_page>`.
4252 ID of the new volumic element
4255 return self.editor.AddVolume(IDsOfNodes)
4257 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4259 Create a volume of many faces, giving nodes for each face.
4262 IdsOfNodes: list of node IDs for volume creation, face by face.
4263 Quantities: list of integer values, Quantities[i]
4264 gives the quantity of nodes in face number i.
4267 ID of the new volumic element
4270 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4272 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4274 Create a volume of many faces, giving the IDs of the existing faces.
4277 The created volume will refer only to the nodes
4278 of the given faces, not to the faces themselves.
4281 IdsOfFaces: the list of face IDs for volume creation.
4284 ID of the new volumic element
4287 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4290 def SetNodeOnVertex(self, NodeID, Vertex):
4292 Bind a node to a vertex
4296 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4299 True if succeed else raises an exception
4302 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4303 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4307 self.editor.SetNodeOnVertex(NodeID, VertexID)
4308 except SALOME.SALOME_Exception as inst:
4309 raise ValueError(inst.details.text)
4313 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4315 Store the node position on an edge
4319 Edge: an edge (GEOM.GEOM_Object) or edge ID
4320 paramOnEdge: a parameter on the edge where the node is located
4323 True if succeed else raises an exception
4326 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4327 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4331 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4332 except SALOME.SALOME_Exception as inst:
4333 raise ValueError(inst.details.text)
4336 def SetNodeOnFace(self, NodeID, Face, u, v):
4338 Store node position on a face
4342 Face: a face (GEOM.GEOM_Object) or face ID
4343 u: U parameter on the face where the node is located
4344 v: V parameter on the face where the node is located
4347 True if succeed else raises an exception
4350 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4351 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4355 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4356 except SALOME.SALOME_Exception as inst:
4357 raise ValueError(inst.details.text)
4360 def SetNodeInVolume(self, NodeID, Solid):
4362 Bind a node to a solid
4366 Solid: a solid (GEOM.GEOM_Object) or solid ID
4369 True if succeed else raises an exception
4372 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4373 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4377 self.editor.SetNodeInVolume(NodeID, SolidID)
4378 except SALOME.SALOME_Exception as inst:
4379 raise ValueError(inst.details.text)
4382 def SetMeshElementOnShape(self, ElementID, Shape):
4384 Bind an element to a shape
4387 ElementID: an element ID
4388 Shape: a shape (GEOM.GEOM_Object) or shape ID
4391 True if succeed else raises an exception
4394 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4395 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4399 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4400 except SALOME.SALOME_Exception as inst:
4401 raise ValueError(inst.details.text)
4405 def MoveNode(self, NodeID, x, y, z):
4407 Move the node with the given id
4410 NodeID: the id of the node
4411 x: a new X coordinate
4412 y: a new Y coordinate
4413 z: a new Z coordinate
4416 True if succeed else False
4419 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4420 if hasVars: self.mesh.SetParameters(Parameters)
4421 return self.editor.MoveNode(NodeID, x, y, z)
4423 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4425 Find the node closest to a point and moves it to a point location
4428 x: the X coordinate of a point
4429 y: the Y coordinate of a point
4430 z: the Z coordinate of a point
4431 NodeID: if specified (>0), the node with this ID is moved,
4432 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4435 the ID of a moved node
4438 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4439 if hasVars: self.mesh.SetParameters(Parameters)
4440 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4442 def FindNodeClosestTo(self, x, y, z):
4444 Find the node closest to a point
4447 x: the X coordinate of a point
4448 y: the Y coordinate of a point
4449 z: the Z coordinate of a point
4455 return self.editor.FindNodeClosestTo(x, y, z)
4457 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4459 Find the elements where a point lays IN or ON
4462 x,y,z (float): coordinates of the point
4463 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4464 means elements of any type excluding nodes, discrete and 0D elements.
4465 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4468 list of IDs of found elements
4471 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4473 return self.editor.FindElementsByPoint(x, y, z, elementType)
4475 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4477 Project a point to a mesh object.
4478 Return ID of an element of given type where the given point is projected
4479 and coordinates of the projection point.
4480 In the case if nothing found, return -1 and []
4482 if isinstance( meshObject, Mesh ):
4483 meshObject = meshObject.GetMesh()
4485 meshObject = self.GetMesh()
4486 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4488 def GetPointState(self, x, y, z):
4490 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4491 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4492 UNKNOWN state means that either mesh is wrong or the analysis fails.
4495 return self.editor.GetPointState(x, y, z)
4497 def IsManifold(self):
4499 Check if a 2D mesh is manifold
4502 return self.editor.IsManifold()
4504 def IsCoherentOrientation2D(self):
4506 Check if orientation of 2D elements is coherent
4509 return self.editor.IsCoherentOrientation2D()
4511 def Get1DBranches( self, edges, startNode = 0 ):
4513 Partition given 1D elements into groups of contiguous edges.
4514 A node where number of meeting edges != 2 is a group end.
4515 An optional startNode is used to orient groups it belongs to.
4518 A list of edge groups and a list of corresponding node groups,
4519 where the group is a list of IDs of edges or nodes, like follows
4520 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4521 If a group is closed, the first and last nodes of the group are same.
4523 if isinstance( edges, Mesh ):
4524 edges = edges.GetMesh()
4525 unRegister = genObjUnRegister()
4526 if isinstance( edges, list ):
4527 edges = self.GetIDSource( edges, SMESH.EDGE )
4528 unRegister.set( edges )
4529 return self.editor.Get1DBranches( edges, startNode )
4531 def FindSharpEdges( self, angle, addExisting=False ):
4533 Return sharp edges of faces and non-manifold ones.
4534 Optionally add existing edges.
4537 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4538 addExisting: to return existing edges (1D elements) as well
4541 list of FaceEdge structures
4543 angle = ParseParameters( angle )[0]
4544 return self.editor.FindSharpEdges( angle, addExisting )
4546 def MeshToPassThroughAPoint(self, x, y, z):
4548 Find the node closest to a point and moves it to a point location
4551 x: the X coordinate of a point
4552 y: the Y coordinate of a point
4553 z: the Z coordinate of a point
4556 the ID of a moved node
4559 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4561 def InverseDiag(self, NodeID1, NodeID2):
4563 Replace two neighbour triangles sharing Node1-Node2 link
4564 with the triangles built on the same 4 nodes but having other common link.
4567 NodeID1: the ID of the first node
4568 NodeID2: the ID of the second node
4571 False if proper faces were not found
4573 return self.editor.InverseDiag(NodeID1, NodeID2)
4575 def DeleteDiag(self, NodeID1, NodeID2):
4577 Replace two neighbour triangles sharing *Node1-Node2* link
4578 with a quadrangle built on the same 4 nodes.
4581 NodeID1: ID of the first node
4582 NodeID2: ID of the second node
4585 False if proper faces were not found
4588 This operation can create gaps in numeration of elements.
4589 Call :meth:`RenumberElements` to remove the gaps.
4592 return self.editor.DeleteDiag(NodeID1, NodeID2)
4594 def Reorient(self, IDsOfElements=None):
4596 Reorient elements by ids
4599 IDsOfElements: if undefined reorients all mesh elements
4602 True if succeed else False
4605 if IDsOfElements == None:
4606 IDsOfElements = self.GetElementsId()
4607 return self.editor.Reorient(IDsOfElements)
4609 def ReorientObject(self, theObject):
4611 Reorient all elements of the object
4614 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4617 True if succeed else False
4620 if ( isinstance( theObject, Mesh )):
4621 theObject = theObject.GetMesh()
4622 return self.editor.ReorientObject(theObject)
4624 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4626 Reorient faces contained in *the2DObject*.
4629 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4630 theDirection: a desired direction of normal of *theFace*.
4631 It can be either a GEOM vector or a list of coordinates [x,y,z].
4632 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4633 compared with theDirection. It can be either ID of face or a point
4634 by which the face will be found. The point can be given as either
4635 a GEOM vertex or a list of point coordinates.
4638 number of reoriented faces
4641 unRegister = genObjUnRegister()
4643 if isinstance( the2DObject, Mesh ):
4644 the2DObject = the2DObject.GetMesh()
4645 if isinstance( the2DObject, list ):
4646 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4647 unRegister.set( the2DObject )
4648 # check theDirection
4649 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4650 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4651 if isinstance( theDirection, list ):
4652 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4653 # prepare theFace and thePoint
4654 theFace = theFaceOrPoint
4655 thePoint = PointStruct(0,0,0)
4656 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4657 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4659 if isinstance( theFaceOrPoint, list ):
4660 thePoint = PointStruct( *theFaceOrPoint )
4662 if isinstance( theFaceOrPoint, PointStruct ):
4663 thePoint = theFaceOrPoint
4665 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4667 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4669 Reorient faces according to adjacent volumes.
4672 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4673 either IDs of faces or face groups.
4674 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4675 theOutsideNormal: to orient faces to have their normals
4676 pointing either *outside* or *inside* the adjacent volumes.
4679 number of reoriented faces.
4682 unRegister = genObjUnRegister()
4684 if not isinstance( the2DObject, list ):
4685 the2DObject = [ the2DObject ]
4686 elif the2DObject and isinstance( the2DObject[0], int ):
4687 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4688 unRegister.set( the2DObject )
4689 the2DObject = [ the2DObject ]
4690 for i,obj2D in enumerate( the2DObject ):
4691 if isinstance( obj2D, Mesh ):
4692 the2DObject[i] = obj2D.GetMesh()
4693 if isinstance( obj2D, list ):
4694 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4695 unRegister.set( the2DObject[i] )
4697 if isinstance( the3DObject, Mesh ):
4698 the3DObject = the3DObject.GetMesh()
4699 if isinstance( the3DObject, list ):
4700 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4701 unRegister.set( the3DObject )
4702 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4704 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4706 Fuse the neighbouring triangles into quadrangles.
4709 IDsOfElements: The triangles to be fused.
4710 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4711 applied to possible quadrangles to choose a neighbour to fuse with.
4712 Note that not all items of :class:`SMESH.FunctorType` corresponds
4713 to numerical functors.
4714 MaxAngle: is the maximum angle between element normals at which the fusion
4715 is still performed; theMaxAngle is measured in radians.
4716 Also it could be a name of variable which defines angle in degrees.
4719 True in case of success, False otherwise.
4722 This operation can create gaps in numeration of elements.
4723 Call :meth:`RenumberElements` to remove the gaps.
4726 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4727 self.mesh.SetParameters(Parameters)
4728 if not IDsOfElements:
4729 IDsOfElements = self.GetElementsId()
4730 Functor = self.smeshpyD.GetFunctor(theCriterion)
4731 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4733 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4735 Fuse the neighbouring triangles of the object into quadrangles
4738 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4739 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4740 applied to possible quadrangles to choose a neighbour to fuse with.
4741 Note that not all items of :class:`SMESH.FunctorType` corresponds
4742 to numerical functors.
4743 MaxAngle: a max angle between element normals at which the fusion
4744 is still performed; theMaxAngle is measured in radians.
4747 True in case of success, False otherwise.
4750 This operation can create gaps in numeration of elements.
4751 Call :meth:`RenumberElements` to remove the gaps.
4754 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4755 self.mesh.SetParameters(Parameters)
4756 if isinstance( theObject, Mesh ):
4757 theObject = theObject.GetMesh()
4758 Functor = self.smeshpyD.GetFunctor(theCriterion)
4759 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4761 def QuadToTri (self, IDsOfElements, theCriterion = None):
4763 Split quadrangles into triangles.
4766 IDsOfElements: the faces to be splitted.
4767 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4768 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4769 value, then quadrangles will be split by the smallest diagonal.
4770 Note that not all items of :class:`SMESH.FunctorType` corresponds
4771 to numerical functors.
4774 True in case of success, False otherwise.
4777 This operation can create gaps in numeration of elements.
4778 Call :meth:`RenumberElements` to remove the gaps.
4780 if IDsOfElements == []:
4781 IDsOfElements = self.GetElementsId()
4782 if theCriterion is None:
4783 theCriterion = FT_MaxElementLength2D
4784 Functor = self.smeshpyD.GetFunctor(theCriterion)
4785 return self.editor.QuadToTri(IDsOfElements, Functor)
4787 def QuadToTriObject (self, theObject, theCriterion = None):
4789 Split quadrangles into triangles.
4792 theObject: the object from which the list of elements is taken,
4793 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4794 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4795 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4796 value, then quadrangles will be split by the smallest diagonal.
4797 Note that not all items of :class:`SMESH.FunctorType` corresponds
4798 to numerical functors.
4801 True in case of success, False otherwise.
4804 This operation can create gaps in numeration of elements.
4805 Call :meth:`RenumberElements` to remove the gaps.
4807 if ( isinstance( theObject, Mesh )):
4808 theObject = theObject.GetMesh()
4809 if theCriterion is None:
4810 theCriterion = FT_MaxElementLength2D
4811 Functor = self.smeshpyD.GetFunctor(theCriterion)
4812 return self.editor.QuadToTriObject(theObject, Functor)
4814 def QuadTo4Tri (self, theElements=[]):
4816 Split each of given quadrangles into 4 triangles. A node is added at the center of
4820 theElements: the faces to be splitted. This can be either
4821 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4822 or a list of face IDs. By default all quadrangles are split
4825 This operation can create gaps in numeration of elements.
4826 Call :meth:`RenumberElements` to remove the gaps.
4828 unRegister = genObjUnRegister()
4829 if isinstance( theElements, Mesh ):
4830 theElements = theElements.mesh
4831 elif not theElements:
4832 theElements = self.mesh
4833 elif isinstance( theElements, list ):
4834 theElements = self.GetIDSource( theElements, SMESH.FACE )
4835 unRegister.set( theElements )
4836 return self.editor.QuadTo4Tri( theElements )
4838 def SplitQuad (self, IDsOfElements, Diag13):
4840 Split quadrangles into triangles.
4843 IDsOfElements: the faces to be splitted
4844 Diag13 (boolean): is used to choose a diagonal for splitting.
4847 True in case of success, False otherwise.
4850 This operation can create gaps in numeration of elements.
4851 Call :meth:`RenumberElements` to remove the gaps.
4853 if IDsOfElements == []:
4854 IDsOfElements = self.GetElementsId()
4855 return self.editor.SplitQuad(IDsOfElements, Diag13)
4857 def SplitQuadObject (self, theObject, Diag13):
4859 Split quadrangles into triangles.
4862 theObject: the object from which the list of elements is taken,
4863 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4864 Diag13 (boolean): is used to choose a diagonal for splitting.
4867 True in case of success, False otherwise.
4870 This operation can create gaps in numeration of elements.
4871 Call :meth:`RenumberElements` to remove the gaps.
4873 if ( isinstance( theObject, Mesh )):
4874 theObject = theObject.GetMesh()
4875 return self.editor.SplitQuadObject(theObject, Diag13)
4877 def BestSplit (self, IDOfQuad, theCriterion):
4879 Find a better splitting of the given quadrangle.
4882 IDOfQuad: the ID of the quadrangle to be splitted.
4883 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4884 choose a diagonal for splitting.
4885 Note that not all items of :class:`SMESH.FunctorType` corresponds
4886 to numerical functors.
4889 * 1 if 1-3 diagonal is better,
4890 * 2 if 2-4 diagonal is better,
4891 * 0 if error occurs.
4894 This operation can create gaps in numeration of elements.
4895 Call :meth:`RenumberElements` to remove the gaps.
4897 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4899 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4901 Split volumic elements into tetrahedrons
4904 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4905 method: flags passing splitting method:
4906 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4907 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4910 This operation can create gaps in numeration of elements.
4911 Call :meth:`RenumberElements` to remove the gaps.
4913 unRegister = genObjUnRegister()
4914 if isinstance( elems, Mesh ):
4915 elems = elems.GetMesh()
4916 if ( isinstance( elems, list )):
4917 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4918 unRegister.set( elems )
4919 self.editor.SplitVolumesIntoTetra(elems, method)
4922 def SplitBiQuadraticIntoLinear(self, elems=None):
4924 Split bi-quadratic elements into linear ones without creation of additional nodes:
4926 - bi-quadratic triangle will be split into 3 linear quadrangles;
4927 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4928 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4930 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4931 will be split in order to keep the mesh conformal.
4934 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4935 if None (default), all bi-quadratic elements will be split
4938 This operation can create gaps in numeration of elements.
4939 Call :meth:`RenumberElements` to remove the gaps.
4941 unRegister = genObjUnRegister()
4942 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4943 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4944 unRegister.set( elems )
4946 elems = [ self.GetMesh() ]
4947 if isinstance( elems, Mesh ):
4948 elems = [ elems.GetMesh() ]
4949 if not isinstance( elems, list ):
4951 self.editor.SplitBiQuadraticIntoLinear( elems )
4953 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4954 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4956 Split hexahedra into prisms
4959 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4960 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4961 gives a normal vector defining facets to split into triangles.
4962 *startHexPoint* can be either a triple of coordinates or a vertex.
4963 facetNormal: a normal to a facet to split into triangles of a
4964 hexahedron found by *startHexPoint*.
4965 *facetNormal* can be either a triple of coordinates or an edge.
4966 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4967 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4968 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4969 to *startHexPoint* are split, else *startHexPoint*
4970 is used to find the facet to split in all domains present in *elems*.
4973 This operation can create gaps in numeration of elements.
4974 Call :meth:`RenumberElements` to remove the gaps.
4977 unRegister = genObjUnRegister()
4978 if isinstance( elems, Mesh ):
4979 elems = elems.GetMesh()
4980 if ( isinstance( elems, list )):
4981 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4982 unRegister.set( elems )
4985 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4986 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4987 elif isinstance( startHexPoint, list ):
4988 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4991 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4992 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4993 elif isinstance( facetNormal, list ):
4994 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4997 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4999 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5001 def SplitQuadsNearTriangularFacets(self):
5003 Split quadrangle faces near triangular facets of volumes
5006 This operation can create gaps in numeration of elements.
5007 Call :meth:`RenumberElements` to remove the gaps.
5009 faces_array = self.GetElementsByType(SMESH.FACE)
5010 for face_id in faces_array:
5011 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5012 quad_nodes = self.mesh.GetElemNodes(face_id)
5013 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5014 isVolumeFound = False
5015 for node1_elem in node1_elems:
5016 if not isVolumeFound:
5017 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5018 nb_nodes = self.GetElemNbNodes(node1_elem)
5019 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5020 volume_elem = node1_elem
5021 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5022 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5023 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5024 isVolumeFound = True
5025 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5026 self.SplitQuad([face_id], False) # diagonal 2-4
5027 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5028 isVolumeFound = True
5029 self.SplitQuad([face_id], True) # diagonal 1-3
5030 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5031 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5032 isVolumeFound = True
5033 self.SplitQuad([face_id], True) # diagonal 1-3
5035 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5037 Split hexahedrons into tetrahedrons.
5039 This operation uses :doc:`pattern_mapping` functionality for splitting.
5042 theObject: the object from which the list of hexahedrons is taken;
5043 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5044 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5045 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5046 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5047 key-point will be mapped into *theNode001*-th node of each volume.
5048 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5051 True in case of success, False otherwise.
5054 This operation can create gaps in numeration of elements.
5055 Call :meth:`RenumberElements` to remove the gaps.
5063 # (0,0,1) 4.---------.7 * |
5070 # (0,0,0) 0.---------.3
5071 pattern_tetra = "!!! Nb of points: \n 8 \n\
5081 !!! Indices of points of 6 tetras: \n\
5089 pattern = self.smeshpyD.GetPattern()
5090 isDone = pattern.LoadFromFile(pattern_tetra)
5092 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5095 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5096 isDone = pattern.MakeMesh(self.mesh, False, False)
5097 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5099 # split quafrangle faces near triangular facets of volumes
5100 self.SplitQuadsNearTriangularFacets()
5104 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5106 Split hexahedrons into prisms.
5108 Uses the :doc:`pattern_mapping` functionality for splitting.
5111 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5112 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5113 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5114 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5115 will be mapped into the *theNode001* -th node of each volume.
5116 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5119 True in case of success, False otherwise.
5122 This operation can create gaps in numeration of elements.
5123 Call :meth:`RenumberElements` to remove the gaps.
5125 # Pattern: 5.---------.6
5130 # (0,0,1) 4.---------.7 |
5137 # (0,0,0) 0.---------.3
5138 pattern_prism = "!!! Nb of points: \n 8 \n\
5148 !!! Indices of points of 2 prisms: \n\
5152 pattern = self.smeshpyD.GetPattern()
5153 isDone = pattern.LoadFromFile(pattern_prism)
5155 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5158 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5159 isDone = pattern.MakeMesh(self.mesh, False, False)
5160 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5162 # Split quafrangle faces near triangular facets of volumes
5163 self.SplitQuadsNearTriangularFacets()
5167 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5168 MaxNbOfIterations, MaxAspectRatio, Method):
5173 IDsOfElements: the list if ids of elements to smooth
5174 IDsOfFixedNodes: the list of ids of fixed nodes.
5175 Note that nodes built on edges and boundary nodes are always fixed.
5176 MaxNbOfIterations: the maximum number of iterations
5177 MaxAspectRatio: varies in range [1.0, inf]
5178 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5179 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5182 True in case of success, False otherwise.
5185 if IDsOfElements == []:
5186 IDsOfElements = self.GetElementsId()
5187 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5188 self.mesh.SetParameters(Parameters)
5189 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5190 MaxNbOfIterations, MaxAspectRatio, Method)
5192 def SmoothObject(self, theObject, IDsOfFixedNodes,
5193 MaxNbOfIterations, MaxAspectRatio, Method):
5195 Smooth elements which belong to the given object
5198 theObject: the object to smooth
5199 IDsOfFixedNodes: the list of ids of fixed nodes.
5200 Note that nodes built on edges and boundary nodes are always fixed.
5201 MaxNbOfIterations: the maximum number of iterations
5202 MaxAspectRatio: varies in range [1.0, inf]
5203 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5204 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5207 True in case of success, False otherwise.
5210 if ( isinstance( theObject, Mesh )):
5211 theObject = theObject.GetMesh()
5212 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5213 MaxNbOfIterations, MaxAspectRatio, Method)
5215 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5216 MaxNbOfIterations, MaxAspectRatio, Method):
5218 Parametrically smooth the given elements
5221 IDsOfElements: the list if ids of elements to smooth
5222 IDsOfFixedNodes: the list of ids of fixed nodes.
5223 Note that nodes built on edges and boundary nodes are always fixed.
5224 MaxNbOfIterations: the maximum number of iterations
5225 MaxAspectRatio: varies in range [1.0, inf]
5226 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5227 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5230 True in case of success, False otherwise.
5233 if IDsOfElements == []:
5234 IDsOfElements = self.GetElementsId()
5235 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5236 self.mesh.SetParameters(Parameters)
5237 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5238 MaxNbOfIterations, MaxAspectRatio, Method)
5240 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5241 MaxNbOfIterations, MaxAspectRatio, Method):
5243 Parametrically smooth the elements which belong to the given object
5246 theObject: the object to smooth
5247 IDsOfFixedNodes: the list of ids of fixed nodes.
5248 Note that nodes built on edges and boundary nodes are always fixed.
5249 MaxNbOfIterations: the maximum number of iterations
5250 MaxAspectRatio: varies in range [1.0, inf]
5251 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5252 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5255 True in case of success, False otherwise.
5258 if ( isinstance( theObject, Mesh )):
5259 theObject = theObject.GetMesh()
5260 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5261 MaxNbOfIterations, MaxAspectRatio, Method)
5263 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5265 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5266 them with quadratic with the same id.
5269 theForce3d: method of new node creation:
5271 * False - the medium node lies at the geometrical entity from which the mesh element is built
5272 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5273 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5274 theToBiQuad: If True, converts the mesh to bi-quadratic
5277 :class:`SMESH.ComputeError` which can hold a warning
5280 If *theSubMesh* is provided, the mesh can become non-conformal
5283 This operation can create gaps in numeration of nodes or elements.
5284 Call :meth:`RenumberElements` to remove the gaps.
5287 if isinstance( theSubMesh, Mesh ):
5288 theSubMesh = theSubMesh.mesh
5290 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5293 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5295 self.editor.ConvertToQuadratic(theForce3d)
5296 error = self.editor.GetLastError()
5297 if error and error.comment:
5298 print(error.comment)
5301 def ConvertFromQuadratic(self, theSubMesh=None):
5303 Convert the mesh from quadratic to ordinary,
5304 deletes old quadratic elements,
5305 replacing them with ordinary mesh elements with the same id.
5308 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5311 If *theSubMesh* is provided, the mesh can become non-conformal
5314 This operation can create gaps in numeration of nodes or elements.
5315 Call :meth:`RenumberElements` to remove the gaps.
5319 self.editor.ConvertFromQuadraticObject(theSubMesh)
5321 return self.editor.ConvertFromQuadratic()
5323 def Make2DMeshFrom3D(self):
5325 Create 2D mesh as skin on boundary faces of a 3D mesh
5328 True if operation has been completed successfully, False otherwise
5331 return self.editor.Make2DMeshFrom3D()
5333 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5334 toCopyElements=False, toCopyExistingBondary=False):
5336 Create missing boundary elements
5339 elements: elements whose boundary is to be checked:
5340 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5341 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5342 dimension: defines type of boundary elements to create, either of
5343 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5344 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5345 groupName: a name of group to store created boundary elements in,
5346 "" means not to create the group
5347 meshName: a name of new mesh to store created boundary elements in,
5348 "" means not to create the new mesh
5349 toCopyElements: if True, the checked elements will be copied into
5350 the new mesh else only boundary elements will be copied into the new mesh
5351 toCopyExistingBondary: if True, not only new but also pre-existing
5352 boundary elements will be copied into the new mesh
5355 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5358 unRegister = genObjUnRegister()
5359 if isinstance( elements, Mesh ):
5360 elements = elements.GetMesh()
5361 if ( isinstance( elements, list )):
5362 elemType = SMESH.ALL
5363 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5364 elements = self.editor.MakeIDSource(elements, elemType)
5365 unRegister.set( elements )
5366 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5367 toCopyElements,toCopyExistingBondary)
5368 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5371 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5372 toCopyAll=False, groups=[]):
5374 Create missing boundary elements around either the whole mesh or
5378 dimension: defines type of boundary elements to create, either of
5379 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5380 groupName: a name of group to store all boundary elements in,
5381 "" means not to create the group
5382 meshName: a name of a new mesh, which is a copy of the initial
5383 mesh + created boundary elements; "" means not to create the new mesh
5384 toCopyAll: if True, the whole initial mesh will be copied into
5385 the new mesh else only boundary elements will be copied into the new mesh
5386 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5389 tuple( long, mesh, group )
5390 - long - number of added boundary elements
5391 - mesh - the :class:`Mesh` where elements were added to
5392 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5395 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5397 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5398 return nb, mesh, group
5400 def RenumberNodes(self):
5402 Renumber mesh nodes to remove unused node IDs
5404 self.editor.RenumberNodes()
5406 def RenumberElements(self):
5408 Renumber mesh elements to remove unused element IDs
5410 self.editor.RenumberElements()
5412 def _getIdSourceList(self, arg, idType, unRegister):
5414 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5416 if arg and isinstance( arg, list ):
5417 if isinstance( arg[0], int ):
5418 arg = self.GetIDSource( arg, idType )
5419 unRegister.set( arg )
5420 elif isinstance( arg[0], Mesh ):
5421 arg[0] = arg[0].GetMesh()
5422 elif isinstance( arg, Mesh ):
5424 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5428 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5429 MakeGroups=False, TotalAngle=False):
5431 Generate new elements by rotation of the given elements and nodes around the axis
5434 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5435 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5436 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5437 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5438 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5439 which defines angle in degrees
5440 NbOfSteps: the number of steps
5441 Tolerance: tolerance
5442 MakeGroups: forces the generation of new groups from existing ones
5443 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5444 of all steps, else - size of each step
5447 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5450 unRegister = genObjUnRegister()
5451 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5452 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5453 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5455 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5456 Axis = self.smeshpyD.GetAxisStruct( Axis )
5457 if isinstance( Axis, list ):
5458 Axis = SMESH.AxisStruct( *Axis )
5460 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5461 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5462 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5463 self.mesh.SetParameters(Parameters)
5464 if TotalAngle and NbOfSteps:
5465 AngleInRadians /= NbOfSteps
5466 return self.editor.RotationSweepObjects( nodes, edges, faces,
5467 Axis, AngleInRadians,
5468 NbOfSteps, Tolerance, MakeGroups)
5470 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5471 MakeGroups=False, TotalAngle=False):
5473 Generate new elements by rotation of the elements around the axis
5476 IDsOfElements: the list of ids of elements to sweep
5477 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5478 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5479 NbOfSteps: the number of steps
5480 Tolerance: tolerance
5481 MakeGroups: forces the generation of new groups from existing ones
5482 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5483 of all steps, else - size of each step
5486 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5489 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5490 AngleInRadians, NbOfSteps, Tolerance,
5491 MakeGroups, TotalAngle)
5493 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5494 MakeGroups=False, TotalAngle=False):
5496 Generate new elements by rotation of the elements of object around the axis
5497 theObject object which elements should be sweeped.
5498 It can be a mesh, a sub mesh or a group.
5501 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5502 AngleInRadians: the angle of Rotation
5503 NbOfSteps: number of steps
5504 Tolerance: tolerance
5505 MakeGroups: forces the generation of new groups from existing ones
5506 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5507 of all steps, else - size of each step
5510 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5513 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5514 AngleInRadians, NbOfSteps, Tolerance,
5515 MakeGroups, TotalAngle )
5517 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5518 MakeGroups=False, TotalAngle=False):
5520 Generate new elements by rotation of the elements of object around the axis
5521 theObject object which elements should be sweeped.
5522 It can be a mesh, a sub mesh or a group.
5525 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5526 AngleInRadians: the angle of Rotation
5527 NbOfSteps: number of steps
5528 Tolerance: tolerance
5529 MakeGroups: forces the generation of new groups from existing ones
5530 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5531 of all steps, else - size of each step
5534 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5535 empty list otherwise
5538 return self.RotationSweepObjects([],theObject,[], Axis,
5539 AngleInRadians, NbOfSteps, Tolerance,
5540 MakeGroups, TotalAngle)
5542 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5543 MakeGroups=False, TotalAngle=False):
5545 Generate new elements by rotation of the elements of object around the axis
5546 theObject object which elements should be sweeped.
5547 It can be a mesh, a sub mesh or a group.
5550 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5551 AngleInRadians: the angle of Rotation
5552 NbOfSteps: number of steps
5553 Tolerance: tolerance
5554 MakeGroups: forces the generation of new groups from existing ones
5555 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5556 of all steps, else - size of each step
5559 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5562 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5563 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5565 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5566 scaleFactors=[], linearVariation=False, basePoint=[],
5567 angles=[], anglesVariation=False):
5569 Generate new elements by extrusion of the given elements and nodes
5572 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5573 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5574 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5575 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5576 the direction and value of extrusion for one step (the total extrusion
5577 length will be NbOfSteps * ||StepVector||)
5578 NbOfSteps: the number of steps
5579 MakeGroups: forces the generation of new groups from existing ones
5580 scaleFactors: optional scale factors to apply during extrusion
5581 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5582 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5583 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5584 nodes and elements being extruded is used as the scaling center.
5587 - a list of tree components of the point or
5590 angles: list of angles in radians. Nodes at each extrusion step are rotated
5591 around *basePoint*, additionally to previous steps.
5592 anglesVariation: forces the computation of rotation angles as linear
5593 variation of the given *angles* along path steps
5595 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5597 Example: :ref:`tui_extrusion`
5599 unRegister = genObjUnRegister()
5600 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5601 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5602 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5604 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5605 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5606 if isinstance( StepVector, list ):
5607 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5609 if isinstance( basePoint, int):
5610 xyz = self.GetNodeXYZ( basePoint )
5612 raise RuntimeError("Invalid node ID: %s" % basePoint)
5614 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5615 basePoint = self.geompyD.PointCoordinates( basePoint )
5617 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5618 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5619 angles,angleParameters,hasVars = ParseAngles(angles)
5620 Parameters = StepVector.PS.parameters + var_separator + \
5621 Parameters + var_separator + \
5622 scaleParameters + var_separator + angleParameters
5623 self.mesh.SetParameters(Parameters)
5625 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5626 StepVector, NbOfSteps, MakeGroups,
5627 scaleFactors, linearVariation, basePoint,
5628 angles, anglesVariation )
5631 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5633 Generate new elements by extrusion of the elements with given ids
5636 IDsOfElements: the list of ids of elements or nodes for extrusion
5637 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5638 the direction and value of extrusion for one step (the total extrusion
5639 length will be NbOfSteps * ||StepVector||)
5640 NbOfSteps: the number of steps
5641 MakeGroups: forces the generation of new groups from existing ones
5642 IsNodes: is True if elements with given ids are nodes
5645 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5647 Example: :ref:`tui_extrusion`
5650 if IsNodes: n = IDsOfElements
5651 else : e,f, = IDsOfElements,IDsOfElements
5652 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5654 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5655 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5657 Generate new elements by extrusion along the normal to a discretized surface or wire
5660 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5661 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5662 StepSize: length of one extrusion step (the total extrusion
5663 length will be *NbOfSteps* *StepSize*).
5664 NbOfSteps: number of extrusion steps.
5665 ByAverageNormal: if True each node is translated by *StepSize*
5666 along the average of the normal vectors to the faces sharing the node;
5667 else each node is translated along the same average normal till
5668 intersection with the plane got by translation of the face sharing
5669 the node along its own normal by *StepSize*.
5670 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5671 for every node of *Elements*.
5672 MakeGroups: forces generation of new groups from existing ones.
5673 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5674 is not yet implemented. This parameter is used if *Elements* contains
5675 both faces and edges, i.e. *Elements* is a Mesh.
5678 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5679 empty list otherwise.
5680 Example: :ref:`tui_extrusion`
5683 unRegister = genObjUnRegister()
5684 if isinstance( Elements, Mesh ):
5685 Elements = [ Elements.GetMesh() ]
5686 if isinstance( Elements, list ):
5688 raise RuntimeError("Elements empty!")
5689 if isinstance( Elements[0], Mesh ):
5690 Elements = [ Elements[0].GetMesh() ]
5691 if isinstance( Elements[0], int ):
5692 Elements = self.GetIDSource( Elements, SMESH.ALL )
5693 unRegister.set( Elements )
5694 if not isinstance( Elements, list ):
5695 Elements = [ Elements ]
5696 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5697 self.mesh.SetParameters(Parameters)
5698 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5699 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5701 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5703 Generate new elements by extrusion of the elements or nodes which belong to the object
5706 theObject: the object whose elements or nodes should be processed.
5707 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5708 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5709 the direction and value of extrusion for one step (the total extrusion
5710 length will be NbOfSteps * ||StepVector||)
5711 NbOfSteps: the number of steps
5712 MakeGroups: forces the generation of new groups from existing ones
5713 IsNodes: is True if elements to extrude are nodes
5716 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5717 Example: :ref:`tui_extrusion`
5721 if IsNodes: n = theObject
5722 else : e,f, = theObject,theObject
5723 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5725 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5727 Generate new elements by extrusion of edges which belong to the object
5730 theObject: object whose 1D elements should be processed.
5731 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5732 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5733 the direction and value of extrusion for one step (the total extrusion
5734 length will be NbOfSteps * ||StepVector||)
5735 NbOfSteps: the number of steps
5736 MakeGroups: to generate new groups from existing ones
5739 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5740 Example: :ref:`tui_extrusion`
5743 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5745 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5747 Generate new elements by extrusion of faces which belong to the object
5750 theObject: object whose 2D elements should be processed.
5751 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5752 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5753 the direction and value of extrusion for one step (the total extrusion
5754 length will be NbOfSteps * ||StepVector||)
5755 NbOfSteps: the number of steps
5756 MakeGroups: forces the generation of new groups from existing ones
5759 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5760 Example: :ref:`tui_extrusion`
5763 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5765 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5766 ExtrFlags, SewTolerance, MakeGroups=False):
5768 Generate new elements by extrusion of the elements with given ids
5771 IDsOfElements: is ids of elements
5772 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5773 the direction and value of extrusion for one step (the total extrusion
5774 length will be NbOfSteps * ||StepVector||)
5775 NbOfSteps: the number of steps
5776 ExtrFlags: sets flags for extrusion
5777 SewTolerance: uses for comparing locations of nodes if flag
5778 EXTRUSION_FLAG_SEW is set
5779 MakeGroups: forces the generation of new groups from existing ones
5782 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5785 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5786 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5787 if isinstance( StepVector, list ):
5788 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5789 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5790 ExtrFlags, SewTolerance, MakeGroups)
5792 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5793 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5794 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5795 ScaleFactors=[], ScalesVariation=False):
5797 Generate new elements by extrusion of the given elements and nodes along the path.
5798 The path of extrusion must be a meshed edge.
5801 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5802 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5803 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5804 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5805 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
5806 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5807 HasAngles: not used obsolete
5808 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5809 around *basePoint*, additionally to previous steps.
5810 LinearVariation: forces the computation of rotation angles as linear
5811 variation of the given Angles along path steps
5812 HasRefPoint: allows using the reference point
5813 RefPoint: optional scaling and rotation center (mass center of the extruded
5814 elements by default). The User can specify any point as the Reference Point.
5815 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5816 MakeGroups: forces the generation of new groups from existing ones
5817 ScaleFactors: optional scale factors to apply during extrusion
5818 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5819 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5822 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5823 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5824 Example: :ref:`tui_extrusion_along_path`
5827 unRegister = genObjUnRegister()
5828 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5829 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5830 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5832 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5833 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5834 if isinstance( RefPoint, list ):
5835 if not RefPoint: RefPoint = [0,0,0]
5836 RefPoint = SMESH.PointStruct( *RefPoint )
5837 if isinstance( PathObject, Mesh ):
5838 PathObject = PathObject.GetMesh()
5839 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5840 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5841 Parameters = AnglesParameters + var_separator + \
5842 RefPoint.parameters + var_separator + ScalesParameters
5843 self.mesh.SetParameters(Parameters)
5844 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5845 PathObject, PathShape, NodeStart,
5846 HasAngles, Angles, LinearVariation,
5847 HasRefPoint, RefPoint, MakeGroups,
5848 ScaleFactors, ScalesVariation)
5850 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5851 HasAngles=False, Angles=[], LinearVariation=False,
5852 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5853 ElemType=SMESH.FACE):
5855 Generate new elements by extrusion of the given elements.
5856 The path of extrusion must be a meshed edge.
5859 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5860 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5861 NodeStart: the start node from Path. Defines the direction of extrusion
5862 HasAngles: not used obsolete
5863 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5864 around *basePoint*, additionally to previous steps.
5865 LinearVariation: forces the computation of rotation angles as linear
5866 variation of the given Angles along path steps
5867 HasRefPoint: allows using the reference point
5868 RefPoint: the reference point around which the elements are rotated (the mass
5869 center of the elements by default).
5870 The User can specify any point as the Reference Point.
5871 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5872 MakeGroups: forces the generation of new groups from existing ones
5873 ElemType: type of elements for extrusion (if param Base is a mesh)
5876 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5877 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5878 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5880 Example: :ref:`tui_extrusion_along_path`
5884 if ElemType == SMESH.NODE: n = Base
5885 if ElemType == SMESH.EDGE: e = Base
5886 if ElemType == SMESH.FACE: f = Base
5887 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5888 HasAngles, Angles, LinearVariation,
5889 HasRefPoint, RefPoint, MakeGroups)
5890 if MakeGroups: return gr,er
5893 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5894 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5895 MakeGroups=False, LinearVariation=False):
5897 Generate new elements by extrusion of the given elements.
5898 The path of extrusion must be a meshed edge.
5901 IDsOfElements: ids of elements
5902 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5903 PathShape: shape (edge) defines the sub-mesh for the path
5904 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5905 HasAngles: not used obsolete
5906 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5907 around *basePoint*, additionally to previous steps.
5908 HasRefPoint: allows using the reference point
5909 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5910 The User can specify any point as the Reference Point.
5911 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5912 MakeGroups: forces the generation of new groups from existing ones
5913 LinearVariation: forces the computation of rotation angles as linear
5914 variation of the given Angles along path steps
5917 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5918 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5919 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5920 Example: :ref:`tui_extrusion_along_path`
5923 if not IDsOfElements:
5924 IDsOfElements = [ self.GetMesh() ]
5925 n,e,f = [],IDsOfElements,IDsOfElements
5926 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5927 NodeStart, HasAngles, Angles,
5929 HasRefPoint, RefPoint, MakeGroups)
5930 if MakeGroups: return gr,er
5933 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5934 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5935 MakeGroups=False, LinearVariation=False):
5937 Generate new elements by extrusion of the elements which belong to the object.
5938 The path of extrusion must be a meshed edge.
5941 theObject: the object whose elements should be processed.
5942 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5943 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5944 PathShape: shape (edge) defines the sub-mesh for the path
5945 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5946 HasAngles: not used obsolete
5947 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5948 around *basePoint*, additionally to previous steps.
5949 HasRefPoint: allows using the reference point
5950 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5951 The User can specify any point as the Reference Point.
5952 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5953 MakeGroups: forces the generation of new groups from existing ones
5954 LinearVariation: forces the computation of rotation angles as linear
5955 variation of the given Angles along path steps
5958 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5959 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5960 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5961 Example: :ref:`tui_extrusion_along_path`
5964 n,e,f = [],theObject,theObject
5965 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5966 HasAngles, Angles, LinearVariation,
5967 HasRefPoint, RefPoint, MakeGroups)
5968 if MakeGroups: return gr,er
5971 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5972 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5973 MakeGroups=False, LinearVariation=False):
5975 Generate new elements by extrusion of mesh segments which belong to the object.
5976 The path of extrusion must be a meshed edge.
5979 theObject: the object whose 1D elements should be processed.
5980 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5981 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5982 PathShape: shape (edge) defines the sub-mesh for the path
5983 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5984 HasAngles: not used obsolete
5985 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5986 around *basePoint*, additionally to previous steps.
5987 HasRefPoint: allows using the reference point
5988 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5989 The User can specify any point as the Reference Point.
5990 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5991 MakeGroups: forces the generation of new groups from existing ones
5992 LinearVariation: forces the computation of rotation angles as linear
5993 variation of the given Angles along path steps
5996 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5997 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5998 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5999 Example: :ref:`tui_extrusion_along_path`
6002 n,e,f = [],theObject,[]
6003 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6004 HasAngles, Angles, LinearVariation,
6005 HasRefPoint, RefPoint, MakeGroups)
6006 if MakeGroups: return gr,er
6009 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6010 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6011 MakeGroups=False, LinearVariation=False):
6013 Generate new elements by extrusion of faces which belong to the object.
6014 The path of extrusion must be a meshed edge.
6017 theObject: the object whose 2D elements should be processed.
6018 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6019 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6020 PathShape: shape (edge) defines the sub-mesh for the path
6021 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6022 HasAngles: not used obsolete
6023 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6024 around *basePoint*, additionally to previous steps.
6025 HasRefPoint: allows using the reference point
6026 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6027 The User can specify any point as the Reference Point.
6028 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6029 MakeGroups: forces the generation of new groups from existing ones
6030 LinearVariation: forces the computation of rotation angles as linear
6031 variation of the given Angles along path steps
6034 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6035 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6036 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6037 Example: :ref:`tui_extrusion_along_path`
6040 n,e,f = [],[],theObject
6041 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6042 HasAngles, Angles, LinearVariation,
6043 HasRefPoint, RefPoint, MakeGroups)
6044 if MakeGroups: return gr,er
6047 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6049 Create a symmetrical copy of mesh elements
6052 IDsOfElements: list of elements ids
6053 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6054 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6055 If the *Mirror* is a geom object this parameter is unnecessary
6056 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6057 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6060 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6063 if IDsOfElements == []:
6064 IDsOfElements = self.GetElementsId()
6065 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6066 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6067 theMirrorType = Mirror._mirrorType
6069 self.mesh.SetParameters(Mirror.parameters)
6070 if Copy and MakeGroups:
6071 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6072 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6075 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6077 Create a new mesh by a symmetrical copy of mesh elements
6080 IDsOfElements: the list of elements ids
6081 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6082 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6083 If the *Mirror* is a geom object this parameter is unnecessary
6084 MakeGroups: to generate new groups from existing ones
6085 NewMeshName: a name of the new mesh to create
6088 instance of class :class:`Mesh`
6091 if IDsOfElements == []:
6092 IDsOfElements = self.GetElementsId()
6093 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6094 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6095 theMirrorType = Mirror._mirrorType
6097 self.mesh.SetParameters(Mirror.parameters)
6098 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6099 MakeGroups, NewMeshName)
6100 return Mesh(self.smeshpyD,self.geompyD,mesh)
6102 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6104 Create a symmetrical copy of the object
6107 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6108 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6109 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6110 If the *Mirror* is a geom object this parameter is unnecessary
6111 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6112 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6115 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6118 if ( isinstance( theObject, Mesh )):
6119 theObject = theObject.GetMesh()
6120 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6121 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6122 theMirrorType = Mirror._mirrorType
6124 self.mesh.SetParameters(Mirror.parameters)
6125 if Copy and MakeGroups:
6126 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6127 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6130 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6132 Create a new mesh by a symmetrical copy of the object
6135 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6136 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6137 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6138 If the *Mirror* is a geom object this parameter is unnecessary
6139 MakeGroups: forces the generation of new groups from existing ones
6140 NewMeshName: the name of the new mesh to create
6143 instance of class :class:`Mesh`
6146 if ( isinstance( theObject, Mesh )):
6147 theObject = theObject.GetMesh()
6148 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6149 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6150 theMirrorType = Mirror._mirrorType
6152 self.mesh.SetParameters(Mirror.parameters)
6153 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6154 MakeGroups, NewMeshName)
6155 return Mesh( self.smeshpyD,self.geompyD,mesh )
6157 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6159 Translate the elements
6162 IDsOfElements: list of elements ids
6163 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6164 Copy: allows copying the translated elements
6165 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6168 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6171 if IDsOfElements == []:
6172 IDsOfElements = self.GetElementsId()
6173 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6174 Vector = self.smeshpyD.GetDirStruct(Vector)
6175 if isinstance( Vector, list ):
6176 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6177 self.mesh.SetParameters(Vector.PS.parameters)
6178 if Copy and MakeGroups:
6179 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6180 self.editor.Translate(IDsOfElements, Vector, Copy)
6183 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6185 Create a new mesh of translated elements
6188 IDsOfElements: list of elements ids
6189 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6190 MakeGroups: forces the generation of new groups from existing ones
6191 NewMeshName: the name of the newly created mesh
6194 instance of class :class:`Mesh`
6197 if IDsOfElements == []:
6198 IDsOfElements = self.GetElementsId()
6199 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6200 Vector = self.smeshpyD.GetDirStruct(Vector)
6201 if isinstance( Vector, list ):
6202 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6203 self.mesh.SetParameters(Vector.PS.parameters)
6204 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6205 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6207 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6209 Translate the object
6212 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6213 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6214 Copy: allows copying the translated elements
6215 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6218 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6221 if ( isinstance( theObject, Mesh )):
6222 theObject = theObject.GetMesh()
6223 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6224 Vector = self.smeshpyD.GetDirStruct(Vector)
6225 if isinstance( Vector, list ):
6226 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6227 self.mesh.SetParameters(Vector.PS.parameters)
6228 if Copy and MakeGroups:
6229 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6230 self.editor.TranslateObject(theObject, Vector, Copy)
6233 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6235 Create a new mesh from the translated object
6238 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6239 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6240 MakeGroups: forces the generation of new groups from existing ones
6241 NewMeshName: the name of the newly created mesh
6244 instance of class :class:`Mesh`
6247 if isinstance( theObject, Mesh ):
6248 theObject = theObject.GetMesh()
6249 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6250 Vector = self.smeshpyD.GetDirStruct(Vector)
6251 if isinstance( Vector, list ):
6252 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6253 self.mesh.SetParameters(Vector.PS.parameters)
6254 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6255 return Mesh( self.smeshpyD, self.geompyD, mesh )
6259 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6264 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6265 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6266 theScaleFact: list of 1-3 scale factors for axises
6267 Copy: allows copying the translated elements
6268 MakeGroups: forces the generation of new groups from existing
6272 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6273 empty list otherwise
6275 unRegister = genObjUnRegister()
6276 if ( isinstance( theObject, Mesh )):
6277 theObject = theObject.GetMesh()
6278 if ( isinstance( theObject, list )):
6279 theObject = self.GetIDSource(theObject, SMESH.ALL)
6280 unRegister.set( theObject )
6281 if ( isinstance( thePoint, list )):
6282 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6283 if ( isinstance( theScaleFact, float )):
6284 theScaleFact = [theScaleFact]
6285 if ( isinstance( theScaleFact, int )):
6286 theScaleFact = [ float(theScaleFact)]
6288 self.mesh.SetParameters(thePoint.parameters)
6290 if Copy and MakeGroups:
6291 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6292 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6295 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6297 Create a new mesh from the translated object
6300 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6301 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6302 theScaleFact: list of 1-3 scale factors for axises
6303 MakeGroups: forces the generation of new groups from existing ones
6304 NewMeshName: the name of the newly created mesh
6307 instance of class :class:`Mesh`
6309 unRegister = genObjUnRegister()
6310 if (isinstance(theObject, Mesh)):
6311 theObject = theObject.GetMesh()
6312 if ( isinstance( theObject, list )):
6313 theObject = self.GetIDSource(theObject,SMESH.ALL)
6314 unRegister.set( theObject )
6315 if ( isinstance( thePoint, list )):
6316 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6317 if ( isinstance( theScaleFact, float )):
6318 theScaleFact = [theScaleFact]
6319 if ( isinstance( theScaleFact, int )):
6320 theScaleFact = [ float(theScaleFact)]
6322 self.mesh.SetParameters(thePoint.parameters)
6323 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6324 MakeGroups, NewMeshName)
6325 return Mesh( self.smeshpyD, self.geompyD, mesh )
6329 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6334 IDsOfElements: list of elements ids
6335 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6336 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6337 Copy: allows copying the rotated elements
6338 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6341 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6345 if IDsOfElements == []:
6346 IDsOfElements = self.GetElementsId()
6347 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6348 Axis = self.smeshpyD.GetAxisStruct(Axis)
6349 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6350 Parameters = Axis.parameters + var_separator + Parameters
6351 self.mesh.SetParameters(Parameters)
6352 if Copy and MakeGroups:
6353 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6354 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6357 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6359 Create a new mesh of rotated elements
6362 IDsOfElements: list of element ids
6363 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6364 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6365 MakeGroups: forces the generation of new groups from existing ones
6366 NewMeshName: the name of the newly created mesh
6369 instance of class :class:`Mesh`
6372 if IDsOfElements == []:
6373 IDsOfElements = self.GetElementsId()
6374 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6375 Axis = self.smeshpyD.GetAxisStruct(Axis)
6376 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6377 Parameters = Axis.parameters + var_separator + Parameters
6378 self.mesh.SetParameters(Parameters)
6379 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6380 MakeGroups, NewMeshName)
6381 return Mesh( self.smeshpyD, self.geompyD, mesh )
6383 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6388 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6389 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6390 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6391 Copy: allows copying the rotated elements
6392 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6395 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6398 if (isinstance(theObject, Mesh)):
6399 theObject = theObject.GetMesh()
6400 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6401 Axis = self.smeshpyD.GetAxisStruct(Axis)
6402 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6403 Parameters = Axis.parameters + ":" + Parameters
6404 self.mesh.SetParameters(Parameters)
6405 if Copy and MakeGroups:
6406 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6407 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6410 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6412 Create a new mesh from the rotated object
6415 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6416 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6417 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6418 MakeGroups: forces the generation of new groups from existing ones
6419 NewMeshName: the name of the newly created mesh
6422 instance of class :class:`Mesh`
6425 if (isinstance( theObject, Mesh )):
6426 theObject = theObject.GetMesh()
6427 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6428 Axis = self.smeshpyD.GetAxisStruct(Axis)
6429 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6430 Parameters = Axis.parameters + ":" + Parameters
6431 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6432 MakeGroups, NewMeshName)
6433 self.mesh.SetParameters(Parameters)
6434 return Mesh( self.smeshpyD, self.geompyD, mesh )
6436 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6438 Create an offset mesh from the given 2D object
6441 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6442 theValue (float): signed offset size
6443 MakeGroups (boolean): forces the generation of new groups from existing ones
6444 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6445 False means to remove original elements.
6446 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6449 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6452 if isinstance( theObject, Mesh ):
6453 theObject = theObject.GetMesh()
6454 theValue,Parameters,hasVars = ParseParameters(Value)
6455 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6456 self.mesh.SetParameters(Parameters)
6458 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6461 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6463 Find groups of adjacent nodes within Tolerance.
6466 Tolerance (float): the value of tolerance
6467 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6468 corner and medium nodes in separate groups thus preventing
6469 their further merge.
6472 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6475 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6477 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6478 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6480 Find groups of adjacent nodes within Tolerance.
6483 Tolerance: the value of tolerance
6484 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6485 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6486 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6487 corner and medium nodes in separate groups thus preventing
6488 their further merge.
6491 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6494 unRegister = genObjUnRegister()
6495 if not isinstance( SubMeshOrGroup, list ):
6496 SubMeshOrGroup = [ SubMeshOrGroup ]
6497 for i,obj in enumerate( SubMeshOrGroup ):
6498 if isinstance( obj, Mesh ):
6499 SubMeshOrGroup = [ obj.GetMesh() ]
6501 if isinstance( obj, int ):
6502 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6503 unRegister.set( SubMeshOrGroup )
6506 if not isinstance( exceptNodes, list ):
6507 exceptNodes = [ exceptNodes ]
6508 if exceptNodes and isinstance( exceptNodes[0], int ):
6509 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6510 unRegister.set( exceptNodes )
6512 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6513 exceptNodes, SeparateCornerAndMediumNodes)
6515 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6520 GroupsOfNodes: a list of groups of nodes IDs for merging.
6521 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6522 in all elements and mesh groups by nodes 1 and 25 correspondingly
6523 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6524 If *NodesToKeep* does not include a node to keep for some group to merge,
6525 then the first node in the group is kept.
6526 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6530 This operation can create gaps in numeration of nodes or elements.
6531 Call :meth:`RenumberElements` to remove the gaps.
6533 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6535 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6537 Find the elements built on the same nodes.
6540 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6541 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6545 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6548 unRegister = genObjUnRegister()
6549 if MeshOrSubMeshOrGroup is None:
6550 MeshOrSubMeshOrGroup = [ self.mesh ]
6551 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6552 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6553 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6554 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6555 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6556 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6557 unRegister.set( MeshOrSubMeshOrGroup )
6558 for item in MeshOrSubMeshOrGroup:
6559 if isinstance( item, Mesh ):
6560 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6562 if not isinstance( exceptElements, list ):
6563 exceptElements = [ exceptElements ]
6564 if exceptElements and isinstance( exceptElements[0], int ):
6565 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6566 unRegister.set( exceptElements )
6568 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6570 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6572 Merge elements in each given group.
6575 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6576 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6577 replaced in all mesh groups by elements 1 and 25)
6578 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6579 If *ElementsToKeep* does not include an element to keep for some group to merge,
6580 then the first element in the group is kept.
6583 This operation can create gaps in numeration of elements.
6584 Call :meth:`RenumberElements` to remove the gaps.
6587 unRegister = genObjUnRegister()
6589 if not isinstance( ElementsToKeep, list ):
6590 ElementsToKeep = [ ElementsToKeep ]
6591 if isinstance( ElementsToKeep[0], int ):
6592 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6593 unRegister.set( ElementsToKeep )
6595 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6597 def MergeEqualElements(self):
6599 Leave one element and remove all other elements built on the same nodes.
6602 This operation can create gaps in numeration of elements.
6603 Call :meth:`RenumberElements` to remove the gaps.
6606 self.editor.MergeEqualElements()
6608 def FindFreeBorders(self, ClosedOnly=True):
6610 Returns all or only closed free borders
6613 list of SMESH.FreeBorder's
6616 return self.editor.FindFreeBorders( ClosedOnly )
6618 def FillHole(self, holeNodes, groupName=""):
6620 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6623 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6624 must describe all sequential nodes of the hole border. The first and the last
6625 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6626 groupName (string): name of a group to add new faces
6628 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6632 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6633 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6634 if not isinstance( holeNodes, SMESH.FreeBorder ):
6635 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6636 return self.editor.FillHole( holeNodes, groupName )
6638 def FindCoincidentFreeBorders (self, tolerance=0.):
6640 Return groups of FreeBorder's coincident within the given tolerance.
6643 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6644 size of elements adjacent to free borders being compared is used.
6647 SMESH.CoincidentFreeBorders structure
6650 return self.editor.FindCoincidentFreeBorders( tolerance )
6652 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6654 Sew FreeBorder's of each group
6657 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6658 where each enclosed list contains node IDs of a group of coincident free
6659 borders such that each consequent triple of IDs within a group describes
6660 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6661 last node of a border.
6662 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6663 groups of coincident free borders, each group including two borders.
6664 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6665 polygons if a node of opposite border falls on a face edge, else such
6666 faces are split into several ones.
6667 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6668 polyhedra if a node of opposite border falls on a volume edge, else such
6669 volumes, if any, remain intact and the mesh becomes non-conformal.
6672 a number of successfully sewed groups
6675 This operation can create gaps in numeration of nodes or elements.
6676 Call :meth:`RenumberElements` to remove the gaps.
6679 if freeBorders and isinstance( freeBorders, list ):
6680 # construct SMESH.CoincidentFreeBorders
6681 if isinstance( freeBorders[0], int ):
6682 freeBorders = [freeBorders]
6684 coincidentGroups = []
6685 for nodeList in freeBorders:
6686 if not nodeList or len( nodeList ) % 3:
6687 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6690 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6691 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6692 nodeList = nodeList[3:]
6694 coincidentGroups.append( group )
6696 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6698 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6700 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6701 FirstNodeID2, SecondNodeID2, LastNodeID2,
6702 CreatePolygons, CreatePolyedrs):
6707 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6710 This operation can create gaps in numeration of nodes or elements.
6711 Call :meth:`RenumberElements` to remove the gaps.
6714 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6715 FirstNodeID2, SecondNodeID2, LastNodeID2,
6716 CreatePolygons, CreatePolyedrs)
6718 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6719 FirstNodeID2, SecondNodeID2):
6721 Sew conform free borders
6724 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6727 This operation can create gaps in numeration of elements.
6728 Call :meth:`RenumberElements` to remove the gaps.
6731 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6732 FirstNodeID2, SecondNodeID2)
6734 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6735 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6740 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6743 This operation can create gaps in numeration of elements.
6744 Call :meth:`RenumberElements` to remove the gaps.
6747 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6748 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6750 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6751 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6752 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6754 Sew two sides of a mesh. The nodes belonging to Side1 are
6755 merged with the nodes of elements of Side2.
6756 The number of elements in theSide1 and in theSide2 must be
6757 equal and they should have similar nodal connectivity.
6758 The nodes to merge should belong to side borders and
6759 the first node should be linked to the second.
6762 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6765 This operation can create gaps in numeration of nodes.
6766 Call :meth:`RenumberElements` to remove the gaps.
6769 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6770 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6771 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6773 def ChangeElemNodes(self, ide, newIDs):
6775 Set new nodes for the given element. Number of nodes should be kept.
6782 False if the number of nodes does not correspond to the type of element
6785 return self.editor.ChangeElemNodes(ide, newIDs)
6787 def GetLastCreatedNodes(self):
6789 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6790 created, this method return the list of their IDs.
6791 If new nodes were not created - return empty list
6794 the list of integer values (can be empty)
6797 return self.editor.GetLastCreatedNodes()
6799 def GetLastCreatedElems(self):
6801 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6802 created this method return the list of their IDs.
6803 If new elements were not created - return empty list
6806 the list of integer values (can be empty)
6809 return self.editor.GetLastCreatedElems()
6811 def ClearLastCreated(self):
6813 Forget what nodes and elements were created by the last mesh edition operation
6816 self.editor.ClearLastCreated()
6818 def DoubleElements(self, theElements, theGroupName=""):
6820 Create duplicates of given elements, i.e. create new elements based on the
6821 same nodes as the given ones.
6824 theElements: container of elements to duplicate. It can be a
6825 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6826 or a list of element IDs. If *theElements* is
6827 a :class:`Mesh`, elements of highest dimension are duplicated
6828 theGroupName: a name of group to contain the generated elements.
6829 If a group with such a name already exists, the new elements
6830 are added to the existing group, else a new group is created.
6831 If *theGroupName* is empty, new elements are not added
6835 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6836 None if *theGroupName* == "".
6839 unRegister = genObjUnRegister()
6840 if isinstance( theElements, Mesh ):
6841 theElements = theElements.mesh
6842 elif isinstance( theElements, list ):
6843 theElements = self.GetIDSource( theElements, SMESH.ALL )
6844 unRegister.set( theElements )
6845 return self.editor.DoubleElements(theElements, theGroupName)
6847 def DoubleNodes(self, theNodes, theModifiedElems):
6849 Create a hole in a mesh by doubling the nodes of some particular elements
6852 theNodes: IDs of nodes to be doubled
6853 theModifiedElems: IDs of elements to be updated by the new (doubled)
6854 nodes. If list of element identifiers is empty then nodes are doubled but
6855 they not assigned to elements
6858 True if operation has been completed successfully, False otherwise
6861 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6863 def DoubleNode(self, theNodeId, theModifiedElems):
6865 Create a hole in a mesh by doubling the nodes of some particular elements.
6866 This method provided for convenience works as :meth:`DoubleNodes`.
6869 theNodeId: IDs of node to double
6870 theModifiedElems: IDs of elements to update
6873 True if operation has been completed successfully, False otherwise
6876 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6878 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6880 Create a hole in a mesh by doubling the nodes of some particular elements.
6881 This method provided for convenience works as :meth:`DoubleNodes`.
6884 theNodes: group of nodes to double.
6885 theModifiedElems: group of elements to update.
6886 theMakeGroup: forces the generation of a group containing new nodes.
6889 True or a created group if operation has been completed successfully,
6890 False or None otherwise
6894 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6895 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6897 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6899 Create a hole in a mesh by doubling the nodes of some particular elements.
6900 This method provided for convenience works as :meth:`DoubleNodes`.
6903 theNodes: list of groups of nodes to double.
6904 theModifiedElems: list of groups of elements to update.
6905 theMakeGroup: forces the generation of a group containing new nodes.
6908 True if operation has been completed successfully, False otherwise
6912 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6913 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6915 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6917 Create a hole in a mesh by doubling the nodes of some particular elements
6920 theElems: the list of elements (edges or faces) to replicate.
6921 The nodes for duplication could be found from these elements
6922 theNodesNot: list of nodes NOT to replicate
6923 theAffectedElems: the list of elements (cells and edges) to which the
6924 replicated nodes should be associated to
6927 True if operation has been completed successfully, False otherwise
6930 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6932 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6934 Create a hole in a mesh by doubling the nodes of some particular elements
6937 theElems: the list of elements (edges or faces) to replicate.
6938 The nodes for duplication could be found from these elements
6939 theNodesNot: list of nodes NOT to replicate
6940 theShape: shape to detect affected elements (element which geometric center
6941 located on or inside shape).
6942 The replicated nodes should be associated to affected elements.
6945 True if operation has been completed successfully, False otherwise
6948 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6950 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6951 theMakeGroup=False, theMakeNodeGroup=False):
6953 Create a hole in a mesh by doubling the nodes of some particular elements.
6954 This method provided for convenience works as :meth:`DoubleNodes`.
6957 theElems: group of of elements (edges or faces) to replicate.
6958 theNodesNot: group of nodes NOT to replicate.
6959 theAffectedElems: group of elements to which the replicated nodes
6960 should be associated to.
6961 theMakeGroup: forces the generation of a group containing new elements.
6962 theMakeNodeGroup: forces the generation of a group containing new nodes.
6965 True or created groups (one or two) if operation has been completed successfully,
6966 False or None otherwise
6969 if theMakeGroup or theMakeNodeGroup:
6970 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6972 theMakeGroup, theMakeNodeGroup)
6973 if theMakeGroup and theMakeNodeGroup:
6976 return twoGroups[ int(theMakeNodeGroup) ]
6977 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6979 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6981 Create a hole in a mesh by doubling the nodes of some particular elements.
6982 This method provided for convenience works as :meth:`DoubleNodes`.
6985 theElems: group of of elements (edges or faces) to replicate
6986 theNodesNot: group of nodes not to replicate
6987 theShape: shape to detect affected elements (element which geometric center
6988 located on or inside shape).
6989 The replicated nodes should be associated to affected elements
6992 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6994 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6995 theMakeGroup=False, theMakeNodeGroup=False):
6997 Create a hole in a mesh by doubling the nodes of some particular elements.
6998 This method provided for convenience works as :meth:`DoubleNodes`.
7001 theElems: list of groups of elements (edges or faces) to replicate
7002 theNodesNot: list of groups of nodes NOT to replicate
7003 theAffectedElems: group of elements to which the replicated nodes
7004 should be associated to
7005 theMakeGroup: forces generation of a group containing new elements.
7006 theMakeNodeGroup: forces generation of a group containing new nodes
7009 True or created groups (one or two) if operation has been completed successfully,
7010 False or None otherwise
7013 if theMakeGroup or theMakeNodeGroup:
7014 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7016 theMakeGroup, theMakeNodeGroup)
7017 if theMakeGroup and theMakeNodeGroup:
7020 return twoGroups[ int(theMakeNodeGroup) ]
7021 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7023 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7025 Create a hole in a mesh by doubling the nodes of some particular elements.
7026 This method provided for convenience works as :meth:`DoubleNodes`.
7029 theElems: list of groups of elements (edges or faces) to replicate
7030 theNodesNot: list of groups of nodes NOT to replicate
7031 theShape: shape to detect affected elements (element which geometric center
7032 located on or inside shape).
7033 The replicated nodes should be associated to affected elements
7036 True if operation has been completed successfully, False otherwise
7039 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7041 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7043 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7044 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7047 theElems: list of groups of nodes or elements (edges or faces) to replicate
7048 theNodesNot: list of groups of nodes NOT to replicate
7049 theShape: shape to detect affected elements (element which geometric center
7050 located on or inside shape).
7051 The replicated nodes should be associated to affected elements
7054 groups of affected elements in order: volumes, faces, edges
7057 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7059 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7062 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7063 The list of groups must describe a partition of the mesh volumes.
7064 The nodes of the internal faces at the boundaries of the groups are doubled.
7065 In option, the internal faces are replaced by flat elements.
7066 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7069 theDomains: list of groups of volumes
7070 createJointElems: if True, create the elements
7071 onAllBoundaries: if True, the nodes and elements are also created on
7072 the boundary between *theDomains* and the rest mesh
7075 True if operation has been completed successfully, False otherwise
7078 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7080 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7082 Double nodes on some external faces and create flat elements.
7083 Flat elements are mainly used by some types of mechanic calculations.
7085 Each group of the list must be constituted of faces.
7086 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7089 theGroupsOfFaces: list of groups of faces
7092 True if operation has been completed successfully, False otherwise
7095 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7097 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7099 Identify all the elements around a geom shape, get the faces delimiting the hole
7101 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7103 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7105 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7106 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7107 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7108 If there are several paths connecting a pair of points, the shortest path is
7109 selected by the module. Position of the cutting plane is defined by the two
7110 points and an optional vector lying on the plane specified by a PolySegment.
7111 By default the vector is defined by Mesh module as following. A middle point
7112 of the two given points is computed. The middle point is projected to the mesh.
7113 The vector goes from the middle point to the projection point. In case of planar
7114 mesh, the vector is normal to the mesh.
7116 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7119 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7120 groupName: optional name of a group where created mesh segments will be added.
7123 editor = self.editor
7125 editor = self.mesh.GetMeshEditPreviewer()
7126 segmentsRes = editor.MakePolyLine( segments, groupName )
7127 for i, seg in enumerate( segmentsRes ):
7128 segments[i].vector = seg.vector
7130 return editor.GetPreviewData()
7133 def MakeSlot(self, segmentGroup, width ):
7135 Create a slot of given width around given 1D elements lying on a triangle mesh.
7136 The slot is constructed by cutting faces by cylindrical surfaces made
7137 around each segment. Segments are expected to be created by MakePolyLine().
7140 FaceEdge's located at the slot boundary
7142 return self.editor.MakeSlot( segmentGroup, width )
7144 def GetFunctor(self, funcType ):
7146 Return a cached numerical functor by its type.
7149 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7150 Note that not all items correspond to numerical functors.
7153 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7156 fn = self.functors[ funcType._v ]
7158 fn = self.smeshpyD.GetFunctor(funcType)
7159 fn.SetMesh(self.mesh)
7160 self.functors[ funcType._v ] = fn
7163 def FunctorValue(self, funcType, elemId, isElem=True):
7165 Return value of a functor for a given element
7168 funcType: an item of :class:`SMESH.FunctorType` enum.
7169 elemId: element or node ID
7170 isElem: *elemId* is ID of element or node
7173 the functor value or zero in case of invalid arguments
7176 fn = self.GetFunctor( funcType )
7177 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7178 val = fn.GetValue(elemId)
7183 def GetLength(self, elemId=None):
7185 Get length of given 1D elements or of all 1D mesh elements
7188 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.
7191 Sum of lengths of given elements
7196 length = self.smeshpyD.GetLength(self)
7197 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7198 length = self.smeshpyD.GetLength(elemId)
7201 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7203 length += self.smeshpyD.GetLength(obj)
7204 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7205 unRegister = genObjUnRegister()
7206 obj = self.GetIDSource( elemId )
7207 unRegister.set( obj )
7208 length = self.smeshpyD.GetLength( obj )
7210 length = self.FunctorValue(SMESH.FT_Length, elemId)
7213 def GetArea(self, elemId=None):
7215 Get area of given 2D elements or of all 2D mesh elements
7218 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.
7221 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7226 area = self.smeshpyD.GetArea(self)
7227 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7228 area = self.smeshpyD.GetArea(elemId)
7231 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7233 area += self.smeshpyD.GetArea(obj)
7234 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7235 unRegister = genObjUnRegister()
7236 obj = self.GetIDSource( elemId )
7237 unRegister.set( obj )
7238 area = self.smeshpyD.GetArea( obj )
7240 area = self.FunctorValue(SMESH.FT_Area, elemId)
7243 def GetVolume(self, elemId=None):
7245 Get volume of given 3D elements or of all 3D mesh elements
7248 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.
7251 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7256 volume= self.smeshpyD.GetVolume(self)
7257 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7258 volume= self.smeshpyD.GetVolume(elemId)
7261 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7263 volume+= self.smeshpyD.GetVolume(obj)
7264 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7265 unRegister = genObjUnRegister()
7266 obj = self.GetIDSource( elemId )
7267 unRegister.set( obj )
7268 volume= self.smeshpyD.GetVolume( obj )
7270 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7273 def GetAngle(self, node1, node2, node3 ):
7275 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7278 node1,node2,node3: IDs of the three nodes
7281 Angle in radians [0,PI]. -1 if failure case.
7283 p1 = self.GetNodeXYZ( node1 )
7284 p2 = self.GetNodeXYZ( node2 )
7285 p3 = self.GetNodeXYZ( node3 )
7286 if p1 and p2 and p3:
7287 return self.smeshpyD.GetAngle( p1,p2,p3 )
7291 def GetMaxElementLength(self, elemId):
7293 Get maximum element length.
7296 elemId: mesh element ID
7299 element's maximum length value
7302 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7303 ftype = SMESH.FT_MaxElementLength3D
7305 ftype = SMESH.FT_MaxElementLength2D
7306 return self.FunctorValue(ftype, elemId)
7308 def GetAspectRatio(self, elemId):
7310 Get aspect ratio of 2D or 3D element.
7313 elemId: mesh element ID
7316 element's aspect ratio value
7319 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7320 ftype = SMESH.FT_AspectRatio3D
7322 ftype = SMESH.FT_AspectRatio
7323 return self.FunctorValue(ftype, elemId)
7325 def GetWarping(self, elemId):
7327 Get warping angle of 2D element.
7330 elemId: mesh element ID
7333 element's warping angle value
7336 return self.FunctorValue(SMESH.FT_Warping, elemId)
7338 def GetMinimumAngle(self, elemId):
7340 Get minimum angle of 2D element.
7343 elemId: mesh element ID
7346 element's minimum angle value
7349 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7351 def GetTaper(self, elemId):
7353 Get taper of 2D element.
7356 elemId: mesh element ID
7359 element's taper value
7362 return self.FunctorValue(SMESH.FT_Taper, elemId)
7364 def GetSkew(self, elemId):
7366 Get skew of 2D element.
7369 elemId: mesh element ID
7372 element's skew value
7375 return self.FunctorValue(SMESH.FT_Skew, elemId)
7377 def GetMinMax(self, funType, meshPart=None):
7379 Return minimal and maximal value of a given functor.
7382 funType (SMESH.FunctorType): a functor type.
7383 Note that not all items of :class:`SMESH.FunctorType` corresponds
7384 to numerical functors.
7385 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7391 unRegister = genObjUnRegister()
7392 if isinstance( meshPart, list ):
7393 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7394 unRegister.set( meshPart )
7395 if isinstance( meshPart, Mesh ):
7396 meshPart = meshPart.mesh
7397 fun = self.GetFunctor( funType )
7400 if hasattr( meshPart, "SetMesh" ):
7401 meshPart.SetMesh( self.mesh ) # set mesh to filter
7402 hist = fun.GetLocalHistogram( 1, False, meshPart )
7404 hist = fun.GetHistogram( 1, False )
7406 return hist[0].min, hist[0].max
7409 pass # end of Mesh class
7412 class meshProxy(SMESH._objref_SMESH_Mesh):
7414 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7415 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7417 def __init__(self,*args):
7418 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7419 def __deepcopy__(self, memo=None):
7420 new = self.__class__(self)
7422 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7423 if len( args ) == 3:
7424 args += SMESH.ALL_NODES, True
7425 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7426 def ExportToMEDX(self, *args): # function removed
7427 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7428 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7429 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7430 def ExportToMED(self, *args): # function removed
7431 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7432 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7434 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7436 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7437 def ExportPartToMED(self, *args): # 'version' parameter removed
7438 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7439 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7440 def ExportMED(self, *args): # signature of method changed
7441 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7443 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7445 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7446 def ExportUNV(self, *args): # renumber arg added
7447 if len( args ) == 1:
7449 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
7450 def ExportDAT(self, *args): # renumber arg added
7451 if len( args ) == 1:
7453 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
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" ):