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 Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4669 Reorient faces contained in a list of *objectFaces*
4670 equally to faces contained in a list of *referenceFaces*.
4673 objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4674 referenceFaces: list of :class:`sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding reference faces. It can be empty, then any face in *objectFaces* is used as the reference.
4677 number of reoriented faces.
4679 if not isinstance( objectFaces, list ):
4680 objectFaces = [ objectFaces ]
4681 for i,obj2D in enumerate( objectFaces ):
4682 if isinstance( obj2D, Mesh ):
4683 objectFaces[i] = obj2D.GetMesh()
4684 if not isinstance( referenceFaces, list ):
4685 referenceFaces = [ referenceFaces ]
4687 return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4690 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4692 Reorient faces according to adjacent volumes.
4695 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4696 either IDs of faces or face groups.
4697 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4698 theOutsideNormal: to orient faces to have their normals
4699 pointing either *outside* or *inside* the adjacent volumes.
4702 number of reoriented faces.
4705 unRegister = genObjUnRegister()
4707 if not isinstance( the2DObject, list ):
4708 the2DObject = [ the2DObject ]
4709 elif the2DObject and isinstance( the2DObject[0], int ):
4710 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4711 unRegister.set( the2DObject )
4712 the2DObject = [ the2DObject ]
4713 for i,obj2D in enumerate( the2DObject ):
4714 if isinstance( obj2D, Mesh ):
4715 the2DObject[i] = obj2D.GetMesh()
4716 if isinstance( obj2D, list ):
4717 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4718 unRegister.set( the2DObject[i] )
4720 if isinstance( the3DObject, Mesh ):
4721 the3DObject = the3DObject.GetMesh()
4722 if isinstance( the3DObject, list ):
4723 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4724 unRegister.set( the3DObject )
4725 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4727 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4729 Fuse the neighbouring triangles into quadrangles.
4732 IDsOfElements: The triangles to be fused.
4733 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4734 applied to possible quadrangles to choose a neighbour to fuse with.
4735 Note that not all items of :class:`SMESH.FunctorType` corresponds
4736 to numerical functors.
4737 MaxAngle: is the maximum angle between element normals at which the fusion
4738 is still performed; theMaxAngle is measured in radians.
4739 Also it could be a name of variable which defines angle in degrees.
4742 True in case of success, False otherwise.
4745 This operation can create gaps in numeration of elements.
4746 Call :meth:`RenumberElements` to remove the gaps.
4749 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4750 self.mesh.SetParameters(Parameters)
4751 if not IDsOfElements:
4752 IDsOfElements = self.GetElementsId()
4753 Functor = self.smeshpyD.GetFunctor(theCriterion)
4754 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4756 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4758 Fuse the neighbouring triangles of the object into quadrangles
4761 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4762 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4763 applied to possible quadrangles to choose a neighbour to fuse with.
4764 Note that not all items of :class:`SMESH.FunctorType` corresponds
4765 to numerical functors.
4766 MaxAngle: a max angle between element normals at which the fusion
4767 is still performed; theMaxAngle is measured in radians.
4770 True in case of success, False otherwise.
4773 This operation can create gaps in numeration of elements.
4774 Call :meth:`RenumberElements` to remove the gaps.
4777 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4778 self.mesh.SetParameters(Parameters)
4779 if isinstance( theObject, Mesh ):
4780 theObject = theObject.GetMesh()
4781 Functor = self.smeshpyD.GetFunctor(theCriterion)
4782 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4784 def QuadToTri (self, IDsOfElements, theCriterion = None):
4786 Split quadrangles into triangles.
4789 IDsOfElements: the faces to be splitted.
4790 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4791 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4792 value, then quadrangles will be split by the smallest diagonal.
4793 Note that not all items of :class:`SMESH.FunctorType` corresponds
4794 to numerical functors.
4797 True in case of success, False otherwise.
4800 This operation can create gaps in numeration of elements.
4801 Call :meth:`RenumberElements` to remove the gaps.
4803 if IDsOfElements == []:
4804 IDsOfElements = self.GetElementsId()
4805 if theCriterion is None:
4806 theCriterion = FT_MaxElementLength2D
4807 Functor = self.smeshpyD.GetFunctor(theCriterion)
4808 return self.editor.QuadToTri(IDsOfElements, Functor)
4810 def QuadToTriObject (self, theObject, theCriterion = None):
4812 Split quadrangles into triangles.
4815 theObject: the object from which the list of elements is taken,
4816 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4817 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4818 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4819 value, then quadrangles will be split by the smallest diagonal.
4820 Note that not all items of :class:`SMESH.FunctorType` corresponds
4821 to numerical functors.
4824 True in case of success, False otherwise.
4827 This operation can create gaps in numeration of elements.
4828 Call :meth:`RenumberElements` to remove the gaps.
4830 if ( isinstance( theObject, Mesh )):
4831 theObject = theObject.GetMesh()
4832 if theCriterion is None:
4833 theCriterion = FT_MaxElementLength2D
4834 Functor = self.smeshpyD.GetFunctor(theCriterion)
4835 return self.editor.QuadToTriObject(theObject, Functor)
4837 def QuadTo4Tri (self, theElements=[]):
4839 Split each of given quadrangles into 4 triangles. A node is added at the center of
4843 theElements: the faces to be splitted. This can be either
4844 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4845 or a list of face IDs. By default all quadrangles are split
4848 This operation can create gaps in numeration of elements.
4849 Call :meth:`RenumberElements` to remove the gaps.
4851 unRegister = genObjUnRegister()
4852 if isinstance( theElements, Mesh ):
4853 theElements = theElements.mesh
4854 elif not theElements:
4855 theElements = self.mesh
4856 elif isinstance( theElements, list ):
4857 theElements = self.GetIDSource( theElements, SMESH.FACE )
4858 unRegister.set( theElements )
4859 return self.editor.QuadTo4Tri( theElements )
4861 def SplitQuad (self, IDsOfElements, Diag13):
4863 Split quadrangles into triangles.
4866 IDsOfElements: the faces to be splitted
4867 Diag13 (boolean): is used to choose a diagonal for splitting.
4870 True in case of success, False otherwise.
4873 This operation can create gaps in numeration of elements.
4874 Call :meth:`RenumberElements` to remove the gaps.
4876 if IDsOfElements == []:
4877 IDsOfElements = self.GetElementsId()
4878 return self.editor.SplitQuad(IDsOfElements, Diag13)
4880 def SplitQuadObject (self, theObject, Diag13):
4882 Split quadrangles into triangles.
4885 theObject: the object from which the list of elements is taken,
4886 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4887 Diag13 (boolean): is used to choose a diagonal for splitting.
4890 True in case of success, False otherwise.
4893 This operation can create gaps in numeration of elements.
4894 Call :meth:`RenumberElements` to remove the gaps.
4896 if ( isinstance( theObject, Mesh )):
4897 theObject = theObject.GetMesh()
4898 return self.editor.SplitQuadObject(theObject, Diag13)
4900 def BestSplit (self, IDOfQuad, theCriterion):
4902 Find a better splitting of the given quadrangle.
4905 IDOfQuad: the ID of the quadrangle to be splitted.
4906 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4907 choose a diagonal for splitting.
4908 Note that not all items of :class:`SMESH.FunctorType` corresponds
4909 to numerical functors.
4912 * 1 if 1-3 diagonal is better,
4913 * 2 if 2-4 diagonal is better,
4914 * 0 if error occurs.
4917 This operation can create gaps in numeration of elements.
4918 Call :meth:`RenumberElements` to remove the gaps.
4920 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4922 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4924 Split volumic elements into tetrahedrons
4927 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4928 method: flags passing splitting method:
4929 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4930 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4933 This operation can create gaps in numeration of elements.
4934 Call :meth:`RenumberElements` to remove the gaps.
4936 unRegister = genObjUnRegister()
4937 if isinstance( elems, Mesh ):
4938 elems = elems.GetMesh()
4939 if ( isinstance( elems, list )):
4940 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4941 unRegister.set( elems )
4942 self.editor.SplitVolumesIntoTetra(elems, method)
4945 def SplitBiQuadraticIntoLinear(self, elems=None):
4947 Split bi-quadratic elements into linear ones without creation of additional nodes:
4949 - bi-quadratic triangle will be split into 3 linear quadrangles;
4950 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4951 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4953 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4954 will be split in order to keep the mesh conformal.
4957 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4958 if None (default), all bi-quadratic elements will be split
4961 This operation can create gaps in numeration of elements.
4962 Call :meth:`RenumberElements` to remove the gaps.
4964 unRegister = genObjUnRegister()
4965 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4966 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4967 unRegister.set( elems )
4969 elems = [ self.GetMesh() ]
4970 if isinstance( elems, Mesh ):
4971 elems = [ elems.GetMesh() ]
4972 if not isinstance( elems, list ):
4974 self.editor.SplitBiQuadraticIntoLinear( elems )
4976 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4977 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4979 Split hexahedra into prisms
4982 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4983 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4984 gives a normal vector defining facets to split into triangles.
4985 *startHexPoint* can be either a triple of coordinates or a vertex.
4986 facetNormal: a normal to a facet to split into triangles of a
4987 hexahedron found by *startHexPoint*.
4988 *facetNormal* can be either a triple of coordinates or an edge.
4989 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4990 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4991 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4992 to *startHexPoint* are split, else *startHexPoint*
4993 is used to find the facet to split in all domains present in *elems*.
4996 This operation can create gaps in numeration of elements.
4997 Call :meth:`RenumberElements` to remove the gaps.
5000 unRegister = genObjUnRegister()
5001 if isinstance( elems, Mesh ):
5002 elems = elems.GetMesh()
5003 if ( isinstance( elems, list )):
5004 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5005 unRegister.set( elems )
5008 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5009 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5010 elif isinstance( startHexPoint, list ):
5011 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5014 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5015 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5016 elif isinstance( facetNormal, list ):
5017 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5020 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5022 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5024 def SplitQuadsNearTriangularFacets(self):
5026 Split quadrangle faces near triangular facets of volumes
5029 This operation can create gaps in numeration of elements.
5030 Call :meth:`RenumberElements` to remove the gaps.
5032 faces_array = self.GetElementsByType(SMESH.FACE)
5033 for face_id in faces_array:
5034 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5035 quad_nodes = self.mesh.GetElemNodes(face_id)
5036 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5037 isVolumeFound = False
5038 for node1_elem in node1_elems:
5039 if not isVolumeFound:
5040 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5041 nb_nodes = self.GetElemNbNodes(node1_elem)
5042 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5043 volume_elem = node1_elem
5044 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5045 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5046 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5047 isVolumeFound = True
5048 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5049 self.SplitQuad([face_id], False) # diagonal 2-4
5050 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5051 isVolumeFound = True
5052 self.SplitQuad([face_id], True) # diagonal 1-3
5053 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5054 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5055 isVolumeFound = True
5056 self.SplitQuad([face_id], True) # diagonal 1-3
5058 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5060 Split hexahedrons into tetrahedrons.
5062 This operation uses :doc:`pattern_mapping` functionality for splitting.
5065 theObject: the object from which the list of hexahedrons is taken;
5066 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5067 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5068 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5069 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5070 key-point will be mapped into *theNode001*-th node of each volume.
5071 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5074 True in case of success, False otherwise.
5077 This operation can create gaps in numeration of elements.
5078 Call :meth:`RenumberElements` to remove the gaps.
5086 # (0,0,1) 4.---------.7 * |
5093 # (0,0,0) 0.---------.3
5094 pattern_tetra = "!!! Nb of points: \n 8 \n\
5104 !!! Indices of points of 6 tetras: \n\
5112 pattern = self.smeshpyD.GetPattern()
5113 isDone = pattern.LoadFromFile(pattern_tetra)
5115 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5118 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5119 isDone = pattern.MakeMesh(self.mesh, False, False)
5120 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5122 # split quafrangle faces near triangular facets of volumes
5123 self.SplitQuadsNearTriangularFacets()
5127 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5129 Split hexahedrons into prisms.
5131 Uses the :doc:`pattern_mapping` functionality for splitting.
5134 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5135 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5136 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5137 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5138 will be mapped into the *theNode001* -th node of each volume.
5139 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5142 True in case of success, False otherwise.
5145 This operation can create gaps in numeration of elements.
5146 Call :meth:`RenumberElements` to remove the gaps.
5148 # Pattern: 5.---------.6
5153 # (0,0,1) 4.---------.7 |
5160 # (0,0,0) 0.---------.3
5161 pattern_prism = "!!! Nb of points: \n 8 \n\
5171 !!! Indices of points of 2 prisms: \n\
5175 pattern = self.smeshpyD.GetPattern()
5176 isDone = pattern.LoadFromFile(pattern_prism)
5178 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5181 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5182 isDone = pattern.MakeMesh(self.mesh, False, False)
5183 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5185 # Split quafrangle faces near triangular facets of volumes
5186 self.SplitQuadsNearTriangularFacets()
5190 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5191 MaxNbOfIterations, MaxAspectRatio, Method):
5196 IDsOfElements: the list if ids of elements to smooth
5197 IDsOfFixedNodes: the list of ids of fixed nodes.
5198 Note that nodes built on edges and boundary nodes are always fixed.
5199 MaxNbOfIterations: the maximum number of iterations
5200 MaxAspectRatio: varies in range [1.0, inf]
5201 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5202 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5205 True in case of success, False otherwise.
5208 if IDsOfElements == []:
5209 IDsOfElements = self.GetElementsId()
5210 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5211 self.mesh.SetParameters(Parameters)
5212 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5213 MaxNbOfIterations, MaxAspectRatio, Method)
5215 def SmoothObject(self, theObject, IDsOfFixedNodes,
5216 MaxNbOfIterations, MaxAspectRatio, Method):
5218 Smooth elements which belong to the given object
5221 theObject: the object 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 ( isinstance( theObject, Mesh )):
5234 theObject = theObject.GetMesh()
5235 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5236 MaxNbOfIterations, MaxAspectRatio, Method)
5238 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5239 MaxNbOfIterations, MaxAspectRatio, Method):
5241 Parametrically smooth the given elements
5244 IDsOfElements: the list if ids of elements to smooth
5245 IDsOfFixedNodes: the list of ids of fixed nodes.
5246 Note that nodes built on edges and boundary nodes are always fixed.
5247 MaxNbOfIterations: the maximum number of iterations
5248 MaxAspectRatio: varies in range [1.0, inf]
5249 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5250 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5253 True in case of success, False otherwise.
5256 if IDsOfElements == []:
5257 IDsOfElements = self.GetElementsId()
5258 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5259 self.mesh.SetParameters(Parameters)
5260 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5261 MaxNbOfIterations, MaxAspectRatio, Method)
5263 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5264 MaxNbOfIterations, MaxAspectRatio, Method):
5266 Parametrically smooth the elements which belong to the given object
5269 theObject: the object to smooth
5270 IDsOfFixedNodes: the list of ids of fixed nodes.
5271 Note that nodes built on edges and boundary nodes are always fixed.
5272 MaxNbOfIterations: the maximum number of iterations
5273 MaxAspectRatio: varies in range [1.0, inf]
5274 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5275 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5278 True in case of success, False otherwise.
5281 if ( isinstance( theObject, Mesh )):
5282 theObject = theObject.GetMesh()
5283 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5284 MaxNbOfIterations, MaxAspectRatio, Method)
5286 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5288 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5289 them with quadratic with the same id.
5292 theForce3d: method of new node creation:
5294 * False - the medium node lies at the geometrical entity from which the mesh element is built
5295 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5296 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5297 theToBiQuad: If True, converts the mesh to bi-quadratic
5300 :class:`SMESH.ComputeError` which can hold a warning
5303 If *theSubMesh* is provided, the mesh can become non-conformal
5306 This operation can create gaps in numeration of nodes or elements.
5307 Call :meth:`RenumberElements` to remove the gaps.
5310 if isinstance( theSubMesh, Mesh ):
5311 theSubMesh = theSubMesh.mesh
5313 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5316 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5318 self.editor.ConvertToQuadratic(theForce3d)
5319 error = self.editor.GetLastError()
5320 if error and error.comment:
5321 print(error.comment)
5324 def ConvertFromQuadratic(self, theSubMesh=None):
5326 Convert the mesh from quadratic to ordinary,
5327 deletes old quadratic elements,
5328 replacing them with ordinary mesh elements with the same id.
5331 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5334 If *theSubMesh* is provided, the mesh can become non-conformal
5337 This operation can create gaps in numeration of nodes or elements.
5338 Call :meth:`RenumberElements` to remove the gaps.
5342 self.editor.ConvertFromQuadraticObject(theSubMesh)
5344 return self.editor.ConvertFromQuadratic()
5346 def Make2DMeshFrom3D(self):
5348 Create 2D mesh as skin on boundary faces of a 3D mesh
5351 True if operation has been completed successfully, False otherwise
5354 return self.editor.Make2DMeshFrom3D()
5356 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5357 toCopyElements=False, toCopyExistingBondary=False):
5359 Create missing boundary elements
5362 elements: elements whose boundary is to be checked:
5363 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5364 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5365 dimension: defines type of boundary elements to create, either of
5366 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5367 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5368 groupName: a name of group to store created boundary elements in,
5369 "" means not to create the group
5370 meshName: a name of new mesh to store created boundary elements in,
5371 "" means not to create the new mesh
5372 toCopyElements: if True, the checked elements will be copied into
5373 the new mesh else only boundary elements will be copied into the new mesh
5374 toCopyExistingBondary: if True, not only new but also pre-existing
5375 boundary elements will be copied into the new mesh
5378 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5381 unRegister = genObjUnRegister()
5382 if isinstance( elements, Mesh ):
5383 elements = elements.GetMesh()
5384 if ( isinstance( elements, list )):
5385 elemType = SMESH.ALL
5386 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5387 elements = self.editor.MakeIDSource(elements, elemType)
5388 unRegister.set( elements )
5389 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5390 toCopyElements,toCopyExistingBondary)
5391 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5394 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5395 toCopyAll=False, groups=[]):
5397 Create missing boundary elements around either the whole mesh or
5401 dimension: defines type of boundary elements to create, either of
5402 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5403 groupName: a name of group to store all boundary elements in,
5404 "" means not to create the group
5405 meshName: a name of a new mesh, which is a copy of the initial
5406 mesh + created boundary elements; "" means not to create the new mesh
5407 toCopyAll: if True, the whole initial mesh will be copied into
5408 the new mesh else only boundary elements will be copied into the new mesh
5409 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5412 tuple( long, mesh, group )
5413 - long - number of added boundary elements
5414 - mesh - the :class:`Mesh` where elements were added to
5415 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5418 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5420 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5421 return nb, mesh, group
5423 def RenumberNodes(self):
5425 Renumber mesh nodes to remove unused node IDs
5427 self.editor.RenumberNodes()
5429 def RenumberElements(self):
5431 Renumber mesh elements to remove unused element IDs
5433 self.editor.RenumberElements()
5435 def _getIdSourceList(self, arg, idType, unRegister):
5437 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5439 if arg and isinstance( arg, list ):
5440 if isinstance( arg[0], int ):
5441 arg = self.GetIDSource( arg, idType )
5442 unRegister.set( arg )
5443 elif isinstance( arg[0], Mesh ):
5444 arg[0] = arg[0].GetMesh()
5445 elif isinstance( arg, Mesh ):
5447 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5451 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5452 MakeGroups=False, TotalAngle=False):
5454 Generate new elements by rotation of the given elements and nodes around the axis
5457 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5458 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5459 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5460 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5461 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5462 which defines angle in degrees
5463 NbOfSteps: the number of steps
5464 Tolerance: tolerance
5465 MakeGroups: forces the generation of new groups from existing ones
5466 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5467 of all steps, else - size of each step
5470 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5473 unRegister = genObjUnRegister()
5474 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5475 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5476 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5478 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5479 Axis = self.smeshpyD.GetAxisStruct( Axis )
5480 if isinstance( Axis, list ):
5481 Axis = SMESH.AxisStruct( *Axis )
5483 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5484 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5485 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5486 self.mesh.SetParameters(Parameters)
5487 if TotalAngle and NbOfSteps:
5488 AngleInRadians /= NbOfSteps
5489 return self.editor.RotationSweepObjects( nodes, edges, faces,
5490 Axis, AngleInRadians,
5491 NbOfSteps, Tolerance, MakeGroups)
5493 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5494 MakeGroups=False, TotalAngle=False):
5496 Generate new elements by rotation of the elements around the axis
5499 IDsOfElements: the list of ids of elements to sweep
5500 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5501 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5502 NbOfSteps: the number of steps
5503 Tolerance: tolerance
5504 MakeGroups: forces the generation of new groups from existing ones
5505 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5506 of all steps, else - size of each step
5509 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5512 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5513 AngleInRadians, NbOfSteps, Tolerance,
5514 MakeGroups, TotalAngle)
5516 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5517 MakeGroups=False, TotalAngle=False):
5519 Generate new elements by rotation of the elements of object around the axis
5520 theObject object which elements should be sweeped.
5521 It can be a mesh, a sub mesh or a group.
5524 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5525 AngleInRadians: the angle of Rotation
5526 NbOfSteps: number of steps
5527 Tolerance: tolerance
5528 MakeGroups: forces the generation of new groups from existing ones
5529 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5530 of all steps, else - size of each step
5533 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5536 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5537 AngleInRadians, NbOfSteps, Tolerance,
5538 MakeGroups, TotalAngle )
5540 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5541 MakeGroups=False, TotalAngle=False):
5543 Generate new elements by rotation of the elements of object around the axis
5544 theObject object which elements should be sweeped.
5545 It can be a mesh, a sub mesh or a group.
5548 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5549 AngleInRadians: the angle of Rotation
5550 NbOfSteps: number of steps
5551 Tolerance: tolerance
5552 MakeGroups: forces the generation of new groups from existing ones
5553 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5554 of all steps, else - size of each step
5557 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5558 empty list otherwise
5561 return self.RotationSweepObjects([],theObject,[], Axis,
5562 AngleInRadians, NbOfSteps, Tolerance,
5563 MakeGroups, TotalAngle)
5565 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5566 MakeGroups=False, TotalAngle=False):
5568 Generate new elements by rotation of the elements of object around the axis
5569 theObject object which elements should be sweeped.
5570 It can be a mesh, a sub mesh or a group.
5573 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5574 AngleInRadians: the angle of Rotation
5575 NbOfSteps: number of steps
5576 Tolerance: tolerance
5577 MakeGroups: forces the generation of new groups from existing ones
5578 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5579 of all steps, else - size of each step
5582 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5585 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5586 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5588 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5589 scaleFactors=[], linearVariation=False, basePoint=[],
5590 angles=[], anglesVariation=False):
5592 Generate new elements by extrusion of the given elements and nodes
5595 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5596 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5597 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5598 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5599 the direction and value of extrusion for one step (the total extrusion
5600 length will be NbOfSteps * ||StepVector||)
5601 NbOfSteps: the number of steps
5602 MakeGroups: forces the generation of new groups from existing ones
5603 scaleFactors: optional scale factors to apply during extrusion
5604 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5605 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5606 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5607 nodes and elements being extruded is used as the scaling center.
5610 - a list of tree components of the point or
5613 angles: list of angles in radians. Nodes at each extrusion step are rotated
5614 around *basePoint*, additionally to previous steps.
5615 anglesVariation: forces the computation of rotation angles as linear
5616 variation of the given *angles* along path steps
5618 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5620 Example: :ref:`tui_extrusion`
5622 unRegister = genObjUnRegister()
5623 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5624 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5625 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5627 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5628 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5629 if isinstance( StepVector, list ):
5630 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5632 if isinstance( basePoint, int):
5633 xyz = self.GetNodeXYZ( basePoint )
5635 raise RuntimeError("Invalid node ID: %s" % basePoint)
5637 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5638 basePoint = self.geompyD.PointCoordinates( basePoint )
5640 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5641 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5642 angles,angleParameters,hasVars = ParseAngles(angles)
5643 Parameters = StepVector.PS.parameters + var_separator + \
5644 Parameters + var_separator + \
5645 scaleParameters + var_separator + angleParameters
5646 self.mesh.SetParameters(Parameters)
5648 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5649 StepVector, NbOfSteps, MakeGroups,
5650 scaleFactors, linearVariation, basePoint,
5651 angles, anglesVariation )
5654 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5656 Generate new elements by extrusion of the elements with given ids
5659 IDsOfElements: the list of ids of elements or nodes for extrusion
5660 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5661 the direction and value of extrusion for one step (the total extrusion
5662 length will be NbOfSteps * ||StepVector||)
5663 NbOfSteps: the number of steps
5664 MakeGroups: forces the generation of new groups from existing ones
5665 IsNodes: is True if elements with given ids are nodes
5668 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5670 Example: :ref:`tui_extrusion`
5673 if IsNodes: n = IDsOfElements
5674 else : e,f, = IDsOfElements,IDsOfElements
5675 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5677 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5678 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5680 Generate new elements by extrusion along the normal to a discretized surface or wire
5683 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5684 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5685 StepSize: length of one extrusion step (the total extrusion
5686 length will be *NbOfSteps* *StepSize*).
5687 NbOfSteps: number of extrusion steps.
5688 ByAverageNormal: if True each node is translated by *StepSize*
5689 along the average of the normal vectors to the faces sharing the node;
5690 else each node is translated along the same average normal till
5691 intersection with the plane got by translation of the face sharing
5692 the node along its own normal by *StepSize*.
5693 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5694 for every node of *Elements*.
5695 MakeGroups: forces generation of new groups from existing ones.
5696 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5697 is not yet implemented. This parameter is used if *Elements* contains
5698 both faces and edges, i.e. *Elements* is a Mesh.
5701 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5702 empty list otherwise.
5703 Example: :ref:`tui_extrusion`
5706 unRegister = genObjUnRegister()
5707 if isinstance( Elements, Mesh ):
5708 Elements = [ Elements.GetMesh() ]
5709 if isinstance( Elements, list ):
5711 raise RuntimeError("Elements empty!")
5712 if isinstance( Elements[0], Mesh ):
5713 Elements = [ Elements[0].GetMesh() ]
5714 if isinstance( Elements[0], int ):
5715 Elements = self.GetIDSource( Elements, SMESH.ALL )
5716 unRegister.set( Elements )
5717 if not isinstance( Elements, list ):
5718 Elements = [ Elements ]
5719 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5720 self.mesh.SetParameters(Parameters)
5721 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5722 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5724 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5726 Generate new elements by extrusion of the elements or nodes which belong to the object
5729 theObject: the object whose elements or nodes should be processed.
5730 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5731 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5732 the direction and value of extrusion for one step (the total extrusion
5733 length will be NbOfSteps * ||StepVector||)
5734 NbOfSteps: the number of steps
5735 MakeGroups: forces the generation of new groups from existing ones
5736 IsNodes: is True if elements to extrude are nodes
5739 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5740 Example: :ref:`tui_extrusion`
5744 if IsNodes: n = theObject
5745 else : e,f, = theObject,theObject
5746 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5748 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5750 Generate new elements by extrusion of edges which belong to the object
5753 theObject: object whose 1D elements should be processed.
5754 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5755 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5756 the direction and value of extrusion for one step (the total extrusion
5757 length will be NbOfSteps * ||StepVector||)
5758 NbOfSteps: the number of steps
5759 MakeGroups: to generate new groups from existing ones
5762 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5763 Example: :ref:`tui_extrusion`
5766 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5768 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5770 Generate new elements by extrusion of faces which belong to the object
5773 theObject: object whose 2D elements should be processed.
5774 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5775 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5776 the direction and value of extrusion for one step (the total extrusion
5777 length will be NbOfSteps * ||StepVector||)
5778 NbOfSteps: the number of steps
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
5783 Example: :ref:`tui_extrusion`
5786 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5788 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5789 ExtrFlags, SewTolerance, MakeGroups=False):
5791 Generate new elements by extrusion of the elements with given ids
5794 IDsOfElements: is ids of elements
5795 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5796 the direction and value of extrusion for one step (the total extrusion
5797 length will be NbOfSteps * ||StepVector||)
5798 NbOfSteps: the number of steps
5799 ExtrFlags: sets flags for extrusion
5800 SewTolerance: uses for comparing locations of nodes if flag
5801 EXTRUSION_FLAG_SEW is set
5802 MakeGroups: forces the generation of new groups from existing ones
5805 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5808 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5809 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5810 if isinstance( StepVector, list ):
5811 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5812 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5813 ExtrFlags, SewTolerance, MakeGroups)
5815 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5816 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5817 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5818 ScaleFactors=[], ScalesVariation=False):
5820 Generate new elements by extrusion of the given elements and nodes along the path.
5821 The path of extrusion must be a meshed edge.
5824 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5825 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5826 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5827 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5828 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
5829 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5830 HasAngles: not used obsolete
5831 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5832 around *basePoint*, additionally to previous steps.
5833 LinearVariation: forces the computation of rotation angles as linear
5834 variation of the given Angles along path steps
5835 HasRefPoint: allows using the reference point
5836 RefPoint: optional scaling and rotation center (mass center of the extruded
5837 elements by default). The User can specify any point as the Reference Point.
5838 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5839 MakeGroups: forces the generation of new groups from existing ones
5840 ScaleFactors: optional scale factors to apply during extrusion
5841 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5842 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5845 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5846 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5847 Example: :ref:`tui_extrusion_along_path`
5850 unRegister = genObjUnRegister()
5851 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5852 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5853 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5855 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5856 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5857 if isinstance( RefPoint, list ):
5858 if not RefPoint: RefPoint = [0,0,0]
5859 RefPoint = SMESH.PointStruct( *RefPoint )
5860 if isinstance( PathObject, Mesh ):
5861 PathObject = PathObject.GetMesh()
5862 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5863 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5864 Parameters = AnglesParameters + var_separator + \
5865 RefPoint.parameters + var_separator + ScalesParameters
5866 self.mesh.SetParameters(Parameters)
5867 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5868 PathObject, PathShape, NodeStart,
5869 HasAngles, Angles, LinearVariation,
5870 HasRefPoint, RefPoint, MakeGroups,
5871 ScaleFactors, ScalesVariation)
5873 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5874 HasAngles=False, Angles=[], LinearVariation=False,
5875 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5876 ElemType=SMESH.FACE):
5878 Generate new elements by extrusion of the given elements.
5879 The path of extrusion must be a meshed edge.
5882 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5883 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5884 NodeStart: the start node from Path. Defines the direction of extrusion
5885 HasAngles: not used obsolete
5886 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5887 around *basePoint*, additionally to previous steps.
5888 LinearVariation: forces the computation of rotation angles as linear
5889 variation of the given Angles along path steps
5890 HasRefPoint: allows using the reference point
5891 RefPoint: the reference point around which the elements are rotated (the mass
5892 center of the elements by default).
5893 The User can specify any point as the Reference Point.
5894 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5895 MakeGroups: forces the generation of new groups from existing ones
5896 ElemType: type of elements for extrusion (if param Base is a mesh)
5899 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5900 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5901 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5903 Example: :ref:`tui_extrusion_along_path`
5907 if ElemType == SMESH.NODE: n = Base
5908 if ElemType == SMESH.EDGE: e = Base
5909 if ElemType == SMESH.FACE: f = Base
5910 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5911 HasAngles, Angles, LinearVariation,
5912 HasRefPoint, RefPoint, MakeGroups)
5913 if MakeGroups: return gr,er
5916 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5917 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5918 MakeGroups=False, LinearVariation=False):
5920 Generate new elements by extrusion of the given elements.
5921 The path of extrusion must be a meshed edge.
5924 IDsOfElements: ids of elements
5925 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5926 PathShape: shape (edge) defines the sub-mesh for the path
5927 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5928 HasAngles: not used obsolete
5929 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5930 around *basePoint*, additionally to previous steps.
5931 HasRefPoint: allows using the reference point
5932 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5933 The User can specify any point as the Reference Point.
5934 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5935 MakeGroups: forces the generation of new groups from existing ones
5936 LinearVariation: forces the computation of rotation angles as linear
5937 variation of the given Angles along path steps
5940 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5941 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5942 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5943 Example: :ref:`tui_extrusion_along_path`
5946 if not IDsOfElements:
5947 IDsOfElements = [ self.GetMesh() ]
5948 n,e,f = [],IDsOfElements,IDsOfElements
5949 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5950 NodeStart, HasAngles, Angles,
5952 HasRefPoint, RefPoint, MakeGroups)
5953 if MakeGroups: return gr,er
5956 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5957 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5958 MakeGroups=False, LinearVariation=False):
5960 Generate new elements by extrusion of the elements which belong to the object.
5961 The path of extrusion must be a meshed edge.
5964 theObject: the object whose elements should be processed.
5965 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5966 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5967 PathShape: shape (edge) defines the sub-mesh for the path
5968 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5969 HasAngles: not used obsolete
5970 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5971 around *basePoint*, additionally to previous steps.
5972 HasRefPoint: allows using the reference point
5973 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5974 The User can specify any point as the Reference Point.
5975 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5976 MakeGroups: forces the generation of new groups from existing ones
5977 LinearVariation: forces the computation of rotation angles as linear
5978 variation of the given Angles along path steps
5981 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5982 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5983 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5984 Example: :ref:`tui_extrusion_along_path`
5987 n,e,f = [],theObject,theObject
5988 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5989 HasAngles, Angles, LinearVariation,
5990 HasRefPoint, RefPoint, MakeGroups)
5991 if MakeGroups: return gr,er
5994 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5995 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5996 MakeGroups=False, LinearVariation=False):
5998 Generate new elements by extrusion of mesh segments which belong to the object.
5999 The path of extrusion must be a meshed edge.
6002 theObject: the object whose 1D elements should be processed.
6003 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6004 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6005 PathShape: shape (edge) defines the sub-mesh for the path
6006 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6007 HasAngles: not used obsolete
6008 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6009 around *basePoint*, additionally to previous steps.
6010 HasRefPoint: allows using the reference point
6011 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6012 The User can specify any point as the Reference Point.
6013 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6014 MakeGroups: forces the generation of new groups from existing ones
6015 LinearVariation: forces the computation of rotation angles as linear
6016 variation of the given Angles along path steps
6019 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6020 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6021 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6022 Example: :ref:`tui_extrusion_along_path`
6025 n,e,f = [],theObject,[]
6026 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6027 HasAngles, Angles, LinearVariation,
6028 HasRefPoint, RefPoint, MakeGroups)
6029 if MakeGroups: return gr,er
6032 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6033 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6034 MakeGroups=False, LinearVariation=False):
6036 Generate new elements by extrusion of faces which belong to the object.
6037 The path of extrusion must be a meshed edge.
6040 theObject: the object whose 2D elements should be processed.
6041 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6042 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6043 PathShape: shape (edge) defines the sub-mesh for the path
6044 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6045 HasAngles: not used obsolete
6046 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6047 around *basePoint*, additionally to previous steps.
6048 HasRefPoint: allows using the reference point
6049 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6050 The User can specify any point as the Reference Point.
6051 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6052 MakeGroups: forces the generation of new groups from existing ones
6053 LinearVariation: forces the computation of rotation angles as linear
6054 variation of the given Angles along path steps
6057 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6058 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6059 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6060 Example: :ref:`tui_extrusion_along_path`
6063 n,e,f = [],[],theObject
6064 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6065 HasAngles, Angles, LinearVariation,
6066 HasRefPoint, RefPoint, MakeGroups)
6067 if MakeGroups: return gr,er
6070 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6072 Create a symmetrical copy of mesh elements
6075 IDsOfElements: list of elements ids
6076 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6077 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6078 If the *Mirror* is a geom object this parameter is unnecessary
6079 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6080 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6083 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6086 if IDsOfElements == []:
6087 IDsOfElements = self.GetElementsId()
6088 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6089 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6090 theMirrorType = Mirror._mirrorType
6092 self.mesh.SetParameters(Mirror.parameters)
6093 if Copy and MakeGroups:
6094 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6095 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6098 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6100 Create a new mesh by a symmetrical copy of mesh elements
6103 IDsOfElements: the list of elements ids
6104 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6105 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6106 If the *Mirror* is a geom object this parameter is unnecessary
6107 MakeGroups: to generate new groups from existing ones
6108 NewMeshName: a name of the new mesh to create
6111 instance of class :class:`Mesh`
6114 if IDsOfElements == []:
6115 IDsOfElements = self.GetElementsId()
6116 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6117 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6118 theMirrorType = Mirror._mirrorType
6120 self.mesh.SetParameters(Mirror.parameters)
6121 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6122 MakeGroups, NewMeshName)
6123 return Mesh(self.smeshpyD,self.geompyD,mesh)
6125 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6127 Create a symmetrical copy of the object
6130 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6131 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6132 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6133 If the *Mirror* is a geom object this parameter is unnecessary
6134 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6135 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6138 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6141 if ( isinstance( theObject, Mesh )):
6142 theObject = theObject.GetMesh()
6143 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6144 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6145 theMirrorType = Mirror._mirrorType
6147 self.mesh.SetParameters(Mirror.parameters)
6148 if Copy and MakeGroups:
6149 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6150 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6153 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6155 Create a new mesh by a symmetrical copy of the object
6158 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6159 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6160 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6161 If the *Mirror* is a geom object this parameter is unnecessary
6162 MakeGroups: forces the generation of new groups from existing ones
6163 NewMeshName: the name of the new mesh to create
6166 instance of class :class:`Mesh`
6169 if ( isinstance( theObject, Mesh )):
6170 theObject = theObject.GetMesh()
6171 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6172 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6173 theMirrorType = Mirror._mirrorType
6175 self.mesh.SetParameters(Mirror.parameters)
6176 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6177 MakeGroups, NewMeshName)
6178 return Mesh( self.smeshpyD,self.geompyD,mesh )
6180 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6182 Translate the elements
6185 IDsOfElements: list of elements ids
6186 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6187 Copy: allows copying the translated elements
6188 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6191 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6194 if IDsOfElements == []:
6195 IDsOfElements = self.GetElementsId()
6196 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6197 Vector = self.smeshpyD.GetDirStruct(Vector)
6198 if isinstance( Vector, list ):
6199 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6200 self.mesh.SetParameters(Vector.PS.parameters)
6201 if Copy and MakeGroups:
6202 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6203 self.editor.Translate(IDsOfElements, Vector, Copy)
6206 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6208 Create a new mesh of translated elements
6211 IDsOfElements: list of elements ids
6212 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6213 MakeGroups: forces the generation of new groups from existing ones
6214 NewMeshName: the name of the newly created mesh
6217 instance of class :class:`Mesh`
6220 if IDsOfElements == []:
6221 IDsOfElements = self.GetElementsId()
6222 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6223 Vector = self.smeshpyD.GetDirStruct(Vector)
6224 if isinstance( Vector, list ):
6225 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6226 self.mesh.SetParameters(Vector.PS.parameters)
6227 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6228 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6230 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6232 Translate the object
6235 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6236 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6237 Copy: allows copying the translated elements
6238 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6241 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6244 if ( isinstance( theObject, Mesh )):
6245 theObject = theObject.GetMesh()
6246 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6247 Vector = self.smeshpyD.GetDirStruct(Vector)
6248 if isinstance( Vector, list ):
6249 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6250 self.mesh.SetParameters(Vector.PS.parameters)
6251 if Copy and MakeGroups:
6252 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6253 self.editor.TranslateObject(theObject, Vector, Copy)
6256 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6258 Create a new mesh from the translated object
6261 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6262 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6263 MakeGroups: forces the generation of new groups from existing ones
6264 NewMeshName: the name of the newly created mesh
6267 instance of class :class:`Mesh`
6270 if isinstance( theObject, Mesh ):
6271 theObject = theObject.GetMesh()
6272 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6273 Vector = self.smeshpyD.GetDirStruct(Vector)
6274 if isinstance( Vector, list ):
6275 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6276 self.mesh.SetParameters(Vector.PS.parameters)
6277 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6278 return Mesh( self.smeshpyD, self.geompyD, mesh )
6282 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6287 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6288 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6289 theScaleFact: list of 1-3 scale factors for axises
6290 Copy: allows copying the translated elements
6291 MakeGroups: forces the generation of new groups from existing
6295 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6296 empty list otherwise
6298 unRegister = genObjUnRegister()
6299 if ( isinstance( theObject, Mesh )):
6300 theObject = theObject.GetMesh()
6301 if ( isinstance( theObject, list )):
6302 theObject = self.GetIDSource(theObject, SMESH.ALL)
6303 unRegister.set( theObject )
6304 if ( isinstance( thePoint, list )):
6305 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6306 if ( isinstance( theScaleFact, float )):
6307 theScaleFact = [theScaleFact]
6308 if ( isinstance( theScaleFact, int )):
6309 theScaleFact = [ float(theScaleFact)]
6311 self.mesh.SetParameters(thePoint.parameters)
6313 if Copy and MakeGroups:
6314 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6315 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6318 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6320 Create a new mesh from the translated object
6323 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6324 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6325 theScaleFact: list of 1-3 scale factors for axises
6326 MakeGroups: forces the generation of new groups from existing ones
6327 NewMeshName: the name of the newly created mesh
6330 instance of class :class:`Mesh`
6332 unRegister = genObjUnRegister()
6333 if (isinstance(theObject, Mesh)):
6334 theObject = theObject.GetMesh()
6335 if ( isinstance( theObject, list )):
6336 theObject = self.GetIDSource(theObject,SMESH.ALL)
6337 unRegister.set( theObject )
6338 if ( isinstance( thePoint, list )):
6339 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6340 if ( isinstance( theScaleFact, float )):
6341 theScaleFact = [theScaleFact]
6342 if ( isinstance( theScaleFact, int )):
6343 theScaleFact = [ float(theScaleFact)]
6345 self.mesh.SetParameters(thePoint.parameters)
6346 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6347 MakeGroups, NewMeshName)
6348 return Mesh( self.smeshpyD, self.geompyD, mesh )
6352 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6357 IDsOfElements: list of elements ids
6358 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6359 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6360 Copy: allows copying the rotated elements
6361 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6364 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6368 if IDsOfElements == []:
6369 IDsOfElements = self.GetElementsId()
6370 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6371 Axis = self.smeshpyD.GetAxisStruct(Axis)
6372 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6373 Parameters = Axis.parameters + var_separator + Parameters
6374 self.mesh.SetParameters(Parameters)
6375 if Copy and MakeGroups:
6376 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6377 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6380 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6382 Create a new mesh of rotated elements
6385 IDsOfElements: list of element ids
6386 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6387 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6388 MakeGroups: forces the generation of new groups from existing ones
6389 NewMeshName: the name of the newly created mesh
6392 instance of class :class:`Mesh`
6395 if IDsOfElements == []:
6396 IDsOfElements = self.GetElementsId()
6397 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6398 Axis = self.smeshpyD.GetAxisStruct(Axis)
6399 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6400 Parameters = Axis.parameters + var_separator + Parameters
6401 self.mesh.SetParameters(Parameters)
6402 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6403 MakeGroups, NewMeshName)
6404 return Mesh( self.smeshpyD, self.geompyD, mesh )
6406 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6411 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6412 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6413 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6414 Copy: allows copying the rotated elements
6415 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6418 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6421 if (isinstance(theObject, Mesh)):
6422 theObject = theObject.GetMesh()
6423 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6424 Axis = self.smeshpyD.GetAxisStruct(Axis)
6425 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6426 Parameters = Axis.parameters + ":" + Parameters
6427 self.mesh.SetParameters(Parameters)
6428 if Copy and MakeGroups:
6429 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6430 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6433 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6435 Create a new mesh from the rotated object
6438 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6439 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6440 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6441 MakeGroups: forces the generation of new groups from existing ones
6442 NewMeshName: the name of the newly created mesh
6445 instance of class :class:`Mesh`
6448 if (isinstance( theObject, Mesh )):
6449 theObject = theObject.GetMesh()
6450 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6451 Axis = self.smeshpyD.GetAxisStruct(Axis)
6452 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6453 Parameters = Axis.parameters + ":" + Parameters
6454 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6455 MakeGroups, NewMeshName)
6456 self.mesh.SetParameters(Parameters)
6457 return Mesh( self.smeshpyD, self.geompyD, mesh )
6459 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6461 Create an offset mesh from the given 2D object
6464 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6465 theValue (float): signed offset size
6466 MakeGroups (boolean): forces the generation of new groups from existing ones
6467 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6468 False means to remove original elements.
6469 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6472 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6475 if isinstance( theObject, Mesh ):
6476 theObject = theObject.GetMesh()
6477 theValue,Parameters,hasVars = ParseParameters(Value)
6478 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6479 self.mesh.SetParameters(Parameters)
6481 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6484 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6486 Find groups of adjacent nodes within Tolerance.
6489 Tolerance (float): the value of tolerance
6490 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6491 corner and medium nodes in separate groups thus preventing
6492 their further merge.
6495 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6498 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6500 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6501 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6503 Find groups of adjacent nodes within Tolerance.
6506 Tolerance: the value of tolerance
6507 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6508 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6509 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6510 corner and medium nodes in separate groups thus preventing
6511 their further merge.
6514 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6517 unRegister = genObjUnRegister()
6518 if not isinstance( SubMeshOrGroup, list ):
6519 SubMeshOrGroup = [ SubMeshOrGroup ]
6520 for i,obj in enumerate( SubMeshOrGroup ):
6521 if isinstance( obj, Mesh ):
6522 SubMeshOrGroup = [ obj.GetMesh() ]
6524 if isinstance( obj, int ):
6525 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6526 unRegister.set( SubMeshOrGroup )
6529 if not isinstance( exceptNodes, list ):
6530 exceptNodes = [ exceptNodes ]
6531 if exceptNodes and isinstance( exceptNodes[0], int ):
6532 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6533 unRegister.set( exceptNodes )
6535 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6536 exceptNodes, SeparateCornerAndMediumNodes)
6538 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6543 GroupsOfNodes: a list of groups of nodes IDs for merging.
6544 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6545 in all elements and mesh groups by nodes 1 and 25 correspondingly
6546 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6547 If *NodesToKeep* does not include a node to keep for some group to merge,
6548 then the first node in the group is kept.
6549 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6553 This operation can create gaps in numeration of nodes or elements.
6554 Call :meth:`RenumberElements` to remove the gaps.
6556 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6558 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6560 Find the elements built on the same nodes.
6563 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6564 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6568 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6571 unRegister = genObjUnRegister()
6572 if MeshOrSubMeshOrGroup is None:
6573 MeshOrSubMeshOrGroup = [ self.mesh ]
6574 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6575 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6576 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6577 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6578 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6579 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6580 unRegister.set( MeshOrSubMeshOrGroup )
6581 for item in MeshOrSubMeshOrGroup:
6582 if isinstance( item, Mesh ):
6583 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6585 if not isinstance( exceptElements, list ):
6586 exceptElements = [ exceptElements ]
6587 if exceptElements and isinstance( exceptElements[0], int ):
6588 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6589 unRegister.set( exceptElements )
6591 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6593 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6595 Merge elements in each given group.
6598 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6599 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6600 replaced in all mesh groups by elements 1 and 25)
6601 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6602 If *ElementsToKeep* does not include an element to keep for some group to merge,
6603 then the first element in the group is kept.
6606 This operation can create gaps in numeration of elements.
6607 Call :meth:`RenumberElements` to remove the gaps.
6610 unRegister = genObjUnRegister()
6612 if not isinstance( ElementsToKeep, list ):
6613 ElementsToKeep = [ ElementsToKeep ]
6614 if isinstance( ElementsToKeep[0], int ):
6615 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6616 unRegister.set( ElementsToKeep )
6618 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6620 def MergeEqualElements(self):
6622 Leave one element and remove all other elements built on the same nodes.
6625 This operation can create gaps in numeration of elements.
6626 Call :meth:`RenumberElements` to remove the gaps.
6629 self.editor.MergeEqualElements()
6631 def FindFreeBorders(self, ClosedOnly=True):
6633 Returns all or only closed free borders
6636 list of SMESH.FreeBorder's
6639 return self.editor.FindFreeBorders( ClosedOnly )
6641 def FillHole(self, holeNodes, groupName=""):
6643 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6646 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6647 must describe all sequential nodes of the hole border. The first and the last
6648 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6649 groupName (string): name of a group to add new faces
6651 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6655 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6656 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6657 if not isinstance( holeNodes, SMESH.FreeBorder ):
6658 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6659 return self.editor.FillHole( holeNodes, groupName )
6661 def FindCoincidentFreeBorders (self, tolerance=0.):
6663 Return groups of FreeBorder's coincident within the given tolerance.
6666 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6667 size of elements adjacent to free borders being compared is used.
6670 SMESH.CoincidentFreeBorders structure
6673 return self.editor.FindCoincidentFreeBorders( tolerance )
6675 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6677 Sew FreeBorder's of each group
6680 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6681 where each enclosed list contains node IDs of a group of coincident free
6682 borders such that each consequent triple of IDs within a group describes
6683 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6684 last node of a border.
6685 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6686 groups of coincident free borders, each group including two borders.
6687 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6688 polygons if a node of opposite border falls on a face edge, else such
6689 faces are split into several ones.
6690 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6691 polyhedra if a node of opposite border falls on a volume edge, else such
6692 volumes, if any, remain intact and the mesh becomes non-conformal.
6695 a number of successfully sewed groups
6698 This operation can create gaps in numeration of nodes or elements.
6699 Call :meth:`RenumberElements` to remove the gaps.
6702 if freeBorders and isinstance( freeBorders, list ):
6703 # construct SMESH.CoincidentFreeBorders
6704 if isinstance( freeBorders[0], int ):
6705 freeBorders = [freeBorders]
6707 coincidentGroups = []
6708 for nodeList in freeBorders:
6709 if not nodeList or len( nodeList ) % 3:
6710 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6713 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6714 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6715 nodeList = nodeList[3:]
6717 coincidentGroups.append( group )
6719 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6721 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6723 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6724 FirstNodeID2, SecondNodeID2, LastNodeID2,
6725 CreatePolygons, CreatePolyedrs):
6730 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6733 This operation can create gaps in numeration of nodes or elements.
6734 Call :meth:`RenumberElements` to remove the gaps.
6737 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6738 FirstNodeID2, SecondNodeID2, LastNodeID2,
6739 CreatePolygons, CreatePolyedrs)
6741 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6742 FirstNodeID2, SecondNodeID2):
6744 Sew conform free borders
6747 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6750 This operation can create gaps in numeration of elements.
6751 Call :meth:`RenumberElements` to remove the gaps.
6754 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6755 FirstNodeID2, SecondNodeID2)
6757 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6758 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6763 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6766 This operation can create gaps in numeration of elements.
6767 Call :meth:`RenumberElements` to remove the gaps.
6770 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6771 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6773 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6774 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6775 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6777 Sew two sides of a mesh. The nodes belonging to Side1 are
6778 merged with the nodes of elements of Side2.
6779 The number of elements in theSide1 and in theSide2 must be
6780 equal and they should have similar nodal connectivity.
6781 The nodes to merge should belong to side borders and
6782 the first node should be linked to the second.
6785 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6788 This operation can create gaps in numeration of nodes.
6789 Call :meth:`RenumberElements` to remove the gaps.
6792 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6793 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6794 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6796 def ChangeElemNodes(self, ide, newIDs):
6798 Set new nodes for the given element. Number of nodes should be kept.
6805 False if the number of nodes does not correspond to the type of element
6808 return self.editor.ChangeElemNodes(ide, newIDs)
6810 def GetLastCreatedNodes(self):
6812 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6813 created, this method return the list of their IDs.
6814 If new nodes were not created - return empty list
6817 the list of integer values (can be empty)
6820 return self.editor.GetLastCreatedNodes()
6822 def GetLastCreatedElems(self):
6824 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6825 created this method return the list of their IDs.
6826 If new elements were not created - return empty list
6829 the list of integer values (can be empty)
6832 return self.editor.GetLastCreatedElems()
6834 def ClearLastCreated(self):
6836 Forget what nodes and elements were created by the last mesh edition operation
6839 self.editor.ClearLastCreated()
6841 def DoubleElements(self, theElements, theGroupName=""):
6843 Create duplicates of given elements, i.e. create new elements based on the
6844 same nodes as the given ones.
6847 theElements: container of elements to duplicate. It can be a
6848 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6849 or a list of element IDs. If *theElements* is
6850 a :class:`Mesh`, elements of highest dimension are duplicated
6851 theGroupName: a name of group to contain the generated elements.
6852 If a group with such a name already exists, the new elements
6853 are added to the existing group, else a new group is created.
6854 If *theGroupName* is empty, new elements are not added
6858 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6859 None if *theGroupName* == "".
6862 unRegister = genObjUnRegister()
6863 if isinstance( theElements, Mesh ):
6864 theElements = theElements.mesh
6865 elif isinstance( theElements, list ):
6866 theElements = self.GetIDSource( theElements, SMESH.ALL )
6867 unRegister.set( theElements )
6868 return self.editor.DoubleElements(theElements, theGroupName)
6870 def DoubleNodes(self, theNodes, theModifiedElems):
6872 Create a hole in a mesh by doubling the nodes of some particular elements
6875 theNodes: IDs of nodes to be doubled
6876 theModifiedElems: IDs of elements to be updated by the new (doubled)
6877 nodes. If list of element identifiers is empty then nodes are doubled but
6878 they not assigned to elements
6881 True if operation has been completed successfully, False otherwise
6884 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6886 def DoubleNode(self, theNodeId, theModifiedElems):
6888 Create a hole in a mesh by doubling the nodes of some particular elements.
6889 This method provided for convenience works as :meth:`DoubleNodes`.
6892 theNodeId: IDs of node to double
6893 theModifiedElems: IDs of elements to update
6896 True if operation has been completed successfully, False otherwise
6899 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6901 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6903 Create a hole in a mesh by doubling the nodes of some particular elements.
6904 This method provided for convenience works as :meth:`DoubleNodes`.
6907 theNodes: group of nodes to double.
6908 theModifiedElems: group of elements to update.
6909 theMakeGroup: forces the generation of a group containing new nodes.
6912 True or a created group if operation has been completed successfully,
6913 False or None otherwise
6917 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6918 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6920 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6922 Create a hole in a mesh by doubling the nodes of some particular elements.
6923 This method provided for convenience works as :meth:`DoubleNodes`.
6926 theNodes: list of groups of nodes to double.
6927 theModifiedElems: list of groups of elements to update.
6928 theMakeGroup: forces the generation of a group containing new nodes.
6931 True if operation has been completed successfully, False otherwise
6935 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6936 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6938 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6940 Create a hole in a mesh by doubling the nodes of some particular elements
6943 theElems: the list of elements (edges or faces) to replicate.
6944 The nodes for duplication could be found from these elements
6945 theNodesNot: list of nodes NOT to replicate
6946 theAffectedElems: the list of elements (cells and edges) to which the
6947 replicated nodes should be associated to
6950 True if operation has been completed successfully, False otherwise
6953 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6955 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6957 Create a hole in a mesh by doubling the nodes of some particular elements
6960 theElems: the list of elements (edges or faces) to replicate.
6961 The nodes for duplication could be found from these elements
6962 theNodesNot: list of nodes NOT to replicate
6963 theShape: shape to detect affected elements (element which geometric center
6964 located on or inside shape).
6965 The replicated nodes should be associated to affected elements.
6968 True if operation has been completed successfully, False otherwise
6971 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6973 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6974 theMakeGroup=False, theMakeNodeGroup=False):
6976 Create a hole in a mesh by doubling the nodes of some particular elements.
6977 This method provided for convenience works as :meth:`DoubleNodes`.
6980 theElems: group of of elements (edges or faces) to replicate.
6981 theNodesNot: group of nodes NOT to replicate.
6982 theAffectedElems: group of elements to which the replicated nodes
6983 should be associated to.
6984 theMakeGroup: forces the generation of a group containing new elements.
6985 theMakeNodeGroup: forces the generation of a group containing new nodes.
6988 True or created groups (one or two) if operation has been completed successfully,
6989 False or None otherwise
6992 if theMakeGroup or theMakeNodeGroup:
6993 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6995 theMakeGroup, theMakeNodeGroup)
6996 if theMakeGroup and theMakeNodeGroup:
6999 return twoGroups[ int(theMakeNodeGroup) ]
7000 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7002 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7004 Create a hole in a mesh by doubling the nodes of some particular elements.
7005 This method provided for convenience works as :meth:`DoubleNodes`.
7008 theElems: group of of elements (edges or faces) to replicate
7009 theNodesNot: group of nodes not to replicate
7010 theShape: shape to detect affected elements (element which geometric center
7011 located on or inside shape).
7012 The replicated nodes should be associated to affected elements
7015 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7017 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7018 theMakeGroup=False, theMakeNodeGroup=False):
7020 Create a hole in a mesh by doubling the nodes of some particular elements.
7021 This method provided for convenience works as :meth:`DoubleNodes`.
7024 theElems: list of groups of elements (edges or faces) to replicate
7025 theNodesNot: list of groups of nodes NOT to replicate
7026 theAffectedElems: group of elements to which the replicated nodes
7027 should be associated to
7028 theMakeGroup: forces generation of a group containing new elements.
7029 theMakeNodeGroup: forces generation of a group containing new nodes
7032 True or created groups (one or two) if operation has been completed successfully,
7033 False or None otherwise
7036 if theMakeGroup or theMakeNodeGroup:
7037 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7039 theMakeGroup, theMakeNodeGroup)
7040 if theMakeGroup and theMakeNodeGroup:
7043 return twoGroups[ int(theMakeNodeGroup) ]
7044 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7046 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7048 Create a hole in a mesh by doubling the nodes of some particular elements.
7049 This method provided for convenience works as :meth:`DoubleNodes`.
7052 theElems: list of groups of elements (edges or faces) to replicate
7053 theNodesNot: list of groups of nodes NOT to replicate
7054 theShape: shape to detect affected elements (element which geometric center
7055 located on or inside shape).
7056 The replicated nodes should be associated to affected elements
7059 True if operation has been completed successfully, False otherwise
7062 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7064 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7066 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7067 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7070 theElems: list of groups of nodes or elements (edges or faces) to replicate
7071 theNodesNot: list of groups of nodes NOT to replicate
7072 theShape: shape to detect affected elements (element which geometric center
7073 located on or inside shape).
7074 The replicated nodes should be associated to affected elements
7077 groups of affected elements in order: volumes, faces, edges
7080 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7082 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7085 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7086 The list of groups must describe a partition of the mesh volumes.
7087 The nodes of the internal faces at the boundaries of the groups are doubled.
7088 In option, the internal faces are replaced by flat elements.
7089 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7092 theDomains: list of groups of volumes
7093 createJointElems: if True, create the elements
7094 onAllBoundaries: if True, the nodes and elements are also created on
7095 the boundary between *theDomains* and the rest mesh
7098 True if operation has been completed successfully, False otherwise
7101 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7103 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7105 Double nodes on some external faces and create flat elements.
7106 Flat elements are mainly used by some types of mechanic calculations.
7108 Each group of the list must be constituted of faces.
7109 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7112 theGroupsOfFaces: list of groups of faces
7115 True if operation has been completed successfully, False otherwise
7118 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7120 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7122 Identify all the elements around a geom shape, get the faces delimiting the hole
7124 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7126 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7128 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7129 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7130 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7131 If there are several paths connecting a pair of points, the shortest path is
7132 selected by the module. Position of the cutting plane is defined by the two
7133 points and an optional vector lying on the plane specified by a PolySegment.
7134 By default the vector is defined by Mesh module as following. A middle point
7135 of the two given points is computed. The middle point is projected to the mesh.
7136 The vector goes from the middle point to the projection point. In case of planar
7137 mesh, the vector is normal to the mesh.
7139 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7142 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7143 groupName: optional name of a group where created mesh segments will be added.
7146 editor = self.editor
7148 editor = self.mesh.GetMeshEditPreviewer()
7149 segmentsRes = editor.MakePolyLine( segments, groupName )
7150 for i, seg in enumerate( segmentsRes ):
7151 segments[i].vector = seg.vector
7153 return editor.GetPreviewData()
7156 def MakeSlot(self, segmentGroup, width ):
7158 Create a slot of given width around given 1D elements lying on a triangle mesh.
7159 The slot is constructed by cutting faces by cylindrical surfaces made
7160 around each segment. Segments are expected to be created by MakePolyLine().
7163 FaceEdge's located at the slot boundary
7165 return self.editor.MakeSlot( segmentGroup, width )
7167 def GetFunctor(self, funcType ):
7169 Return a cached numerical functor by its type.
7172 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7173 Note that not all items correspond to numerical functors.
7176 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7179 fn = self.functors[ funcType._v ]
7181 fn = self.smeshpyD.GetFunctor(funcType)
7182 fn.SetMesh(self.mesh)
7183 self.functors[ funcType._v ] = fn
7186 def FunctorValue(self, funcType, elemId, isElem=True):
7188 Return value of a functor for a given element
7191 funcType: an item of :class:`SMESH.FunctorType` enum.
7192 elemId: element or node ID
7193 isElem: *elemId* is ID of element or node
7196 the functor value or zero in case of invalid arguments
7199 fn = self.GetFunctor( funcType )
7200 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7201 val = fn.GetValue(elemId)
7206 def GetLength(self, elemId=None):
7208 Get length of given 1D elements or of all 1D mesh elements
7211 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.
7214 Sum of lengths of given elements
7219 length = self.smeshpyD.GetLength(self)
7220 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7221 length = self.smeshpyD.GetLength(elemId)
7224 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7226 length += self.smeshpyD.GetLength(obj)
7227 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7228 unRegister = genObjUnRegister()
7229 obj = self.GetIDSource( elemId )
7230 unRegister.set( obj )
7231 length = self.smeshpyD.GetLength( obj )
7233 length = self.FunctorValue(SMESH.FT_Length, elemId)
7236 def GetArea(self, elemId=None):
7238 Get area of given 2D elements or of all 2D mesh elements
7241 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.
7244 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7249 area = self.smeshpyD.GetArea(self)
7250 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7251 area = self.smeshpyD.GetArea(elemId)
7254 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7256 area += self.smeshpyD.GetArea(obj)
7257 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7258 unRegister = genObjUnRegister()
7259 obj = self.GetIDSource( elemId )
7260 unRegister.set( obj )
7261 area = self.smeshpyD.GetArea( obj )
7263 area = self.FunctorValue(SMESH.FT_Area, elemId)
7266 def GetVolume(self, elemId=None):
7268 Get volume of given 3D elements or of all 3D mesh elements
7271 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.
7274 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7279 volume= self.smeshpyD.GetVolume(self)
7280 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7281 volume= self.smeshpyD.GetVolume(elemId)
7284 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7286 volume+= self.smeshpyD.GetVolume(obj)
7287 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7288 unRegister = genObjUnRegister()
7289 obj = self.GetIDSource( elemId )
7290 unRegister.set( obj )
7291 volume= self.smeshpyD.GetVolume( obj )
7293 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7296 def GetAngle(self, node1, node2, node3 ):
7298 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7301 node1,node2,node3: IDs of the three nodes
7304 Angle in radians [0,PI]. -1 if failure case.
7306 p1 = self.GetNodeXYZ( node1 )
7307 p2 = self.GetNodeXYZ( node2 )
7308 p3 = self.GetNodeXYZ( node3 )
7309 if p1 and p2 and p3:
7310 return self.smeshpyD.GetAngle( p1,p2,p3 )
7314 def GetMaxElementLength(self, elemId):
7316 Get maximum element length.
7319 elemId: mesh element ID
7322 element's maximum length value
7325 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7326 ftype = SMESH.FT_MaxElementLength3D
7328 ftype = SMESH.FT_MaxElementLength2D
7329 return self.FunctorValue(ftype, elemId)
7331 def GetAspectRatio(self, elemId):
7333 Get aspect ratio of 2D or 3D element.
7336 elemId: mesh element ID
7339 element's aspect ratio value
7342 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7343 ftype = SMESH.FT_AspectRatio3D
7345 ftype = SMESH.FT_AspectRatio
7346 return self.FunctorValue(ftype, elemId)
7348 def GetWarping(self, elemId):
7350 Get warping angle of 2D element.
7353 elemId: mesh element ID
7356 element's warping angle value
7359 return self.FunctorValue(SMESH.FT_Warping, elemId)
7361 def GetMinimumAngle(self, elemId):
7363 Get minimum angle of 2D element.
7366 elemId: mesh element ID
7369 element's minimum angle value
7372 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7374 def GetTaper(self, elemId):
7376 Get taper of 2D element.
7379 elemId: mesh element ID
7382 element's taper value
7385 return self.FunctorValue(SMESH.FT_Taper, elemId)
7387 def GetSkew(self, elemId):
7389 Get skew of 2D element.
7392 elemId: mesh element ID
7395 element's skew value
7398 return self.FunctorValue(SMESH.FT_Skew, elemId)
7400 def GetMinMax(self, funType, meshPart=None):
7402 Return minimal and maximal value of a given functor.
7405 funType (SMESH.FunctorType): a functor type.
7406 Note that not all items of :class:`SMESH.FunctorType` corresponds
7407 to numerical functors.
7408 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7414 unRegister = genObjUnRegister()
7415 if isinstance( meshPart, list ):
7416 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7417 unRegister.set( meshPart )
7418 if isinstance( meshPart, Mesh ):
7419 meshPart = meshPart.mesh
7420 fun = self.GetFunctor( funType )
7423 if hasattr( meshPart, "SetMesh" ):
7424 meshPart.SetMesh( self.mesh ) # set mesh to filter
7425 hist = fun.GetLocalHistogram( 1, False, meshPart )
7427 hist = fun.GetHistogram( 1, False )
7429 return hist[0].min, hist[0].max
7432 pass # end of Mesh class
7435 class meshProxy(SMESH._objref_SMESH_Mesh):
7437 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7438 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7440 def __init__(self,*args):
7441 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7442 def __deepcopy__(self, memo=None):
7443 new = self.__class__(self)
7445 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7446 if len( args ) == 3:
7447 args += SMESH.ALL_NODES, True
7448 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7449 def ExportToMEDX(self, *args): # function removed
7450 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7451 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7452 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7453 def ExportToMED(self, *args): # function removed
7454 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7455 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7457 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7459 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7460 def ExportPartToMED(self, *args): # 'version' parameter removed
7461 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7462 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7463 def ExportMED(self, *args): # signature of method changed
7464 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7466 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7468 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7469 def ExportUNV(self, *args): # renumber arg added
7470 if len( args ) == 1:
7472 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
7473 def ExportDAT(self, *args): # renumber arg added
7474 if len( args ) == 1:
7476 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
7478 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7481 class submeshProxy(SMESH._objref_SMESH_subMesh):
7484 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7486 def __init__(self,*args):
7487 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7489 def __deepcopy__(self, memo=None):
7490 new = self.__class__(self)
7493 def Compute(self,refresh=False):
7495 Compute the sub-mesh and return the status of the computation
7498 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7503 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7504 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7508 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7510 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7512 if salome.sg.hasDesktop():
7513 if refresh: salome.sg.updateObjBrowser()
7518 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7521 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7523 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7524 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7527 def __init__(self,*args):
7528 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7530 def __getattr__(self, name ): # method called if an attribute not found
7531 if not self.mesh: # look for name() method in Mesh class
7532 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7533 if hasattr( self.mesh, name ):
7534 return getattr( self.mesh, name )
7535 if name == "ExtrusionAlongPathObjX":
7536 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7537 print("meshEditor: attribute '%s' NOT FOUND" % name)
7539 def __deepcopy__(self, memo=None):
7540 new = self.__class__(self)
7542 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7543 if len( args ) == 1: args += False,
7544 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7545 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7546 if len( args ) == 2: args += False,
7547 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7548 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7549 if len( args ) == 1:
7550 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7551 NodesToKeep = args[1]
7552 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7553 unRegister = genObjUnRegister()
7555 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7556 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7557 if not isinstance( NodesToKeep, list ):
7558 NodesToKeep = [ NodesToKeep ]
7559 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7561 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7563 class Pattern(SMESH._objref_SMESH_Pattern):
7565 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7566 variables in some methods
7569 def LoadFromFile(self, patternTextOrFile ):
7570 text = patternTextOrFile
7571 if os.path.exists( text ):
7572 text = open( patternTextOrFile ).read()
7574 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7576 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7577 decrFun = lambda i: i-1
7578 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7579 theMesh.SetParameters(Parameters)
7580 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7582 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7583 decrFun = lambda i: i-1
7584 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7585 theMesh.SetParameters(Parameters)
7586 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7588 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7589 if isinstance( mesh, Mesh ):
7590 mesh = mesh.GetMesh()
7591 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7593 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7595 Registering the new proxy for Pattern
7600 Private class used to bind methods creating algorithms to the class Mesh
7603 def __init__(self, method):
7605 self.defaultAlgoType = ""
7606 self.algoTypeToClass = {}
7607 self.method = method
7609 def add(self, algoClass):
7611 Store a python class of algorithm
7613 if inspect.isclass(algoClass) and \
7614 hasattr( algoClass, "algoType"):
7615 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7616 if not self.defaultAlgoType and \
7617 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7618 self.defaultAlgoType = algoClass.algoType
7619 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7621 def copy(self, mesh):
7623 Create a copy of self and assign mesh to the copy
7626 other = algoCreator( self.method )
7627 other.defaultAlgoType = self.defaultAlgoType
7628 other.algoTypeToClass = self.algoTypeToClass
7632 def __call__(self,algo="",geom=0,*args):
7634 Create an instance of algorithm
7638 if isinstance( algo, str ):
7640 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7641 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7646 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7648 elif not algoType and isinstance( geom, str ):
7653 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7655 elif isinstance( arg, str ) and not algoType:
7658 import traceback, sys
7659 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7660 sys.stderr.write( msg + '\n' )
7661 tb = traceback.extract_stack(None,2)
7662 traceback.print_list( [tb[0]] )
7664 algoType = self.defaultAlgoType
7665 if not algoType and self.algoTypeToClass:
7666 algoType = sorted( self.algoTypeToClass.keys() )[0]
7667 if algoType in self.algoTypeToClass:
7668 #print("Create algo",algoType)
7669 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7670 raise RuntimeError( "No class found for algo type %s" % algoType)
7673 class hypMethodWrapper:
7675 Private class used to substitute and store variable parameters of hypotheses.
7678 def __init__(self, hyp, method):
7680 self.method = method
7681 #print("REBIND:", method.__name__)
7684 def __call__(self,*args):
7686 call a method of hypothesis with calling SetVarParameter() before
7690 return self.method( self.hyp, *args ) # hypothesis method with no args
7692 #print("MethWrapper.__call__", self.method.__name__, args)
7694 parsed = ParseParameters(*args) # replace variables with their values
7695 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7696 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7697 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7698 # maybe there is a replaced string arg which is not variable
7699 result = self.method( self.hyp, *args )
7700 except ValueError as detail: # raised by ParseParameters()
7702 result = self.method( self.hyp, *args )
7703 except omniORB.CORBA.BAD_PARAM:
7704 raise ValueError(detail) # wrong variable name
7709 class genObjUnRegister:
7711 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7714 def __init__(self, genObj=None):
7715 self.genObjList = []
7719 def set(self, genObj):
7720 "Store one or a list of of SALOME.GenericObj'es"
7721 if isinstance( genObj, list ):
7722 self.genObjList.extend( genObj )
7724 self.genObjList.append( genObj )
7728 for genObj in self.genObjList:
7729 if genObj and hasattr( genObj, "UnRegister" ):
7732 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7734 Bind methods creating mesher plug-ins to the Mesh class
7737 # print("pluginName: ", pluginName)
7738 pluginBuilderName = pluginName + "Builder"
7740 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7741 except Exception as e:
7742 from salome_utils import verbose
7743 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7745 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7746 plugin = eval( pluginBuilderName )
7747 # print(" plugin:" , str(plugin))
7749 # add methods creating algorithms to Mesh
7750 for k in dir( plugin ):
7751 if k[0] == '_': continue
7752 algo = getattr( plugin, k )
7753 #print(" algo:", str(algo))
7754 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7755 #print(" meshMethod:" , str(algo.meshMethod))
7756 if not hasattr( Mesh, algo.meshMethod ):
7757 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7759 _mmethod = getattr( Mesh, algo.meshMethod )
7760 if hasattr( _mmethod, "add" ):