1 # Copyright (C) 2007-2022 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 CreateDualMesh( self, mesh, meshName, adaptToShape):
778 Create a dual of a mesh.
781 mesh: Tetrahedron mesh
782 :class:`mesh, <SMESH.SMESH_IDSource>`.
784 meshName: a name of the new mesh
785 adpatToShape: if true project boundary points on shape
788 an instance of class :class:`Mesh`
790 if isinstance( mesh, Mesh ):
791 mesh = mesh.GetMesh()
792 print("calling createdualmesh from Python")
793 dualMesh = SMESH._objref_SMESH_Gen.CreateDualMesh(self, mesh, meshName, adaptToShape)
794 return Mesh(self, self.geompyD, dualMesh)
797 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
799 Create a mesh by copying a part of another mesh.
802 meshPart: a part of mesh to copy, either
803 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
804 To copy nodes or elements not forming any mesh object,
805 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
806 meshName: a name of the new mesh
807 toCopyGroups: to create in the new mesh groups the copied elements belongs to
808 toKeepIDs: to preserve order of the copied elements or not
811 an instance of class :class:`Mesh`
814 if isinstance( meshPart, Mesh ):
815 meshPart = meshPart.GetMesh()
816 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
817 return Mesh(self, self.geompyD, mesh)
819 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
820 toReuseHypotheses=True, toCopyElements=True):
822 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
823 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
824 To facilitate and speed up the operation, consider using
825 "Set presentation parameters and sub-shapes from arguments" option in
826 a dialog of geometrical operation used to create the new geometry.
829 sourceMesh: the mesh to copy definition of.
830 newGeom: the new geometry.
831 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
832 toCopyGroups: to create groups in the new mesh.
833 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
834 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
837 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
838 *invalidEntries* are study entries of objects whose
839 counterparts are not found in the *newGeom*, followed by entries
840 of mesh sub-objects that are invalid because they depend on a not found
843 if isinstance( sourceMesh, Mesh ):
844 sourceMesh = sourceMesh.GetMesh()
846 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
847 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
851 return ( ok, Mesh(self, self.geompyD, newMesh),
852 newGroups, newSubMeshes, newHypotheses, invalidEntries )
854 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
856 Return IDs of sub-shapes
859 theMainObject (GEOM.GEOM_Object): a shape
860 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
862 the list of integer values
865 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
867 def GetPattern(self):
869 Create a pattern mapper.
872 an instance of :class:`SMESH.SMESH_Pattern`
874 :ref:`Example of Patterns usage <tui_pattern_mapping>`
877 return SMESH._objref_SMESH_Gen.GetPattern(self)
879 def SetBoundaryBoxSegmentation(self, nbSegments):
881 Set number of segments per diagonal of boundary box of geometry, by which
882 default segment length of appropriate 1D hypotheses is defined in GUI.
886 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
888 # Filtering. Auxiliary functions:
889 # ------------------------------
891 def GetEmptyCriterion(self):
893 Create an empty criterion
896 :class:`SMESH.Filter.Criterion`
899 Type = self.EnumToLong(FT_Undefined)
900 Compare = self.EnumToLong(FT_Undefined)
904 UnaryOp = self.EnumToLong(FT_Undefined)
905 BinaryOp = self.EnumToLong(FT_Undefined)
908 Precision = -1 ##@1e-07
909 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
910 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
912 def GetCriterion(self,elementType,
914 Compare = FT_EqualTo,
916 UnaryOp=FT_Undefined,
917 BinaryOp=FT_Undefined,
920 Create a criterion by the given parameters
921 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
924 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
925 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
926 Note that the items starting from FT_LessThan are not suitable for *CritType*.
927 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
928 Threshold: the threshold value (range of ids as string, shape, numeric)
929 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
930 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
932 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
933 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
936 :class:`SMESH.Filter.Criterion`
938 Example: :ref:`combining_filters`
941 if not CritType in SMESH.FunctorType._items:
942 raise TypeError("CritType should be of SMESH.FunctorType")
943 aCriterion = self.GetEmptyCriterion()
944 aCriterion.TypeOfElement = elementType
945 aCriterion.Type = self.EnumToLong(CritType)
946 aCriterion.Tolerance = Tolerance
948 aThreshold = Threshold
950 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
951 aCriterion.Compare = self.EnumToLong(Compare)
952 elif Compare == "=" or Compare == "==":
953 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
955 aCriterion.Compare = self.EnumToLong(FT_LessThan)
957 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
958 elif Compare != FT_Undefined:
959 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
962 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
963 FT_BelongToCylinder, FT_LyingOnGeom]:
964 # Check that Threshold is GEOM object
965 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
966 aCriterion.ThresholdStr = GetName(aThreshold)
967 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
968 if not aCriterion.ThresholdID:
969 name = aCriterion.ThresholdStr
971 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
972 geompyD = aThreshold.GetGen()
973 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
974 # or a name of GEOM object
975 elif isinstance( aThreshold, str ):
976 aCriterion.ThresholdStr = aThreshold
978 raise TypeError("The Threshold should be a shape.")
979 if isinstance(UnaryOp,float):
980 aCriterion.Tolerance = UnaryOp
981 UnaryOp = FT_Undefined
983 elif CritType == FT_BelongToMeshGroup:
984 # Check that Threshold is a group
985 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
986 if aThreshold.GetType() != elementType:
987 raise ValueError("Group type mismatches Element type")
988 aCriterion.ThresholdStr = aThreshold.GetName()
989 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
990 study = salome.myStudy
992 so = study.FindObjectIOR( aCriterion.ThresholdID )
996 aCriterion.ThresholdID = entry
998 raise TypeError("The Threshold should be a Mesh Group")
999 elif CritType == FT_RangeOfIds:
1000 # Check that Threshold is string
1001 if isinstance(aThreshold, str):
1002 aCriterion.ThresholdStr = aThreshold
1004 raise TypeError("The Threshold should be a string.")
1005 elif CritType == FT_CoplanarFaces:
1006 # Check the Threshold
1007 if isinstance(aThreshold, int):
1008 aCriterion.ThresholdID = str(aThreshold)
1009 elif isinstance(aThreshold, str):
1010 ID = int(aThreshold)
1012 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
1013 aCriterion.ThresholdID = aThreshold
1015 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1016 elif CritType == FT_ConnectedElements:
1017 # Check the Threshold
1018 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1019 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1020 if not aCriterion.ThresholdID:
1021 name = aThreshold.GetName()
1023 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1024 geompyD = aThreshold.GetGen()
1025 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
1026 elif isinstance(aThreshold, int): # node id
1027 aCriterion.Threshold = aThreshold
1028 elif isinstance(aThreshold, list): # 3 point coordinates
1029 if len( aThreshold ) < 3:
1030 raise ValueError("too few point coordinates, must be 3")
1031 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1032 elif isinstance(aThreshold, str):
1033 if aThreshold.isdigit():
1034 aCriterion.Threshold = aThreshold # node id
1036 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1038 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1039 "or a list of point coordinates and not '%s'"%aThreshold)
1040 elif CritType == FT_ElemGeomType:
1041 # Check the Threshold
1043 aCriterion.Threshold = self.EnumToLong(aThreshold)
1044 assert( aThreshold in SMESH.GeometryType._items )
1046 if isinstance(aThreshold, int):
1047 aCriterion.Threshold = aThreshold
1049 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1052 elif CritType == FT_EntityType:
1053 # Check the Threshold
1055 aCriterion.Threshold = self.EnumToLong(aThreshold)
1056 assert( aThreshold in SMESH.EntityType._items )
1058 if isinstance(aThreshold, int):
1059 aCriterion.Threshold = aThreshold
1061 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1065 elif CritType == FT_GroupColor:
1066 # Check the Threshold
1068 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1070 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1072 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1073 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1074 FT_BareBorderFace, FT_BareBorderVolume,
1075 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1076 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1077 # At this point the Threshold is unnecessary
1078 if aThreshold == FT_LogicalNOT:
1079 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1080 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1081 aCriterion.BinaryOp = aThreshold
1085 aThreshold = float(aThreshold)
1086 aCriterion.Threshold = aThreshold
1088 raise TypeError("The Threshold should be a number.")
1091 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1092 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1094 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1095 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1097 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1098 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1100 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1101 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1105 def GetFilter(self,elementType,
1106 CritType=FT_Undefined,
1109 UnaryOp=FT_Undefined,
1113 Create a filter with the given parameters
1116 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1117 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1118 Note that the items starting from FT_LessThan are not suitable for CritType.
1119 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1120 Threshold: the threshold value (range of ids as string, shape, numeric)
1121 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1122 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1123 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1124 mesh: the mesh to initialize the filter with
1127 :class:`SMESH.Filter`
1130 See :doc:`Filters usage examples <tui_filters>`
1133 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1134 aFilterMgr = self.CreateFilterManager()
1135 aFilter = aFilterMgr.CreateFilter()
1137 aCriteria.append(aCriterion)
1138 aFilter.SetCriteria(aCriteria)
1140 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1141 else : aFilter.SetMesh( mesh )
1142 aFilterMgr.UnRegister()
1145 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1147 Create a filter from criteria
1150 criteria: a list of :class:`SMESH.Filter.Criterion`
1151 binOp: binary operator used when binary operator of criteria is undefined
1154 :class:`SMESH.Filter`
1157 See :doc:`Filters usage examples <tui_filters>`
1160 for i in range( len( criteria ) - 1 ):
1161 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1162 criteria[i].BinaryOp = self.EnumToLong( binOp )
1163 aFilterMgr = self.CreateFilterManager()
1164 aFilter = aFilterMgr.CreateFilter()
1165 aFilter.SetCriteria(criteria)
1166 aFilterMgr.UnRegister()
1169 def GetFunctor(self,theCriterion):
1171 Create a numerical functor by its type
1174 theCriterion (SMESH.FunctorType): functor type.
1175 Note that not all items correspond to numerical functors.
1178 :class:`SMESH.NumericalFunctor`
1181 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1183 aFilterMgr = self.CreateFilterManager()
1185 if theCriterion == FT_AspectRatio:
1186 functor = aFilterMgr.CreateAspectRatio()
1187 elif theCriterion == FT_AspectRatio3D:
1188 functor = aFilterMgr.CreateAspectRatio3D()
1189 elif theCriterion == FT_Warping:
1190 functor = aFilterMgr.CreateWarping()
1191 elif theCriterion == FT_MinimumAngle:
1192 functor = aFilterMgr.CreateMinimumAngle()
1193 elif theCriterion == FT_Taper:
1194 functor = aFilterMgr.CreateTaper()
1195 elif theCriterion == FT_Skew:
1196 functor = aFilterMgr.CreateSkew()
1197 elif theCriterion == FT_Area:
1198 functor = aFilterMgr.CreateArea()
1199 elif theCriterion == FT_Volume3D:
1200 functor = aFilterMgr.CreateVolume3D()
1201 elif theCriterion == FT_MaxElementLength2D:
1202 functor = aFilterMgr.CreateMaxElementLength2D()
1203 elif theCriterion == FT_MaxElementLength3D:
1204 functor = aFilterMgr.CreateMaxElementLength3D()
1205 elif theCriterion == FT_MultiConnection:
1206 functor = aFilterMgr.CreateMultiConnection()
1207 elif theCriterion == FT_MultiConnection2D:
1208 functor = aFilterMgr.CreateMultiConnection2D()
1209 elif theCriterion == FT_Length:
1210 functor = aFilterMgr.CreateLength()
1211 elif theCriterion == FT_Length2D:
1212 functor = aFilterMgr.CreateLength2D()
1213 elif theCriterion == FT_Length3D:
1214 functor = aFilterMgr.CreateLength3D()
1215 elif theCriterion == FT_Deflection2D:
1216 functor = aFilterMgr.CreateDeflection2D()
1217 elif theCriterion == FT_NodeConnectivityNumber:
1218 functor = aFilterMgr.CreateNodeConnectivityNumber()
1219 elif theCriterion == FT_BallDiameter:
1220 functor = aFilterMgr.CreateBallDiameter()
1222 print("Error: given parameter is not numerical functor type.")
1223 aFilterMgr.UnRegister()
1226 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1231 theHType (string): mesh hypothesis type
1232 theLibName (string): mesh plug-in library name
1235 created hypothesis instance
1237 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1239 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1242 # wrap hypothesis methods
1243 for meth_name in dir( hyp.__class__ ):
1244 if not meth_name.startswith("Get") and \
1245 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1246 method = getattr ( hyp.__class__, meth_name )
1247 if callable(method):
1248 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1252 def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1254 Create hypothesis initialized according to parameters
1257 hypType (string): hypothesis type
1258 libName (string): plug-in library name
1259 mesh: optional mesh by which a hypotheses can initialize self
1260 shape: optional geometry by size of which a hypotheses can initialize self
1261 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1264 created hypothesis instance
1266 if isinstance( mesh, Mesh ):
1267 mesh = mesh.GetMesh()
1268 if isinstance( initParams, (bool,int)):
1269 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1270 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1271 mesh, shape, initParams )
1273 def GetMeshInfo(self, obj):
1275 Get the mesh statistic.
1278 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1281 if isinstance( obj, Mesh ):
1284 if hasattr(obj, "GetMeshInfo"):
1285 values = obj.GetMeshInfo()
1286 for i in range(SMESH.Entity_Last._v):
1287 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1291 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1293 Get minimum distance between two objects
1295 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1296 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1299 src1 (SMESH.SMESH_IDSource): first source object
1300 src2 (SMESH.SMESH_IDSource): second source object
1301 id1 (int): node/element id from the first source
1302 id2 (int): node/element id from the second (or first) source
1303 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1304 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1307 minimum distance value
1310 :meth:`GetMinDistance`
1313 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1317 result = result.value
1320 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1322 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1324 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1325 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1328 src1 (SMESH.SMESH_IDSource): first source object
1329 src2 (SMESH.SMESH_IDSource): second source object
1330 id1 (int): node/element id from the first source
1331 id2 (int): node/element id from the second (or first) source
1332 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1333 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1336 :class:`SMESH.Measure` structure or None if input data is invalid
1341 if isinstance(src1, Mesh): src1 = src1.mesh
1342 if isinstance(src2, Mesh): src2 = src2.mesh
1343 if src2 is None and id2 != 0: src2 = src1
1344 if not hasattr(src1, "_narrow"): return None
1345 src1 = src1._narrow(SMESH.SMESH_IDSource)
1346 if not src1: return None
1347 unRegister = genObjUnRegister()
1350 e = m.GetMeshEditor()
1352 src1 = e.MakeIDSource([id1], SMESH.FACE)
1354 src1 = e.MakeIDSource([id1], SMESH.NODE)
1355 unRegister.set( src1 )
1357 if hasattr(src2, "_narrow"):
1358 src2 = src2._narrow(SMESH.SMESH_IDSource)
1359 if src2 and id2 != 0:
1361 e = m.GetMeshEditor()
1363 src2 = e.MakeIDSource([id2], SMESH.FACE)
1365 src2 = e.MakeIDSource([id2], SMESH.NODE)
1366 unRegister.set( src2 )
1369 aMeasurements = self.CreateMeasurements()
1370 unRegister.set( aMeasurements )
1371 result = aMeasurements.MinDistance(src1, src2)
1374 def BoundingBox(self, objects):
1376 Get bounding box of the specified object(s)
1379 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1382 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1385 :meth:`GetBoundingBox`
1388 result = self.GetBoundingBox(objects)
1392 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1395 def GetBoundingBox(self, objects):
1397 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1400 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1403 :class:`SMESH.Measure` structure
1409 if isinstance(objects, tuple):
1410 objects = list(objects)
1411 if not isinstance(objects, list):
1415 if isinstance(o, Mesh):
1416 srclist.append(o.mesh)
1417 elif hasattr(o, "_narrow"):
1418 src = o._narrow(SMESH.SMESH_IDSource)
1419 if src: srclist.append(src)
1422 aMeasurements = self.CreateMeasurements()
1423 result = aMeasurements.BoundingBox(srclist)
1424 aMeasurements.UnRegister()
1427 def GetLength(self, obj):
1429 Get sum of lengths of all 1D elements in the mesh object.
1432 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1435 sum of lengths of all 1D elements
1438 if isinstance(obj, Mesh): obj = obj.mesh
1439 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1440 aMeasurements = self.CreateMeasurements()
1441 value = aMeasurements.Length(obj)
1442 aMeasurements.UnRegister()
1445 def GetArea(self, obj):
1447 Get sum of areas of all 2D elements in the mesh object.
1450 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1453 sum of areas of all 2D elements
1456 if isinstance(obj, Mesh): obj = obj.mesh
1457 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1458 aMeasurements = self.CreateMeasurements()
1459 value = aMeasurements.Area(obj)
1460 aMeasurements.UnRegister()
1463 def GetVolume(self, obj):
1465 Get sum of volumes of all 3D elements in the mesh object.
1468 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1471 sum of volumes of all 3D elements
1474 if isinstance(obj, Mesh): obj = obj.mesh
1475 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1476 aMeasurements = self.CreateMeasurements()
1477 value = aMeasurements.Volume(obj)
1478 aMeasurements.UnRegister()
1481 def GetGravityCenter(self, obj):
1483 Get gravity center of all nodes of a mesh object.
1486 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1489 Three components of the gravity center (x,y,z)
1492 :meth:`Mesh.BaryCenter`
1494 if isinstance(obj, Mesh): obj = obj.mesh
1495 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1496 aMeasurements = self.CreateMeasurements()
1497 pointStruct = aMeasurements.GravityCenter(obj)
1498 aMeasurements.UnRegister()
1499 return pointStruct.x, pointStruct.y, pointStruct.z
1501 def GetAngle(self, p1, p2, p3 ):
1503 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1506 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1512 if isinstance( p1, list ): p1 = PointStruct(*p1)
1513 if isinstance( p2, list ): p2 = PointStruct(*p2)
1514 if isinstance( p3, list ): p3 = PointStruct(*p3)
1516 aMeasurements = self.CreateMeasurements()
1517 angle = aMeasurements.Angle(p1,p2,p3)
1518 aMeasurements.UnRegister()
1523 pass # end of class smeshBuilder
1526 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1527 """Registering the new proxy for SMESH.SMESH_Gen"""
1530 def New( instance=None, instanceGeom=None):
1532 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1533 interface to create or load meshes.
1538 salome.salome_init()
1539 from salome.smesh import smeshBuilder
1540 smesh = smeshBuilder.New()
1543 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1544 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1546 :class:`smeshBuilder` instance
1551 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1553 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1558 smeshInst = smeshBuilder()
1559 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1560 smeshInst.init_smesh(instanceGeom)
1564 # Public class: Mesh
1565 # ==================
1568 class Mesh(metaclass = MeshMeta):
1570 This class allows defining and managing a mesh.
1571 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1572 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1573 new nodes and elements and by changing the existing entities), to get information
1574 about a mesh and to export a mesh in different formats.
1581 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1586 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1587 sets the GUI name of this mesh to *name*.
1590 smeshpyD: an instance of smeshBuilder class
1591 geompyD: an instance of geomBuilder class
1592 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1593 name: Study name of the mesh
1596 self.smeshpyD = smeshpyD
1597 self.geompyD = geompyD
1602 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1605 # publish geom of mesh (issue 0021122)
1606 if not self.geom.GetStudyEntry():
1610 geo_name = name + " shape"
1612 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1613 geompyD.addToStudy( self.geom, geo_name )
1614 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1616 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1619 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1621 self.smeshpyD.SetName(self.mesh, name)
1623 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1626 self.geom = self.mesh.GetShapeToMesh()
1628 self.editor = self.mesh.GetMeshEditor()
1629 self.functors = [None] * SMESH.FT_Undefined._v
1631 # set self to algoCreator's
1632 for attrName in dir(self):
1633 attr = getattr( self, attrName )
1634 if isinstance( attr, algoCreator ):
1635 setattr( self, attrName, attr.copy( self ))
1642 Destructor. Clean-up resources
1645 self.mesh.UnRegister()
1649 def SetMesh(self, theMesh):
1651 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1654 theMesh: a :class:`SMESH.SMESH_Mesh` object
1656 # do not call Register() as this prevents mesh servant deletion at closing study
1657 #if self.mesh: self.mesh.UnRegister()
1660 #self.mesh.Register()
1661 self.geom = self.mesh.GetShapeToMesh()
1665 if salome.sg.hasDesktop():
1666 so = salome.ObjectToSObject( self.geom )
1667 comp = so.GetFatherComponent()
1668 if comp.ComponentDataType() == "SHAPERSTUDY":
1669 import shaperBuilder
1670 self.geompyD = shaperBuilder.New()
1673 if not self.geompyD:
1674 self.geompyD = self.geom.GetGen()
1679 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1682 a :class:`SMESH.SMESH_Mesh` object
1687 def GetEngine(self):
1689 Return a smeshBuilder instance created this mesh
1691 return self.smeshpyD
1693 def GetGeomEngine(self):
1695 Return a geomBuilder instance
1701 Get the name of the mesh
1704 the name of the mesh as a string
1707 name = GetName(self.GetMesh())
1710 def SetName(self, name):
1712 Set a name to the mesh
1715 name: a new name of the mesh
1718 self.smeshpyD.SetName(self.GetMesh(), name)
1720 def GetSubMesh(self, geom, name):
1722 Get a sub-mesh object associated to a *geom* geometrical object.
1725 geom: a geometrical object (shape)
1726 name: a name for the sub-mesh in the Object Browser
1729 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1730 which lies on the given shape
1733 A sub-mesh is implicitly created when a sub-shape is specified at
1734 creating an algorithm, for example::
1736 algo1D = mesh.Segment(geom=Edge_1)
1738 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1739 The created sub-mesh can be retrieved from the algorithm::
1741 submesh = algo1D.GetSubMesh()
1744 AssureGeomPublished( self, geom, name )
1745 submesh = self.mesh.GetSubMesh( geom, name )
1750 Return the shape associated to the mesh
1758 def SetShape(self, geom):
1760 Associate the given shape to the mesh (entails the recreation of the mesh)
1763 geom: the shape to be meshed (GEOM_Object)
1766 self.mesh = self.smeshpyD.CreateMesh(geom)
1768 def HasShapeToMesh(self):
1770 Return ``True`` if this mesh is based on geometry
1772 return self.mesh.HasShapeToMesh()
1776 Load mesh from the study after opening the study
1780 def IsReadyToCompute(self, theSubObject):
1782 Return true if the hypotheses are defined well
1785 theSubObject: a sub-shape of a mesh shape
1791 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1793 def GetAlgoState(self, theSubObject):
1795 Return errors of hypotheses definition.
1796 The list of errors is empty if everything is OK.
1799 theSubObject: a sub-shape of a mesh shape
1805 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1807 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1809 Return a geometrical object on which the given element was built.
1810 The returned geometrical object, if not nil, is either found in the
1811 study or published by this method with the given name
1814 theElementID: the id of the mesh element
1815 theGeomName: the user-defined name of the geometrical object
1818 GEOM.GEOM_Object instance
1821 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1823 def MeshDimension(self):
1825 Return the mesh dimension depending on the dimension of the underlying shape
1826 or, if the mesh is not based on any shape, basing on deimension of elements
1829 mesh dimension as an integer value [0,3]
1832 if self.mesh.HasShapeToMesh():
1833 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1834 if len( shells ) > 0 :
1836 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1838 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1843 if self.NbVolumes() > 0: return 3
1844 if self.NbFaces() > 0: return 2
1845 if self.NbEdges() > 0: return 1
1848 def Evaluate(self, geom=0):
1850 Evaluate size of prospective mesh on a shape
1853 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1854 To know predicted number of e.g. edges, inquire it this way::
1856 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1859 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1861 geom = self.mesh.GetShapeToMesh()
1864 return self.smeshpyD.Evaluate(self.mesh, geom)
1866 def ParallelCompute(self, nbThreads, mesherNbThreads=1, geom=0, discardModifs=False, refresh=False):
1868 Parallel computation of the mesh and return the status of the computation
1869 The mesh must contains have be constructed using create_parallel_mesh
1872 nbThreads: Number of threads to use for a parallel computation
1873 geom: geomtrical shape on which mesh data should be computed
1874 discardModifs: if True and the mesh has been edited since
1875 a last total re-compute and that may prevent successful partial re-compute,
1876 then the mesh is cleaned before Compute()
1877 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1882 if (nbThreads <= 1):
1883 raise ValueError("nbThreads must be strictly greater than 1")
1884 if (mesherNbThreads < 1):
1885 raise ValueError("nbThreads must be greater than 1")
1887 self.mesh.SetMesherNbThreads(mesherNbThreads)
1888 self.mesh.SetNbThreads(nbThreads)
1889 return self.Compute(geom=geom, discardModifs=discardModifs, refresh=refresh)
1891 def Compute(self, geom=0, discardModifs=False, refresh=False):
1893 Compute the mesh and return the status of the computation
1896 geom: geomtrical shape on which mesh data should be computed
1897 discardModifs: if True and the mesh has been edited since
1898 a last total re-compute and that may prevent successful partial re-compute,
1899 then the mesh is cleaned before Compute()
1900 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1906 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1907 geom = self.mesh.GetShapeToMesh()
1910 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1912 ok = self.smeshpyD.Compute(self.mesh, geom)
1913 except SALOME.SALOME_Exception as ex:
1914 print("Mesh computation failed, exception caught:")
1915 print(" ", ex.details.text)
1918 print("Mesh computation failed, exception caught:")
1919 traceback.print_exc()
1923 # Treat compute errors
1924 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1926 for err in computeErrors:
1927 if self.mesh.HasShapeToMesh():
1928 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1930 stdErrors = ["OK", #COMPERR_OK
1931 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1932 "std::exception", #COMPERR_STD_EXCEPTION
1933 "OCC exception", #COMPERR_OCC_EXCEPTION
1934 "..", #COMPERR_SLM_EXCEPTION
1935 "Unknown exception", #COMPERR_EXCEPTION
1936 "Memory allocation problem", #COMPERR_MEMORY_PB
1937 "Algorithm failed", #COMPERR_ALGO_FAILED
1938 "Unexpected geometry", #COMPERR_BAD_SHAPE
1939 "Warning", #COMPERR_WARNING
1940 "Computation cancelled",#COMPERR_CANCELED
1941 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1943 if err.code < len(stdErrors): errText = stdErrors[err.code]
1945 errText = "code %s" % -err.code
1946 if errText: errText += ". "
1947 errText += err.comment
1948 if allReasons: allReasons += "\n"
1950 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1952 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1956 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1958 if err.isGlobalAlgo:
1966 reason = '%s %sD algorithm is missing' % (glob, dim)
1967 elif err.state == HYP_MISSING:
1968 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1969 % (glob, dim, name, dim))
1970 elif err.state == HYP_NOTCONFORM:
1971 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1972 elif err.state == HYP_BAD_PARAMETER:
1973 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1974 % ( glob, dim, name ))
1975 elif err.state == HYP_BAD_GEOMETRY:
1976 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1977 'geometry' % ( glob, dim, name ))
1978 elif err.state == HYP_HIDDEN_ALGO:
1979 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1980 'algorithm of upper dimension generating %sD mesh'
1981 % ( glob, dim, name, glob, dim ))
1983 reason = ("For unknown reason. "
1984 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1986 if allReasons: allReasons += "\n"
1987 allReasons += "- " + reason
1989 if not ok or allReasons != "":
1990 msg = '"' + GetName(self.mesh) + '"'
1991 if ok: msg += " has been computed with warnings"
1992 else: msg += " has not been computed"
1993 if allReasons != "": msg += ":"
1999 if salome.sg.hasDesktop():
2000 if not isinstance( refresh, list): # not a call from subMesh.Compute()
2001 if refresh: salome.sg.updateObjBrowser()
2005 def GetComputeErrors(self, shape=0 ):
2007 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
2011 shape = self.mesh.GetShapeToMesh()
2012 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
2014 def GetSubShapeName(self, subShapeID ):
2016 Return a name of a sub-shape by its ID.
2017 Possible variants (for *subShapeID* == 3):
2019 - **"Face_12"** - published sub-shape
2020 - **FACE #3** - not published sub-shape
2021 - **sub-shape #3** - invalid sub-shape ID
2022 - **#3** - error in this function
2025 subShapeID: a unique ID of a sub-shape
2028 a string describing the sub-shape
2032 if not self.mesh.HasShapeToMesh():
2036 mainIOR = salome.orb.object_to_string( self.GetShape() )
2038 mainSO = s.FindObjectIOR(mainIOR)
2041 shapeText = '"%s"' % mainSO.GetName()
2042 subIt = s.NewChildIterator(mainSO)
2044 subSO = subIt.Value()
2046 obj = subSO.GetObject()
2047 if not obj: continue
2048 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2051 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2054 if ids == subShapeID:
2055 shapeText = '"%s"' % subSO.GetName()
2058 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2060 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2062 shapeText = 'sub-shape #%s' % (subShapeID)
2064 shapeText = "#%s" % (subShapeID)
2067 def GetFailedShapes(self, publish=False):
2069 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2070 error of an algorithm
2073 publish: if *True*, the returned groups will be published in the study
2076 a list of GEOM groups each named after a failed algorithm
2081 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2082 for err in computeErrors:
2083 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2084 if not shape: continue
2085 if err.algoName in algo2shapes:
2086 algo2shapes[ err.algoName ].append( shape )
2088 algo2shapes[ err.algoName ] = [ shape ]
2092 for algoName, shapes in list(algo2shapes.items()):
2094 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2095 otherTypeShapes = []
2097 group = self.geompyD.CreateGroup( self.geom, groupType )
2098 for shape in shapes:
2099 if shape.GetShapeType() == shapes[0].GetShapeType():
2100 sameTypeShapes.append( shape )
2102 otherTypeShapes.append( shape )
2103 self.geompyD.UnionList( group, sameTypeShapes )
2105 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2107 group.SetName( algoName )
2108 groups.append( group )
2109 shapes = otherTypeShapes
2112 for group in groups:
2113 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2116 def GetMeshOrder(self):
2118 Return sub-mesh objects list in meshing order
2121 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2124 return self.mesh.GetMeshOrder()
2126 def SetMeshOrder(self, submeshes):
2128 Set priority of sub-meshes. It works in two ways:
2130 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2131 *several dimensions*, it sets the order in which the sub-meshes are computed.
2132 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2133 when looking for meshing parameters to apply to a sub-shape. To impose the
2134 order in which sub-meshes with uni-dimensional algorithms are computed,
2135 call **submesh.Compute()** in a desired order.
2138 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2140 Warning: the method is for setting the order for all sub-meshes at once:
2141 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2144 return self.mesh.SetMeshOrder(submeshes)
2146 def Clear(self, refresh=False):
2148 Remove all nodes and elements generated on geometry. Imported elements remain.
2151 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2155 if ( salome.sg.hasDesktop() ):
2156 if refresh: salome.sg.updateObjBrowser()
2158 def ClearSubMesh(self, geomId, refresh=False):
2160 Remove all nodes and elements of indicated shape
2163 geomId: the ID of a sub-shape to remove elements on
2164 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2167 self.mesh.ClearSubMesh(geomId)
2168 if salome.sg.hasDesktop():
2169 if refresh: salome.sg.updateObjBrowser()
2171 def AutomaticTetrahedralization(self, fineness=0):
2173 Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron
2176 fineness: [0.0,1.0] defines mesh fineness
2182 dim = self.MeshDimension()
2184 self.RemoveGlobalHypotheses()
2185 self.Segment().AutomaticLength(fineness)
2187 self.Triangle().LengthFromEdges()
2192 return self.Compute()
2194 def AutomaticHexahedralization(self, fineness=0):
2196 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2199 fineness: [0.0, 1.0] defines mesh fineness
2205 dim = self.MeshDimension()
2206 # assign the hypotheses
2207 self.RemoveGlobalHypotheses()
2208 self.Segment().AutomaticLength(fineness)
2215 return self.Compute()
2217 def AddHypothesis(self, hyp, geom=0):
2222 hyp: a hypothesis to assign
2223 geom: a subhape of mesh geometry
2226 :class:`SMESH.Hypothesis_Status`
2229 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2230 hyp, geom = geom, hyp
2231 if isinstance( hyp, Mesh_Algorithm ):
2232 hyp = hyp.GetAlgorithm()
2237 geom = self.mesh.GetShapeToMesh()
2240 if self.mesh.HasShapeToMesh():
2241 hyp_type = hyp.GetName()
2242 lib_name = hyp.GetLibName()
2243 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2244 # if checkAll and geom:
2245 # checkAll = geom.GetType() == 37
2247 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2249 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2250 status = self.mesh.AddHypothesis(geom, hyp)
2252 status = HYP_BAD_GEOMETRY, ""
2253 hyp_name = GetName( hyp )
2256 geom_name = geom.GetName()
2257 isAlgo = hyp._narrow( SMESH_Algo )
2258 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2261 def IsUsedHypothesis(self, hyp, geom):
2263 Return True if an algorithm or hypothesis is assigned to a given shape
2266 hyp: an algorithm or hypothesis to check
2267 geom: a subhape of mesh geometry
2273 if not hyp: # or not geom
2275 if isinstance( hyp, Mesh_Algorithm ):
2276 hyp = hyp.GetAlgorithm()
2278 hyps = self.GetHypothesisList(geom)
2280 if h.GetId() == hyp.GetId():
2284 def RemoveHypothesis(self, hyp, geom=0):
2286 Unassign a hypothesis
2289 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2290 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2293 :class:`SMESH.Hypothesis_Status`
2298 if isinstance( hyp, Mesh_Algorithm ):
2299 hyp = hyp.GetAlgorithm()
2305 if self.IsUsedHypothesis( hyp, shape ):
2306 return self.mesh.RemoveHypothesis( shape, hyp )
2307 hypName = GetName( hyp )
2308 geoName = GetName( shape )
2309 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2312 def GetHypothesisList(self, geom):
2314 Get the list of hypotheses added on a geometry
2317 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2320 the sequence of :class:`SMESH.SMESH_Hypothesis`
2323 return self.mesh.GetHypothesisList( geom )
2325 def RemoveGlobalHypotheses(self):
2327 Remove all global hypotheses
2330 current_hyps = self.mesh.GetHypothesisList( self.geom )
2331 for hyp in current_hyps:
2332 self.mesh.RemoveHypothesis( self.geom, hyp )
2336 def ExportMEDCoupling(self, *args, **kwargs):
2338 Export the mesh in a memory representation.
2341 auto_groups (boolean): parameter for creating/not creating
2342 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2343 the typical use is auto_groups=False.
2344 overwrite (boolean): parameter for overwriting/not overwriting the file
2345 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2346 to export instead of the mesh
2347 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2349 - 1D if all mesh nodes lie on OX coordinate axis, or
2350 - 2D if all mesh nodes lie on XOY coordinate plane, or
2351 - 3D in the rest cases.
2353 If *autoDimension* is *False*, the space dimension is always 3.
2354 fields: list of GEOM fields defined on the shape to mesh.
2355 geomAssocFields: each character of this string means a need to export a
2356 corresponding field; correspondence between fields and characters
2359 - 'v' stands for "_vertices_" field;
2360 - 'e' stands for "_edges_" field;
2361 - 'f' stands for "_faces_" field;
2362 - 's' stands for "_solids_" field.
2364 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2365 close to zero within a given tolerance, the coordinate is set to zero.
2366 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2367 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2369 auto_groups = args[0] if len(args) > 0 else False
2370 meshPart = args[1] if len(args) > 1 else None
2371 autoDimension = args[2] if len(args) > 2 else True
2372 fields = args[3] if len(args) > 3 else []
2373 geomAssocFields = args[4] if len(args) > 4 else ''
2374 z_tolerance = args[5] if len(args) > 5 else -1.
2375 saveNumbers = args[6] if len(args) > 6 else True
2376 # process keywords arguments
2377 auto_groups = kwargs.get("auto_groups", auto_groups)
2378 meshPart = kwargs.get("meshPart", meshPart)
2379 autoDimension = kwargs.get("autoDimension", autoDimension)
2380 fields = kwargs.get("fields", fields)
2381 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2382 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2383 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2385 # invoke engine's function
2386 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2387 unRegister = genObjUnRegister()
2388 if isinstance( meshPart, list ):
2389 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2390 unRegister.set( meshPart )
2392 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2393 self.mesh.SetParameters(Parameters)
2395 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2396 fields, geomAssocFields, z_tolerance,
2399 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2400 return medcoupling.MEDFileData.New(dab)
2402 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2404 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2405 return medcoupling.MEDFileMesh.New(dab)
2407 def ExportMED(self, *args, **kwargs):
2409 Export the mesh in a file in MED format
2410 allowing to overwrite the file if it exists or add the exported data to its contents
2413 fileName: is the file name
2414 auto_groups (boolean): parameter for creating/not creating
2415 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2416 the typical use is auto_groups=False.
2417 version (int): define the version (xy, where version is x.y.z) of MED file format.
2418 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2419 The rules of compatibility to write a mesh in an older version than
2420 the current version depend on the current version. For instance,
2421 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2422 or 3.2.1 or 3.3.1 formats.
2423 If the version is equal to -1, the version is not changed (default).
2424 overwrite (boolean): parameter for overwriting/not overwriting the file
2425 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2426 to export instead of the mesh
2427 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2429 - 1D if all mesh nodes lie on OX coordinate axis, or
2430 - 2D if all mesh nodes lie on XOY coordinate plane, or
2431 - 3D in the rest cases.
2433 If *autoDimension* is *False*, the space dimension is always 3.
2434 fields: list of GEOM fields defined on the shape to mesh.
2435 geomAssocFields: each character of this string means a need to export a
2436 corresponding field; correspondence between fields and characters
2439 - 'v' stands for "_vertices_" field;
2440 - 'e' stands for "_edges_" field;
2441 - 'f' stands for "_faces_" field;
2442 - 's' stands for "_solids_" field.
2444 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2445 close to zero within a given tolerance, the coordinate is set to zero.
2446 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2447 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2449 # process positional arguments
2450 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2452 auto_groups = args[1] if len(args) > 1 else False
2453 version = args[2] if len(args) > 2 else -1
2454 overwrite = args[3] if len(args) > 3 else True
2455 meshPart = args[4] if len(args) > 4 else None
2456 autoDimension = args[5] if len(args) > 5 else True
2457 fields = args[6] if len(args) > 6 else []
2458 geomAssocFields = args[7] if len(args) > 7 else ''
2459 z_tolerance = args[8] if len(args) > 8 else -1.
2460 saveNumbers = args[9] if len(args) > 9 else True
2461 # process keywords arguments
2462 auto_groups = kwargs.get("auto_groups", auto_groups)
2463 version = kwargs.get("version", version)
2464 version = kwargs.get("minor", version)
2465 overwrite = kwargs.get("overwrite", overwrite)
2466 meshPart = kwargs.get("meshPart", meshPart)
2467 autoDimension = kwargs.get("autoDimension", autoDimension)
2468 fields = kwargs.get("fields", fields)
2469 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2470 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2471 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2473 if isinstance( meshPart, Mesh):
2474 meshPart = meshPart.GetMesh()
2476 # invoke engine's function
2477 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2478 unRegister = genObjUnRegister()
2479 if isinstance( meshPart, list ):
2480 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2481 unRegister.set( meshPart )
2483 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2484 self.mesh.SetParameters(Parameters)
2486 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2487 version, overwrite, autoDimension,
2488 fields, geomAssocFields, z_tolerance, saveNumbers )
2490 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2492 def ExportDAT(self, f, meshPart=None, renumber=True):
2494 Export the mesh in a file in DAT format
2498 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2499 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2502 if meshPart or not renumber:
2503 unRegister = genObjUnRegister()
2504 if isinstance( meshPart, list ):
2505 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2506 unRegister.set( meshPart )
2507 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2509 self.mesh.ExportDAT( f, renumber )
2511 def ExportUNV(self, f, meshPart=None, renumber=True):
2513 Export the mesh in a file in UNV format
2517 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2518 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2521 if meshPart or not renumber:
2522 unRegister = genObjUnRegister()
2523 if isinstance( meshPart, list ):
2524 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2525 unRegister.set( meshPart )
2526 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2528 self.mesh.ExportUNV( f, renumber )
2530 def ExportSTL(self, f, ascii=1, meshPart=None):
2532 Export the mesh in a file in STL format
2536 ascii: defines the file encoding
2537 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2541 unRegister = genObjUnRegister()
2542 if isinstance( meshPart, list ):
2543 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2544 unRegister.set( meshPart )
2545 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2547 self.mesh.ExportSTL(f, ascii)
2549 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2551 Export the mesh in a file in CGNS format
2555 overwrite: boolean parameter for overwriting/not overwriting the file
2556 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2557 groupElemsByType: if True all elements of same entity type are exported at ones,
2558 else elements are exported in order of their IDs which can cause creation
2559 of multiple cgns sections
2562 unRegister = genObjUnRegister()
2563 if isinstance( meshPart, list ):
2564 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2565 unRegister.set( meshPart )
2566 if isinstance( meshPart, Mesh ):
2567 meshPart = meshPart.mesh
2569 meshPart = self.mesh
2570 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2572 def ExportGMF(self, f, meshPart=None):
2574 Export the mesh in a file in GMF format.
2575 GMF files must have .mesh extension for the ASCII format and .meshb for
2576 the bynary format. Other extensions are not allowed.
2580 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2583 unRegister = genObjUnRegister()
2584 if isinstance( meshPart, list ):
2585 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2586 unRegister.set( meshPart )
2587 if isinstance( meshPart, Mesh ):
2588 meshPart = meshPart.mesh
2590 meshPart = self.mesh
2591 self.mesh.ExportGMF(meshPart, f, True)
2593 def ExportToMED(self, *args, **kwargs):
2595 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2596 Export the mesh in a file in MED format
2597 allowing to overwrite the file if it exists or add the exported data to its contents
2600 fileName: the file name
2601 opt (boolean): parameter for creating/not creating
2602 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2603 overwrite: boolean parameter for overwriting/not overwriting the file
2604 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2606 - 1D if all mesh nodes lie on OX coordinate axis, or
2607 - 2D if all mesh nodes lie on XOY coordinate plane, or
2608 - 3D in the rest cases.
2610 If **autoDimension** is *False*, the space dimension is always 3.
2613 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2614 # process positional arguments
2615 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2617 auto_groups = args[1] if len(args) > 1 else False
2618 overwrite = args[2] if len(args) > 2 else True
2619 autoDimension = args[3] if len(args) > 3 else True
2620 # process keywords arguments
2621 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2622 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2623 overwrite = kwargs.get("overwrite", overwrite)
2624 autoDimension = kwargs.get("autoDimension", autoDimension)
2626 # invoke engine's function
2627 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2629 def ExportToMEDX(self, *args, **kwargs):
2631 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2632 Export the mesh in a file in MED format
2635 fileName: the file name
2636 opt (boolean): parameter for creating/not creating
2637 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2638 overwrite: boolean parameter for overwriting/not overwriting the file
2639 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2641 - 1D if all mesh nodes lie on OX coordinate axis, or
2642 - 2D if all mesh nodes lie on XOY coordinate plane, or
2643 - 3D in the rest cases.
2645 If **autoDimension** is *False*, the space dimension is always 3.
2648 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2649 # process positional arguments
2650 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2652 auto_groups = args[1] if len(args) > 1 else False
2653 overwrite = args[2] if len(args) > 2 else True
2654 autoDimension = args[3] if len(args) > 3 else True
2655 # process keywords arguments
2656 auto_groups = kwargs.get("auto_groups", auto_groups)
2657 overwrite = kwargs.get("overwrite", overwrite)
2658 autoDimension = kwargs.get("autoDimension", autoDimension)
2660 # invoke engine's function
2661 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2665 def Append(self, meshes, uniteIdenticalGroups = True,
2666 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2668 Append given meshes into this mesh.
2669 All groups of input meshes will be created in this mesh.
2672 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2673 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2674 mergeNodesAndElements: if True, equal nodes and elements are merged
2675 mergeTolerance: tolerance for merging nodes
2676 allGroups: forces creation of groups corresponding to every input mesh
2678 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2679 mergeNodesAndElements, mergeTolerance, allGroups,
2680 meshToAppendTo = self.GetMesh() )
2682 # Operations with groups:
2683 # ----------------------
2684 def CreateEmptyGroup(self, elementType, name):
2686 Create an empty standalone mesh group
2689 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2690 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2691 name: the name of the mesh group
2694 :class:`SMESH.SMESH_Group`
2697 return self.mesh.CreateGroup(elementType, name)
2699 def Group(self, grp, name=""):
2701 Create a mesh group based on the geometric object *grp*
2702 and give it a *name*.
2703 If *name* is not defined the name of the geometric group is used
2706 Works like :meth:`GroupOnGeom`.
2709 grp: a geometric group, a vertex, an edge, a face or a solid
2710 name: the name of the mesh group
2713 :class:`SMESH.SMESH_GroupOnGeom`
2716 return self.GroupOnGeom(grp, name)
2718 def GroupOnGeom(self, grp, name="", typ=None):
2720 Create a mesh group based on the geometrical object *grp*
2721 and give it a *name*.
2722 if *name* is not defined the name of the geometric group is used
2725 grp: a geometrical group, a vertex, an edge, a face or a solid
2726 name: the name of the mesh group
2727 typ: the type of elements in the group; either of
2728 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2729 automatically detected by the type of the geometry
2732 :class:`SMESH.SMESH_GroupOnGeom`
2735 AssureGeomPublished( self, grp, name )
2737 name = grp.GetName()
2739 typ = self._groupTypeFromShape( grp )
2740 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2742 def _groupTypeFromShape( self, shape ):
2744 Pivate method to get a type of group on geometry
2746 tgeo = str(shape.GetShapeType())
2747 if tgeo == "VERTEX":
2749 elif tgeo == "EDGE" or tgeo == "WIRE":
2751 elif tgeo == "FACE" or tgeo == "SHELL":
2753 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2755 elif tgeo == "COMPOUND":
2757 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2759 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2760 # simplification of access in geomBuilder: omniORB.registerObjref
2761 from SHAPERSTUDY_utils import getEngine
2764 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2766 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2767 return self._groupTypeFromShape( sub[0] )
2769 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2772 def GroupOnFilter(self, typ, name, filter):
2774 Create a mesh group with given *name* based on the *filter*.
2775 It is a special type of group dynamically updating it's contents during
2779 typ: the type of elements in the group; either of
2780 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2781 name: the name of the mesh group
2782 filter (SMESH.Filter): the filter defining group contents
2785 :class:`SMESH.SMESH_GroupOnFilter`
2788 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2790 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2792 Create a mesh group by the given ids of elements
2795 groupName: the name of the mesh group
2796 elementType: the type of elements in the group; either of
2797 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2798 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2801 :class:`SMESH.SMESH_Group`
2804 group = self.mesh.CreateGroup(elementType, groupName)
2805 if isinstance( elemIDs, Mesh ):
2806 elemIDs = elemIDs.GetMesh()
2807 if hasattr( elemIDs, "GetIDs" ):
2808 if hasattr( elemIDs, "SetMesh" ):
2809 elemIDs.SetMesh( self.GetMesh() )
2810 group.AddFrom( elemIDs )
2818 CritType=FT_Undefined,
2821 UnaryOp=FT_Undefined,
2824 Create a mesh group by the given conditions
2827 groupName: the name of the mesh group
2828 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2829 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2830 Note that the items starting from FT_LessThan are not suitable for CritType.
2831 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2832 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2833 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2834 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2835 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2838 :class:`SMESH.SMESH_GroupOnFilter`
2841 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2842 group = self.MakeGroupByCriterion(groupName, aCriterion)
2845 def MakeGroupByCriterion(self, groupName, Criterion):
2847 Create a mesh group by the given criterion
2850 groupName: the name of the mesh group
2851 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2854 :class:`SMESH.SMESH_GroupOnFilter`
2857 :meth:`smeshBuilder.GetCriterion`
2860 return self.MakeGroupByCriteria( groupName, [Criterion] )
2862 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2864 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2867 groupName: the name of the mesh group
2868 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2869 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2872 :class:`SMESH.SMESH_GroupOnFilter`
2875 :meth:`smeshBuilder.GetCriterion`
2878 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2879 group = self.MakeGroupByFilter(groupName, aFilter)
2882 def MakeGroupByFilter(self, groupName, theFilter):
2884 Create a mesh group by the given filter
2887 groupName (string): the name of the mesh group
2888 theFilter (SMESH.Filter): the filter
2891 :class:`SMESH.SMESH_GroupOnFilter`
2894 :meth:`smeshBuilder.GetFilter`
2897 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2898 #theFilter.SetMesh( self.mesh )
2899 #group.AddFrom( theFilter )
2900 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2903 def RemoveGroup(self, group):
2908 group (SMESH.SMESH_GroupBase): group to remove
2911 self.mesh.RemoveGroup(group)
2913 def RemoveGroupWithContents(self, group):
2915 Remove a group with its contents
2918 group (SMESH.SMESH_GroupBase): group to remove
2921 This operation can create gaps in numeration of nodes or elements.
2922 Call :meth:`RenumberElements` to remove the gaps.
2925 self.mesh.RemoveGroupWithContents(group)
2927 def GetGroups(self, elemType = SMESH.ALL):
2929 Get the list of groups existing in the mesh in the order of creation
2930 (starting from the oldest one)
2933 elemType (SMESH.ElementType): type of elements the groups contain;
2934 by default groups of elements of all types are returned
2937 a list of :class:`SMESH.SMESH_GroupBase`
2940 groups = self.mesh.GetGroups()
2941 if elemType == SMESH.ALL:
2945 if g.GetType() == elemType:
2946 typedGroups.append( g )
2953 Get the number of groups existing in the mesh
2956 the quantity of groups as an integer value
2959 return self.mesh.NbGroups()
2961 def GetGroupNames(self):
2963 Get the list of names of groups existing in the mesh
2969 groups = self.GetGroups()
2971 for group in groups:
2972 names.append(group.GetName())
2975 def GetGroupByName(self, name, elemType = None):
2977 Find groups by name and type
2980 name (string): name of the group of interest
2981 elemType (SMESH.ElementType): type of elements the groups contain;
2982 by default one group of any type is returned;
2983 if elemType == SMESH.ALL then all groups of any type are returned
2986 a list of :class:`SMESH.SMESH_GroupBase`
2990 for group in self.GetGroups():
2991 if group.GetName() == name:
2992 if elemType is None:
2994 if ( elemType == SMESH.ALL or
2995 group.GetType() == elemType ):
2996 groups.append( group )
2999 def UnionGroups(self, group1, group2, name):
3001 Produce a union of two groups.
3002 A new group is created. All mesh elements that are
3003 present in the initial groups are added to the new one
3006 group1 (SMESH.SMESH_GroupBase): a group
3007 group2 (SMESH.SMESH_GroupBase): another group
3010 instance of :class:`SMESH.SMESH_Group`
3013 return self.mesh.UnionGroups(group1, group2, name)
3015 def UnionListOfGroups(self, groups, name):
3017 Produce a union list of groups.
3018 New group is created. All mesh elements that are present in
3019 initial groups are added to the new one
3022 groups: list of :class:`SMESH.SMESH_GroupBase`
3025 instance of :class:`SMESH.SMESH_Group`
3027 return self.mesh.UnionListOfGroups(groups, name)
3029 def IntersectGroups(self, group1, group2, name):
3031 Prodice an intersection of two groups.
3032 A new group is created. All mesh elements that are common
3033 for the two initial groups are added to the new one.
3036 group1 (SMESH.SMESH_GroupBase): a group
3037 group2 (SMESH.SMESH_GroupBase): another group
3040 instance of :class:`SMESH.SMESH_Group`
3043 return self.mesh.IntersectGroups(group1, group2, name)
3045 def IntersectListOfGroups(self, groups, name):
3047 Produce an intersection of groups.
3048 New group is created. All mesh elements that are present in all
3049 initial groups simultaneously are added to the new one
3052 groups: a list of :class:`SMESH.SMESH_GroupBase`
3055 instance of :class:`SMESH.SMESH_Group`
3057 return self.mesh.IntersectListOfGroups(groups, name)
3059 def CutGroups(self, main_group, tool_group, name):
3061 Produce a cut of two groups.
3062 A new group is created. All mesh elements that are present in
3063 the main group but are not present in the tool group are added to the new one
3066 main_group (SMESH.SMESH_GroupBase): a group to cut from
3067 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3070 an instance of :class:`SMESH.SMESH_Group`
3073 return self.mesh.CutGroups(main_group, tool_group, name)
3075 def CutListOfGroups(self, main_groups, tool_groups, name):
3077 Produce a cut of groups.
3078 A new group is created. All mesh elements that are present in main groups
3079 but do not present in tool groups are added to the new one
3082 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3083 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3086 an instance of :class:`SMESH.SMESH_Group`
3089 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3091 def CreateDimGroup(self, groups, elemType, name,
3092 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3094 Create a standalone group of entities basing on nodes of other groups.
3097 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3098 elemType: a type of elements to include to the new group; either of
3099 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3100 name: a name of the new group.
3101 nbCommonNodes: a criterion of inclusion of an element to the new group
3102 basing on number of element nodes common with reference *groups*.
3103 Meaning of possible values are:
3105 - SMESH.ALL_NODES - include if all nodes are common,
3106 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3107 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3108 - SMEHS.MAJORITY - include if half of nodes or more are common.
3109 underlyingOnly: if *True* (default), an element is included to the
3110 new group provided that it is based on nodes of an element of *groups*;
3111 in this case the reference *groups* are supposed to be of higher dimension
3112 than *elemType*, which can be useful for example to get all faces lying on
3113 volumes of the reference *groups*.
3116 an instance of :class:`SMESH.SMESH_Group`
3119 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3121 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3123 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3125 Distribute all faces of the mesh among groups using sharp edges and optionally
3126 existing 1D elements as group boundaries.
3129 sharpAngle: edge is considered sharp if an angle between normals of
3130 adjacent faces is more than \a sharpAngle in degrees.
3131 createEdges (boolean): to create 1D elements for detected sharp edges.
3132 useExistingEdges (boolean): to use existing edges as group boundaries
3134 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3136 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3137 self.mesh.SetParameters(Parameters)
3138 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3140 def ConvertToStandalone(self, group):
3142 Convert group on geom into standalone group
3145 return self.mesh.ConvertToStandalone(group)
3147 # Get some info about mesh:
3148 # ------------------------
3150 def GetLog(self, clearAfterGet):
3152 Return the log of nodes and elements added or removed
3153 since the previous clear of the log.
3156 clearAfterGet: log is emptied after Get (safe if concurrents access)
3159 list of SMESH.log_block structures { commandType, number, coords, indexes }
3162 return self.mesh.GetLog(clearAfterGet)
3166 Clear the log of nodes and elements added or removed since the previous
3167 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3170 self.mesh.ClearLog()
3172 def SetAutoColor(self, theAutoColor):
3174 Toggle auto color mode on the object.
3175 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3178 theAutoColor (boolean): the flag which toggles auto color mode.
3181 self.mesh.SetAutoColor(theAutoColor)
3183 def GetAutoColor(self):
3185 Get flag of object auto color mode.
3191 return self.mesh.GetAutoColor()
3198 integer value, which is the internal Id of the mesh
3201 return self.mesh.GetId()
3203 def HasDuplicatedGroupNamesMED(self):
3205 Check the group names for duplications.
3206 Consider the maximum group name length stored in MED file.
3212 return self.mesh.HasDuplicatedGroupNamesMED()
3214 def GetMeshEditor(self):
3216 Obtain the mesh editor tool
3219 an instance of :class:`SMESH.SMESH_MeshEditor`
3224 def GetIDSource(self, ids, elemType = SMESH.ALL):
3226 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3227 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3231 elemType: type of elements; this parameter is used to distinguish
3232 IDs of nodes from IDs of elements; by default ids are treated as
3233 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3236 an instance of :class:`SMESH.SMESH_IDSource`
3239 call UnRegister() for the returned object as soon as it is no more useful::
3241 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3242 mesh.DoSomething( idSrc )
3246 if isinstance( ids, int ):
3248 return self.editor.MakeIDSource(ids, elemType)
3251 # Get information about mesh contents:
3252 # ------------------------------------
3254 def GetMeshInfo(self, obj = None):
3256 Get the mesh statistic.
3259 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3262 if not obj: obj = self.mesh
3263 return self.smeshpyD.GetMeshInfo(obj)
3267 Return the number of nodes in the mesh
3273 return self.mesh.NbNodes()
3275 def NbElements(self):
3277 Return the number of elements in the mesh
3283 return self.mesh.NbElements()
3285 def Nb0DElements(self):
3287 Return the number of 0d elements in the mesh
3293 return self.mesh.Nb0DElements()
3297 Return the number of ball discrete elements in the mesh
3303 return self.mesh.NbBalls()
3307 Return the number of edges in the mesh
3313 return self.mesh.NbEdges()
3315 def NbEdgesOfOrder(self, elementOrder):
3317 Return the number of edges with the given order in the mesh
3320 elementOrder: the order of elements
3321 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3327 return self.mesh.NbEdgesOfOrder(elementOrder)
3331 Return the number of faces in the mesh
3337 return self.mesh.NbFaces()
3339 def NbFacesOfOrder(self, elementOrder):
3341 Return the number of faces with the given order in the mesh
3344 elementOrder: the order of elements
3345 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3351 return self.mesh.NbFacesOfOrder(elementOrder)
3353 def NbTriangles(self):
3355 Return the number of triangles in the mesh
3361 return self.mesh.NbTriangles()
3363 def NbTrianglesOfOrder(self, elementOrder):
3365 Return the number of triangles with the given order in the mesh
3368 elementOrder: is the order of elements
3369 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3375 return self.mesh.NbTrianglesOfOrder(elementOrder)
3377 def NbBiQuadTriangles(self):
3379 Return the number of biquadratic triangles in the mesh
3385 return self.mesh.NbBiQuadTriangles()
3387 def NbQuadrangles(self):
3389 Return the number of quadrangles in the mesh
3395 return self.mesh.NbQuadrangles()
3397 def NbQuadranglesOfOrder(self, elementOrder):
3399 Return the number of quadrangles with the given order in the mesh
3402 elementOrder: the order of elements
3403 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3409 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3411 def NbBiQuadQuadrangles(self):
3413 Return the number of biquadratic quadrangles in the mesh
3419 return self.mesh.NbBiQuadQuadrangles()
3421 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3423 Return the number of polygons of given order in the mesh
3426 elementOrder: the order of elements
3427 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3433 return self.mesh.NbPolygonsOfOrder(elementOrder)
3435 def NbVolumes(self):
3437 Return the number of volumes in the mesh
3443 return self.mesh.NbVolumes()
3446 def NbVolumesOfOrder(self, elementOrder):
3448 Return the number of volumes with the given order in the mesh
3451 elementOrder: the order of elements
3452 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3458 return self.mesh.NbVolumesOfOrder(elementOrder)
3462 Return the number of tetrahedrons in the mesh
3468 return self.mesh.NbTetras()
3470 def NbTetrasOfOrder(self, elementOrder):
3472 Return the number of tetrahedrons with the given order in the mesh
3475 elementOrder: the order of elements
3476 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3482 return self.mesh.NbTetrasOfOrder(elementOrder)
3486 Return the number of hexahedrons in the mesh
3492 return self.mesh.NbHexas()
3494 def NbHexasOfOrder(self, elementOrder):
3496 Return the number of hexahedrons with the given order in the mesh
3499 elementOrder: the order of elements
3500 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3506 return self.mesh.NbHexasOfOrder(elementOrder)
3508 def NbTriQuadraticHexas(self):
3510 Return the number of triquadratic hexahedrons in the mesh
3516 return self.mesh.NbTriQuadraticHexas()
3518 def NbPyramids(self):
3520 Return the number of pyramids in the mesh
3526 return self.mesh.NbPyramids()
3528 def NbPyramidsOfOrder(self, elementOrder):
3530 Return the number of pyramids with the given order in the mesh
3533 elementOrder: the order of elements
3534 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3540 return self.mesh.NbPyramidsOfOrder(elementOrder)
3544 Return the number of prisms in the mesh
3550 return self.mesh.NbPrisms()
3552 def NbPrismsOfOrder(self, elementOrder):
3554 Return the number of prisms with the given order in the mesh
3557 elementOrder: the order of elements
3558 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3564 return self.mesh.NbPrismsOfOrder(elementOrder)
3566 def NbHexagonalPrisms(self):
3568 Return the number of hexagonal prisms in the mesh
3574 return self.mesh.NbHexagonalPrisms()
3576 def NbPolyhedrons(self):
3578 Return the number of polyhedrons in the mesh
3584 return self.mesh.NbPolyhedrons()
3586 def NbSubMesh(self):
3588 Return the number of submeshes in the mesh
3594 return self.mesh.NbSubMesh()
3596 def GetElementsId(self):
3598 Return the list of all mesh elements IDs
3601 the list of integer values
3604 :meth:`GetElementsByType`
3607 return self.mesh.GetElementsId()
3609 def GetElementsByType(self, elementType):
3611 Return the list of IDs of mesh elements with the given type
3614 elementType (SMESH.ElementType): the required type of elements
3617 list of integer values
3620 return self.mesh.GetElementsByType(elementType)
3622 def GetNodesId(self):
3624 Return the list of mesh nodes IDs
3627 the list of integer values
3630 return self.mesh.GetNodesId()
3632 # Get the information about mesh elements:
3633 # ------------------------------------
3635 def GetElementType(self, id, iselem=True):
3637 Return the type of mesh element or node
3640 the value from :class:`SMESH.ElementType` enumeration.
3641 Return SMESH.ALL if element or node with the given ID does not exist
3644 return self.mesh.GetElementType(id, iselem)
3646 def GetElementGeomType(self, id):
3648 Return the geometric type of mesh element
3651 the value from :class:`SMESH.EntityType` enumeration.
3654 return self.mesh.GetElementGeomType(id)
3656 def GetElementShape(self, id):
3658 Return the shape type of mesh element
3661 the value from :class:`SMESH.GeometryType` enumeration.
3664 return self.mesh.GetElementShape(id)
3666 def GetSubMeshElementsId(self, Shape):
3668 Return the list of sub-mesh elements IDs
3671 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3672 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3675 list of integer values
3678 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3679 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3682 return self.mesh.GetSubMeshElementsId(ShapeID)
3684 def GetSubMeshNodesId(self, Shape, all):
3686 Return the list of sub-mesh nodes IDs
3689 Shape: a geom object (sub-shape).
3690 *Shape* must be the sub-shape of a :meth:`GetShape`
3691 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3694 list of integer values
3697 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3698 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3701 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3703 def GetSubMeshElementType(self, Shape):
3705 Return type of elements on given shape
3708 Shape: a geom object (sub-shape).
3709 *Shape* must be a sub-shape of a ShapeToMesh()
3712 :class:`SMESH.ElementType`
3715 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3716 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3719 return self.mesh.GetSubMeshElementType(ShapeID)
3723 Get the mesh description
3729 return self.mesh.Dump()
3732 # Get the information about nodes and elements of a mesh by its IDs:
3733 # -----------------------------------------------------------
3735 def GetNodeXYZ(self, id):
3737 Get XYZ coordinates of a node.
3738 If there is no node for the given ID - return an empty list
3741 list of float values
3744 return self.mesh.GetNodeXYZ(id)
3746 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3748 Return list of IDs of inverse elements for the given node.
3749 If there is no node for the given ID - return an empty list
3753 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3756 list of integer values
3759 return self.mesh.GetNodeInverseElements(id,elemType)
3761 def GetNodePosition(self,NodeID):
3763 Return the position of a node on the shape
3766 :class:`SMESH.NodePosition`
3769 return self.mesh.GetNodePosition(NodeID)
3771 def GetElementPosition(self,ElemID):
3773 Return the position of an element on the shape
3776 :class:`SMESH.ElementPosition`
3779 return self.mesh.GetElementPosition(ElemID)
3781 def GetShapeID(self, id):
3783 Return the ID of the shape, on which the given node was generated.
3786 an integer value > 0 or -1 if there is no node for the given
3787 ID or the node is not assigned to any geometry
3790 return self.mesh.GetShapeID(id)
3792 def GetShapeIDForElem(self,id):
3794 Return the ID of the shape, on which the given element was generated.
3797 an integer value > 0 or -1 if there is no element for the given
3798 ID or the element is not assigned to any geometry
3801 return self.mesh.GetShapeIDForElem(id)
3803 def GetElemNbNodes(self, id):
3805 Return the number of nodes of the given element
3808 an integer value > 0 or -1 if there is no element for the given ID
3811 return self.mesh.GetElemNbNodes(id)
3813 def GetElemNode(self, id, index):
3815 Return the node ID the given (zero based) index for the given element.
3817 * If there is no element for the given ID - return -1.
3818 * If there is no node for the given index - return -2.
3821 id (int): element ID
3822 index (int): node index within the element
3825 an integer value (ID)
3828 :meth:`GetElemNodes`
3831 return self.mesh.GetElemNode(id, index)
3833 def GetElemNodes(self, id):
3835 Return the IDs of nodes of the given element
3838 a list of integer values
3841 return self.mesh.GetElemNodes(id)
3843 def IsMediumNode(self, elementID, nodeID):
3845 Return true if the given node is the medium node in the given quadratic element
3848 return self.mesh.IsMediumNode(elementID, nodeID)
3850 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3852 Return true if the given node is the medium node in one of quadratic elements
3855 nodeID: ID of the node
3856 elementType: the type of elements to check a state of the node, either of
3857 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3860 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3862 def ElemNbEdges(self, id):
3864 Return the number of edges for the given element
3867 return self.mesh.ElemNbEdges(id)
3869 def ElemNbFaces(self, id):
3871 Return the number of faces for the given element
3874 return self.mesh.ElemNbFaces(id)
3876 def GetElemFaceNodes(self,elemId, faceIndex):
3878 Return nodes of given face (counted from zero) for given volumic element.
3881 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3883 def GetFaceNormal(self, faceId, normalized=False):
3885 Return three components of normal of given mesh face
3886 (or an empty array in KO case)
3889 return self.mesh.GetFaceNormal(faceId,normalized)
3891 def FindElementByNodes(self, nodes):
3893 Return an element based on all given nodes.
3896 return self.mesh.FindElementByNodes(nodes)
3898 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3900 Return elements including all given nodes.
3903 return self.mesh.GetElementsByNodes( nodes, elemType )
3905 def IsPoly(self, id):
3907 Return true if the given element is a polygon
3910 return self.mesh.IsPoly(id)
3912 def IsQuadratic(self, id):
3914 Return true if the given element is quadratic
3917 return self.mesh.IsQuadratic(id)
3919 def GetBallDiameter(self, id):
3921 Return diameter of a ball discrete element or zero in case of an invalid *id*
3924 return self.mesh.GetBallDiameter(id)
3926 def BaryCenter(self, id):
3928 Return XYZ coordinates of the barycenter of the given element.
3929 If there is no element for the given ID - return an empty list
3932 a list of three double values
3935 :meth:`smeshBuilder.GetGravityCenter`
3938 return self.mesh.BaryCenter(id)
3940 def GetIdsFromFilter(self, filter, meshParts=[] ):
3942 Pass mesh elements through the given filter and return IDs of fitting elements
3945 filter: :class:`SMESH.Filter`
3946 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3952 :meth:`SMESH.Filter.GetIDs`
3953 :meth:`SMESH.Filter.GetElementsIdFromParts`
3956 filter.SetMesh( self.mesh )
3959 if isinstance( meshParts, Mesh ):
3960 filter.SetMesh( meshParts.GetMesh() )
3961 return theFilter.GetIDs()
3962 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3963 meshParts = [ meshParts ]
3964 return filter.GetElementsIdFromParts( meshParts )
3966 return filter.GetIDs()
3968 # Get mesh measurements information:
3969 # ------------------------------------
3971 def GetFreeBorders(self):
3973 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3974 Return a list of special structures (borders).
3977 a list of :class:`SMESH.FreeEdges.Border`
3980 aFilterMgr = self.smeshpyD.CreateFilterManager()
3981 aPredicate = aFilterMgr.CreateFreeEdges()
3982 aPredicate.SetMesh(self.mesh)
3983 aBorders = aPredicate.GetBorders()
3984 aFilterMgr.UnRegister()
3987 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3989 Get minimum distance between two nodes, elements or distance to the origin
3992 id1: first node/element id
3993 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3994 isElem1: *True* if *id1* is element id, *False* if it is node id
3995 isElem2: *True* if *id2* is element id, *False* if it is node id
3998 minimum distance value
4000 :meth:`GetMinDistance`
4003 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
4004 return aMeasure.value
4006 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
4008 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
4011 id1: first node/element id
4012 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
4013 isElem1: *True* if *id1* is element id, *False* if it is node id
4014 isElem2: *True* if *id2* is element id, *False* if it is node id
4017 :class:`SMESH.Measure` structure
4023 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
4025 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
4028 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
4030 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4035 aMeasurements = self.smeshpyD.CreateMeasurements()
4036 aMeasure = aMeasurements.MinDistance(id1, id2)
4037 genObjUnRegister([aMeasurements,id1, id2])
4040 def BoundingBox(self, objects=None, isElem=False):
4042 Get bounding box of the specified object(s)
4045 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4046 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4047 *False* specifies that *objects* are nodes
4050 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4053 :meth:`GetBoundingBox()`
4056 result = self.GetBoundingBox(objects, isElem)
4060 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4063 def GetBoundingBox(self, objects=None, isElem=False):
4065 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4068 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4069 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4070 False means that *objects* are nodes
4073 :class:`SMESH.Measure` structure
4076 :meth:`BoundingBox()`
4080 objects = [self.mesh]
4081 elif isinstance(objects, tuple):
4082 objects = list(objects)
4083 if not isinstance(objects, list):
4085 if len(objects) > 0 and isinstance(objects[0], int):
4088 unRegister = genObjUnRegister()
4090 if isinstance(o, Mesh):
4091 srclist.append(o.mesh)
4092 elif hasattr(o, "_narrow"):
4093 src = o._narrow(SMESH.SMESH_IDSource)
4094 if src: srclist.append(src)
4096 elif isinstance(o, list):
4098 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4100 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4101 unRegister.set( srclist[-1] )
4104 aMeasurements = self.smeshpyD.CreateMeasurements()
4105 unRegister.set( aMeasurements )
4106 aMeasure = aMeasurements.BoundingBox(srclist)
4109 # Mesh edition (SMESH_MeshEditor functionality):
4110 # ---------------------------------------------
4112 def RemoveElements(self, IDsOfElements):
4114 Remove the elements from the mesh by ids
4117 IDsOfElements: is a list of ids of elements to remove
4123 This operation can create gaps in numeration of elements.
4124 Call :meth:`RenumberElements` to remove the gaps.
4127 return self.editor.RemoveElements(IDsOfElements)
4129 def RemoveNodes(self, IDsOfNodes):
4131 Remove nodes from mesh by ids
4134 IDsOfNodes: is a list of ids of nodes to remove
4140 This operation can create gaps in numeration of nodes.
4141 Call :meth:`RenumberElements` to remove the gaps.
4144 return self.editor.RemoveNodes(IDsOfNodes)
4146 def RemoveNodeWithReconnection(self, nodeID ):
4148 Remove a node along with changing surrounding faces to cover a hole.
4151 nodeID: ID of node to remove
4154 return self.editor.RemoveNodeWithReconnection( nodeID )
4156 def RemoveOrphanNodes(self):
4158 Remove all orphan (free) nodes from mesh
4161 number of the removed nodes
4164 This operation can create gaps in numeration of nodes.
4165 Call :meth:`RenumberElements` to remove the gaps.
4168 return self.editor.RemoveOrphanNodes()
4170 def AddNode(self, x, y, z):
4172 Add a node to the mesh by coordinates
4178 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4179 if hasVars: self.mesh.SetParameters(Parameters)
4180 return self.editor.AddNode( x, y, z)
4182 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4184 Create a 0D element on a node with given number.
4187 IDOfNode: the ID of node for creation of the element.
4188 DuplicateElements: to add one more 0D element to a node or not
4191 ID of the new 0D element
4194 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4196 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4198 Create 0D elements on all nodes of the given elements except those
4199 nodes on which a 0D element already exists.
4202 theObject: an object on whose nodes 0D elements will be created.
4203 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4204 theGroupName: optional name of a group to add 0D elements created
4205 and/or found on nodes of *theObject*.
4206 DuplicateElements: to add one more 0D element to a node or not
4209 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4210 IDs of new and/or found 0D elements. IDs of 0D elements
4211 can be retrieved from the returned object by
4212 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4215 unRegister = genObjUnRegister()
4216 if isinstance( theObject, Mesh ):
4217 theObject = theObject.GetMesh()
4218 elif isinstance( theObject, list ):
4219 theObject = self.GetIDSource( theObject, SMESH.ALL )
4220 unRegister.set( theObject )
4221 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4223 def AddBall(self, IDOfNode, diameter):
4225 Create a ball element on a node with given ID.
4228 IDOfNode: the ID of node for creation of the element.
4229 diameter: the bal diameter.
4232 ID of the new ball element
4235 return self.editor.AddBall( IDOfNode, diameter )
4237 def AddEdge(self, IDsOfNodes):
4239 Create a linear or quadratic edge (this is determined
4240 by the number of given nodes).
4243 IDsOfNodes: list of node IDs for creation of the element.
4244 The order of nodes in this list should correspond to
4245 the :ref:`connectivity convention <connectivity_page>`.
4251 return self.editor.AddEdge(IDsOfNodes)
4253 def AddFace(self, IDsOfNodes):
4255 Create a linear or quadratic face (this is determined
4256 by the number of given nodes).
4259 IDsOfNodes: list of node IDs for creation of the element.
4260 The order of nodes in this list should correspond to
4261 the :ref:`connectivity convention <connectivity_page>`.
4267 return self.editor.AddFace(IDsOfNodes)
4269 def AddPolygonalFace(self, IdsOfNodes):
4271 Add a polygonal face defined by a list of node IDs
4274 IdsOfNodes: the list of node IDs for creation of the element.
4280 return self.editor.AddPolygonalFace(IdsOfNodes)
4282 def AddQuadPolygonalFace(self, IdsOfNodes):
4284 Add a quadratic polygonal face defined by a list of node IDs
4287 IdsOfNodes: the list of node IDs for creation of the element;
4288 corner nodes follow first.
4294 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4296 def AddVolume(self, IDsOfNodes):
4298 Create both simple and quadratic volume (this is determined
4299 by the number of given nodes).
4302 IDsOfNodes: list of node IDs for creation of the element.
4303 The order of nodes in this list should correspond to
4304 the :ref:`connectivity convention <connectivity_page>`.
4307 ID of the new volumic element
4310 return self.editor.AddVolume(IDsOfNodes)
4312 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4314 Create a volume of many faces, giving nodes for each face.
4317 IdsOfNodes: list of node IDs for volume creation, face by face.
4318 Quantities: list of integer values, Quantities[i]
4319 gives the quantity of nodes in face number i.
4322 ID of the new volumic element
4325 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4327 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4329 Create a volume of many faces, giving the IDs of the existing faces.
4332 The created volume will refer only to the nodes
4333 of the given faces, not to the faces themselves.
4336 IdsOfFaces: the list of face IDs for volume creation.
4339 ID of the new volumic element
4342 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4345 def SetNodeOnVertex(self, NodeID, Vertex):
4347 Bind a node to a vertex
4351 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4354 True if succeed else raises an exception
4357 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4358 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4362 self.editor.SetNodeOnVertex(NodeID, VertexID)
4363 except SALOME.SALOME_Exception as inst:
4364 raise ValueError(inst.details.text)
4368 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4370 Store the node position on an edge
4374 Edge: an edge (GEOM.GEOM_Object) or edge ID
4375 paramOnEdge: a parameter on the edge where the node is located
4378 True if succeed else raises an exception
4381 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4382 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4386 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4387 except SALOME.SALOME_Exception as inst:
4388 raise ValueError(inst.details.text)
4391 def SetNodeOnFace(self, NodeID, Face, u, v):
4393 Store node position on a face
4397 Face: a face (GEOM.GEOM_Object) or face ID
4398 u: U parameter on the face where the node is located
4399 v: V parameter on the face where the node is located
4402 True if succeed else raises an exception
4405 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4406 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4410 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4411 except SALOME.SALOME_Exception as inst:
4412 raise ValueError(inst.details.text)
4415 def SetNodeInVolume(self, NodeID, Solid):
4417 Bind a node to a solid
4421 Solid: a solid (GEOM.GEOM_Object) or solid ID
4424 True if succeed else raises an exception
4427 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4428 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4432 self.editor.SetNodeInVolume(NodeID, SolidID)
4433 except SALOME.SALOME_Exception as inst:
4434 raise ValueError(inst.details.text)
4437 def SetMeshElementOnShape(self, ElementID, Shape):
4439 Bind an element to a shape
4442 ElementID: an element ID
4443 Shape: a shape (GEOM.GEOM_Object) or shape ID
4446 True if succeed else raises an exception
4449 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4450 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4454 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4455 except SALOME.SALOME_Exception as inst:
4456 raise ValueError(inst.details.text)
4460 def MoveNode(self, NodeID, x, y, z):
4462 Move the node with the given id
4465 NodeID: the id of the node
4466 x: a new X coordinate
4467 y: a new Y coordinate
4468 z: a new Z coordinate
4471 True if succeed else False
4474 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4475 if hasVars: self.mesh.SetParameters(Parameters)
4476 return self.editor.MoveNode(NodeID, x, y, z)
4478 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4480 Find the node closest to a point and moves it to a point location
4483 x: the X coordinate of a point
4484 y: the Y coordinate of a point
4485 z: the Z coordinate of a point
4486 NodeID: if specified (>0), the node with this ID is moved,
4487 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4490 the ID of a moved node
4493 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4494 if hasVars: self.mesh.SetParameters(Parameters)
4495 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4497 def FindNodeClosestTo(self, x, y, z):
4499 Find the node closest to a point
4502 x: the X coordinate of a point
4503 y: the Y coordinate of a point
4504 z: the Z coordinate of a point
4510 return self.editor.FindNodeClosestTo(x, y, z)
4512 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4514 Find the elements where a point lays IN or ON
4517 x,y,z (float): coordinates of the point
4518 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4519 means elements of any type excluding nodes, discrete and 0D elements.
4520 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4523 list of IDs of found elements
4526 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4528 return self.editor.FindElementsByPoint(x, y, z, elementType)
4530 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4532 Project a point to a mesh object.
4533 Return ID of an element of given type where the given point is projected
4534 and coordinates of the projection point.
4535 In the case if nothing found, return -1 and []
4537 if isinstance( meshObject, Mesh ):
4538 meshObject = meshObject.GetMesh()
4540 meshObject = self.GetMesh()
4541 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4543 def GetPointState(self, x, y, z):
4545 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4546 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4547 UNKNOWN state means that either mesh is wrong or the analysis fails.
4550 return self.editor.GetPointState(x, y, z)
4552 def IsManifold(self):
4554 Check if a 2D mesh is manifold
4557 return self.editor.IsManifold()
4559 def IsCoherentOrientation2D(self):
4561 Check if orientation of 2D elements is coherent
4564 return self.editor.IsCoherentOrientation2D()
4566 def Get1DBranches( self, edges, startNode = 0 ):
4568 Partition given 1D elements into groups of contiguous edges.
4569 A node where number of meeting edges != 2 is a group end.
4570 An optional startNode is used to orient groups it belongs to.
4573 A list of edge groups and a list of corresponding node groups,
4574 where the group is a list of IDs of edges or nodes, like follows
4575 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4576 If a group is closed, the first and last nodes of the group are same.
4578 if isinstance( edges, Mesh ):
4579 edges = edges.GetMesh()
4580 unRegister = genObjUnRegister()
4581 if isinstance( edges, list ):
4582 edges = self.GetIDSource( edges, SMESH.EDGE )
4583 unRegister.set( edges )
4584 return self.editor.Get1DBranches( edges, startNode )
4586 def FindSharpEdges( self, angle, addExisting=False ):
4588 Return sharp edges of faces and non-manifold ones.
4589 Optionally add existing edges.
4592 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4593 addExisting: to return existing edges (1D elements) as well
4596 list of FaceEdge structures
4598 angle = ParseParameters( angle )[0]
4599 return self.editor.FindSharpEdges( angle, addExisting )
4601 def MeshToPassThroughAPoint(self, x, y, z):
4603 Find the node closest to a point and moves it to a point location
4606 x: the X coordinate of a point
4607 y: the Y coordinate of a point
4608 z: the Z coordinate of a point
4611 the ID of a moved node
4614 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4616 def InverseDiag(self, NodeID1, NodeID2):
4618 Replace two neighbour triangles sharing Node1-Node2 link
4619 with the triangles built on the same 4 nodes but having other common link.
4622 NodeID1: the ID of the first node
4623 NodeID2: the ID of the second node
4626 False if proper faces were not found
4628 return self.editor.InverseDiag(NodeID1, NodeID2)
4630 def DeleteDiag(self, NodeID1, NodeID2):
4632 Replace two neighbour triangles sharing *Node1-Node2* link
4633 with a quadrangle built on the same 4 nodes.
4636 NodeID1: ID of the first node
4637 NodeID2: ID of the second node
4640 False if proper faces were not found
4643 This operation can create gaps in numeration of elements.
4644 Call :meth:`RenumberElements` to remove the gaps.
4647 return self.editor.DeleteDiag(NodeID1, NodeID2)
4649 def AddNodeOnSegment(self, Node1, Node2, position = 0.5):
4651 Replace each triangle bound by Node1-Node2 segment with
4652 two triangles by connecting a node made on the link with a node
4653 opposite to the link.
4656 Node1: ID of the first node
4657 Node2: ID of the second node
4658 position: location [0,1] of the new node on the segment
4660 return self.editor.AddNodeOnSegment(Node1, Node2, position)
4662 def AddNodeOnFace(self, face, x, y, z):
4664 Split a face into triangles by adding a new node onto the face
4665 and connecting the new node with face nodes
4668 face: ID of the face
4669 x,y,z: coordinates of the new node
4671 return self.editor.AddNodeOnFace(face, x, y, z)
4673 def Reorient(self, IDsOfElements=None):
4675 Reorient elements by ids
4678 IDsOfElements: if undefined reorients all mesh elements
4681 True if succeed else False
4684 if IDsOfElements == None:
4685 IDsOfElements = self.GetElementsId()
4686 return self.editor.Reorient(IDsOfElements)
4688 def ReorientObject(self, theObject):
4690 Reorient all elements of the object
4693 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4696 True if succeed else False
4699 if ( isinstance( theObject, Mesh )):
4700 theObject = theObject.GetMesh()
4701 return self.editor.ReorientObject(theObject)
4703 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4705 Reorient faces contained in *the2DObject*.
4708 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4709 theDirection: a desired direction of normal of *theFace*.
4710 It can be either a GEOM vector or a list of coordinates [x,y,z].
4711 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4712 compared with theDirection. It can be either ID of face or a point
4713 by which the face will be found. The point can be given as either
4714 a GEOM vertex or a list of point coordinates.
4717 number of reoriented faces
4720 unRegister = genObjUnRegister()
4722 if isinstance( the2DObject, Mesh ):
4723 the2DObject = the2DObject.GetMesh()
4724 if isinstance( the2DObject, list ):
4725 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4726 unRegister.set( the2DObject )
4727 # check theDirection
4728 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4729 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4730 if isinstance( theDirection, list ):
4731 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4732 # prepare theFace and thePoint
4733 theFace = theFaceOrPoint
4734 thePoint = PointStruct(0,0,0)
4735 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4736 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4738 if isinstance( theFaceOrPoint, list ):
4739 thePoint = PointStruct( *theFaceOrPoint )
4741 if isinstance( theFaceOrPoint, PointStruct ):
4742 thePoint = theFaceOrPoint
4744 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4746 def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4748 Reorient faces contained in a list of *objectFaces*
4749 equally to faces contained in a list of *referenceFaces*.
4752 objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4753 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.
4756 number of reoriented faces.
4758 if not isinstance( objectFaces, list ):
4759 objectFaces = [ objectFaces ]
4760 for i,obj2D in enumerate( objectFaces ):
4761 if isinstance( obj2D, Mesh ):
4762 objectFaces[i] = obj2D.GetMesh()
4763 if not isinstance( referenceFaces, list ):
4764 referenceFaces = [ referenceFaces ]
4766 return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4769 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4771 Reorient faces according to adjacent volumes.
4774 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4775 either IDs of faces or face groups.
4776 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4777 theOutsideNormal: to orient faces to have their normals
4778 pointing either *outside* or *inside* the adjacent volumes.
4781 number of reoriented faces.
4784 unRegister = genObjUnRegister()
4786 if not isinstance( the2DObject, list ):
4787 the2DObject = [ the2DObject ]
4788 elif the2DObject and isinstance( the2DObject[0], int ):
4789 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4790 unRegister.set( the2DObject )
4791 the2DObject = [ the2DObject ]
4792 for i,obj2D in enumerate( the2DObject ):
4793 if isinstance( obj2D, Mesh ):
4794 the2DObject[i] = obj2D.GetMesh()
4795 if isinstance( obj2D, list ):
4796 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4797 unRegister.set( the2DObject[i] )
4799 if isinstance( the3DObject, Mesh ):
4800 the3DObject = the3DObject.GetMesh()
4801 if isinstance( the3DObject, list ):
4802 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4803 unRegister.set( the3DObject )
4804 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4806 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4808 Fuse the neighbouring triangles into quadrangles.
4811 IDsOfElements: The triangles to be fused.
4812 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4813 applied to possible quadrangles to choose a neighbour to fuse with.
4814 Note that not all items of :class:`SMESH.FunctorType` corresponds
4815 to numerical functors.
4816 MaxAngle: is the maximum angle between element normals at which the fusion
4817 is still performed; theMaxAngle is measured in radians.
4818 Also it could be a name of variable which defines angle in degrees.
4821 True in case of success, False otherwise.
4824 This operation can create gaps in numeration of elements.
4825 Call :meth:`RenumberElements` to remove the gaps.
4828 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4829 self.mesh.SetParameters(Parameters)
4830 if not IDsOfElements:
4831 IDsOfElements = self.GetElementsId()
4832 Functor = self.smeshpyD.GetFunctor(theCriterion)
4833 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4835 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4837 Fuse the neighbouring triangles of the object into quadrangles
4840 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4841 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4842 applied to possible quadrangles to choose a neighbour to fuse with.
4843 Note that not all items of :class:`SMESH.FunctorType` corresponds
4844 to numerical functors.
4845 MaxAngle: a max angle between element normals at which the fusion
4846 is still performed; theMaxAngle is measured in radians.
4849 True in case of success, False otherwise.
4852 This operation can create gaps in numeration of elements.
4853 Call :meth:`RenumberElements` to remove the gaps.
4856 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4857 self.mesh.SetParameters(Parameters)
4858 if isinstance( theObject, Mesh ):
4859 theObject = theObject.GetMesh()
4860 Functor = self.smeshpyD.GetFunctor(theCriterion)
4861 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4863 def QuadToTri (self, IDsOfElements, theCriterion = None):
4865 Split quadrangles into triangles.
4868 IDsOfElements: the faces to be splitted.
4869 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4870 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4871 value, then quadrangles will be split by the smallest diagonal.
4872 Note that not all items of :class:`SMESH.FunctorType` corresponds
4873 to numerical functors.
4876 True in case of success, False otherwise.
4879 This operation can create gaps in numeration of elements.
4880 Call :meth:`RenumberElements` to remove the gaps.
4882 if IDsOfElements == []:
4883 IDsOfElements = self.GetElementsId()
4884 if theCriterion is None:
4885 theCriterion = FT_MaxElementLength2D
4886 Functor = self.smeshpyD.GetFunctor(theCriterion)
4887 return self.editor.QuadToTri(IDsOfElements, Functor)
4889 def QuadToTriObject (self, theObject, theCriterion = None):
4891 Split quadrangles into triangles.
4894 theObject: the object from which the list of elements is taken,
4895 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4896 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4897 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4898 value, then quadrangles will be split by the smallest diagonal.
4899 Note that not all items of :class:`SMESH.FunctorType` corresponds
4900 to numerical functors.
4903 True in case of success, False otherwise.
4906 This operation can create gaps in numeration of elements.
4907 Call :meth:`RenumberElements` to remove the gaps.
4909 if ( isinstance( theObject, Mesh )):
4910 theObject = theObject.GetMesh()
4911 if theCriterion is None:
4912 theCriterion = FT_MaxElementLength2D
4913 Functor = self.smeshpyD.GetFunctor(theCriterion)
4914 return self.editor.QuadToTriObject(theObject, Functor)
4916 def QuadTo4Tri (self, theElements=[]):
4918 Split each of given quadrangles into 4 triangles. A node is added at the center of
4922 theElements: the faces to be splitted. This can be either
4923 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4924 or a list of face IDs. By default all quadrangles are split
4927 This operation can create gaps in numeration of elements.
4928 Call :meth:`RenumberElements` to remove the gaps.
4930 unRegister = genObjUnRegister()
4931 if isinstance( theElements, Mesh ):
4932 theElements = theElements.mesh
4933 elif not theElements:
4934 theElements = self.mesh
4935 elif isinstance( theElements, list ):
4936 theElements = self.GetIDSource( theElements, SMESH.FACE )
4937 unRegister.set( theElements )
4938 return self.editor.QuadTo4Tri( theElements )
4940 def SplitQuad (self, IDsOfElements, Diag13):
4942 Split quadrangles into triangles.
4945 IDsOfElements: the faces to be splitted
4946 Diag13 (boolean): is used to choose a diagonal for splitting.
4949 True in case of success, False otherwise.
4952 This operation can create gaps in numeration of elements.
4953 Call :meth:`RenumberElements` to remove the gaps.
4955 if IDsOfElements == []:
4956 IDsOfElements = self.GetElementsId()
4957 return self.editor.SplitQuad(IDsOfElements, Diag13)
4959 def SplitQuadObject (self, theObject, Diag13):
4961 Split quadrangles into triangles.
4964 theObject: the object from which the list of elements is taken,
4965 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4966 Diag13 (boolean): is used to choose a diagonal for splitting.
4969 True in case of success, False otherwise.
4972 This operation can create gaps in numeration of elements.
4973 Call :meth:`RenumberElements` to remove the gaps.
4975 if ( isinstance( theObject, Mesh )):
4976 theObject = theObject.GetMesh()
4977 return self.editor.SplitQuadObject(theObject, Diag13)
4979 def BestSplit (self, IDOfQuad, theCriterion):
4981 Find a better splitting of the given quadrangle.
4984 IDOfQuad: the ID of the quadrangle to be splitted.
4985 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4986 choose a diagonal for splitting.
4987 Note that not all items of :class:`SMESH.FunctorType` corresponds
4988 to numerical functors.
4991 * 1 if 1-3 diagonal is better,
4992 * 2 if 2-4 diagonal is better,
4993 * 0 if error occurs.
4996 This operation can create gaps in numeration of elements.
4997 Call :meth:`RenumberElements` to remove the gaps.
4999 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
5001 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
5003 Split volumic elements into tetrahedrons
5006 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5007 method: flags passing splitting method:
5008 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
5009 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
5012 This operation can create gaps in numeration of elements.
5013 Call :meth:`RenumberElements` to remove the gaps.
5015 unRegister = genObjUnRegister()
5016 if isinstance( elems, Mesh ):
5017 elems = elems.GetMesh()
5018 if ( isinstance( elems, list )):
5019 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5020 unRegister.set( elems )
5021 self.editor.SplitVolumesIntoTetra(elems, method)
5024 def SplitBiQuadraticIntoLinear(self, elems=None):
5026 Split bi-quadratic elements into linear ones without creation of additional nodes:
5028 - bi-quadratic triangle will be split into 3 linear quadrangles;
5029 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
5030 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
5032 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
5033 will be split in order to keep the mesh conformal.
5036 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
5037 if None (default), all bi-quadratic elements will be split
5040 This operation can create gaps in numeration of elements.
5041 Call :meth:`RenumberElements` to remove the gaps.
5043 unRegister = genObjUnRegister()
5044 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
5045 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
5046 unRegister.set( elems )
5048 elems = [ self.GetMesh() ]
5049 if isinstance( elems, Mesh ):
5050 elems = [ elems.GetMesh() ]
5051 if not isinstance( elems, list ):
5053 self.editor.SplitBiQuadraticIntoLinear( elems )
5055 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
5056 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
5058 Split hexahedra into prisms
5061 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5062 startHexPoint: a point used to find a hexahedron for which *facetNormal*
5063 gives a normal vector defining facets to split into triangles.
5064 *startHexPoint* can be either a triple of coordinates or a vertex.
5065 facetNormal: a normal to a facet to split into triangles of a
5066 hexahedron found by *startHexPoint*.
5067 *facetNormal* can be either a triple of coordinates or an edge.
5068 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
5069 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
5070 allDomains: if :code:`False`, only hexahedra adjacent to one closest
5071 to *startHexPoint* are split, else *startHexPoint*
5072 is used to find the facet to split in all domains present in *elems*.
5075 This operation can create gaps in numeration of elements.
5076 Call :meth:`RenumberElements` to remove the gaps.
5079 unRegister = genObjUnRegister()
5080 if isinstance( elems, Mesh ):
5081 elems = elems.GetMesh()
5082 if ( isinstance( elems, list )):
5083 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5084 unRegister.set( elems )
5087 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5088 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5089 elif isinstance( startHexPoint, list ):
5090 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5093 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5094 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5095 elif isinstance( facetNormal, list ):
5096 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5099 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5101 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5103 def SplitQuadsNearTriangularFacets(self):
5105 Split quadrangle faces near triangular facets of volumes
5108 This operation can create gaps in numeration of elements.
5109 Call :meth:`RenumberElements` to remove the gaps.
5111 faces_array = self.GetElementsByType(SMESH.FACE)
5112 for face_id in faces_array:
5113 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5114 quad_nodes = self.mesh.GetElemNodes(face_id)
5115 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5116 isVolumeFound = False
5117 for node1_elem in node1_elems:
5118 if not isVolumeFound:
5119 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5120 nb_nodes = self.GetElemNbNodes(node1_elem)
5121 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5122 volume_elem = node1_elem
5123 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5124 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5125 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5126 isVolumeFound = True
5127 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5128 self.SplitQuad([face_id], False) # diagonal 2-4
5129 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5130 isVolumeFound = True
5131 self.SplitQuad([face_id], True) # diagonal 1-3
5132 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5133 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5134 isVolumeFound = True
5135 self.SplitQuad([face_id], True) # diagonal 1-3
5137 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5139 Split hexahedrons into tetrahedrons.
5141 This operation uses :doc:`pattern_mapping` functionality for splitting.
5144 theObject: the object from which the list of hexahedrons is taken;
5145 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5146 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5147 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5148 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5149 key-point will be mapped into *theNode001*-th node of each volume.
5150 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5153 True in case of success, False otherwise.
5156 This operation can create gaps in numeration of elements.
5157 Call :meth:`RenumberElements` to remove the gaps.
5165 # (0,0,1) 4.---------.7 * |
5172 # (0,0,0) 0.---------.3
5173 pattern_tetra = "!!! Nb of points: \n 8 \n\
5183 !!! Indices of points of 6 tetras: \n\
5191 pattern = self.smeshpyD.GetPattern()
5192 isDone = pattern.LoadFromFile(pattern_tetra)
5194 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5197 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5198 isDone = pattern.MakeMesh(self.mesh, False, False)
5199 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5201 # split quafrangle faces near triangular facets of volumes
5202 self.SplitQuadsNearTriangularFacets()
5206 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5208 Split hexahedrons into prisms.
5210 Uses the :doc:`pattern_mapping` functionality for splitting.
5213 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5214 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5215 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5216 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5217 will be mapped into the *theNode001* -th node of each volume.
5218 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5221 True in case of success, False otherwise.
5224 This operation can create gaps in numeration of elements.
5225 Call :meth:`RenumberElements` to remove the gaps.
5227 # Pattern: 5.---------.6
5232 # (0,0,1) 4.---------.7 |
5239 # (0,0,0) 0.---------.3
5240 pattern_prism = "!!! Nb of points: \n 8 \n\
5250 !!! Indices of points of 2 prisms: \n\
5254 pattern = self.smeshpyD.GetPattern()
5255 isDone = pattern.LoadFromFile(pattern_prism)
5257 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5260 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5261 isDone = pattern.MakeMesh(self.mesh, False, False)
5262 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5264 # Split quafrangle faces near triangular facets of volumes
5265 self.SplitQuadsNearTriangularFacets()
5269 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5270 MaxNbOfIterations, MaxAspectRatio, Method):
5275 IDsOfElements: the list if ids of elements to smooth
5276 IDsOfFixedNodes: the list of ids of fixed nodes.
5277 Note that nodes built on edges and boundary nodes are always fixed.
5278 MaxNbOfIterations: the maximum number of iterations
5279 MaxAspectRatio: varies in range [1.0, inf]
5280 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5281 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5284 True in case of success, False otherwise.
5287 if IDsOfElements == []:
5288 IDsOfElements = self.GetElementsId()
5289 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5290 self.mesh.SetParameters(Parameters)
5291 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5292 MaxNbOfIterations, MaxAspectRatio, Method)
5294 def SmoothObject(self, theObject, IDsOfFixedNodes,
5295 MaxNbOfIterations, MaxAspectRatio, Method):
5297 Smooth elements which belong to the given object
5300 theObject: the object to smooth
5301 IDsOfFixedNodes: the list of ids of fixed nodes.
5302 Note that nodes built on edges and boundary nodes are always fixed.
5303 MaxNbOfIterations: the maximum number of iterations
5304 MaxAspectRatio: varies in range [1.0, inf]
5305 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5306 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5309 True in case of success, False otherwise.
5312 if ( isinstance( theObject, Mesh )):
5313 theObject = theObject.GetMesh()
5314 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5315 MaxNbOfIterations, MaxAspectRatio, Method)
5317 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5318 MaxNbOfIterations, MaxAspectRatio, Method):
5320 Parametrically smooth the given elements
5323 IDsOfElements: the list if ids of elements to smooth
5324 IDsOfFixedNodes: the list of ids of fixed nodes.
5325 Note that nodes built on edges and boundary nodes are always fixed.
5326 MaxNbOfIterations: the maximum number of iterations
5327 MaxAspectRatio: varies in range [1.0, inf]
5328 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5329 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5332 True in case of success, False otherwise.
5335 if IDsOfElements == []:
5336 IDsOfElements = self.GetElementsId()
5337 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5338 self.mesh.SetParameters(Parameters)
5339 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5340 MaxNbOfIterations, MaxAspectRatio, Method)
5342 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5343 MaxNbOfIterations, MaxAspectRatio, Method):
5345 Parametrically smooth the elements which belong to the given object
5348 theObject: the object to smooth
5349 IDsOfFixedNodes: the list of ids of fixed nodes.
5350 Note that nodes built on edges and boundary nodes are always fixed.
5351 MaxNbOfIterations: the maximum number of iterations
5352 MaxAspectRatio: varies in range [1.0, inf]
5353 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5354 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5357 True in case of success, False otherwise.
5360 if ( isinstance( theObject, Mesh )):
5361 theObject = theObject.GetMesh()
5362 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5363 MaxNbOfIterations, MaxAspectRatio, Method)
5365 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5367 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5368 them with quadratic with the same id.
5371 theForce3d: method of new node creation:
5373 * False - the medium node lies at the geometrical entity from which the mesh element is built
5374 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5375 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5376 theToBiQuad: If True, converts the mesh to bi-quadratic
5379 :class:`SMESH.ComputeError` which can hold a warning
5382 If *theSubMesh* is provided, the mesh can become non-conformal
5385 This operation can create gaps in numeration of nodes or elements.
5386 Call :meth:`RenumberElements` to remove the gaps.
5389 if isinstance( theSubMesh, Mesh ):
5390 theSubMesh = theSubMesh.mesh
5392 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5395 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5397 self.editor.ConvertToQuadratic(theForce3d)
5398 error = self.editor.GetLastError()
5399 if error and error.comment:
5400 print(error.comment)
5403 def ConvertFromQuadratic(self, theSubMesh=None):
5405 Convert the mesh from quadratic to ordinary,
5406 deletes old quadratic elements,
5407 replacing them with ordinary mesh elements with the same id.
5410 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5413 If *theSubMesh* is provided, the mesh can become non-conformal
5416 This operation can create gaps in numeration of nodes or elements.
5417 Call :meth:`RenumberElements` to remove the gaps.
5421 self.editor.ConvertFromQuadraticObject(theSubMesh)
5423 return self.editor.ConvertFromQuadratic()
5425 def Make2DMeshFrom3D(self):
5427 Create 2D mesh as skin on boundary faces of a 3D mesh
5430 True if operation has been completed successfully, False otherwise
5433 return self.editor.Make2DMeshFrom3D()
5435 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5436 toCopyElements=False, toCopyExistingBondary=False):
5438 Create missing boundary elements
5441 elements: elements whose boundary is to be checked:
5442 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5443 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5444 dimension: defines type of boundary elements to create, either of
5445 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5446 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5447 groupName: a name of group to store created boundary elements in,
5448 "" means not to create the group
5449 meshName: a name of new mesh to store created boundary elements in,
5450 "" means not to create the new mesh
5451 toCopyElements: if True, the checked elements will be copied into
5452 the new mesh else only boundary elements will be copied into the new mesh
5453 toCopyExistingBondary: if True, not only new but also pre-existing
5454 boundary elements will be copied into the new mesh
5457 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5460 unRegister = genObjUnRegister()
5461 if isinstance( elements, Mesh ):
5462 elements = elements.GetMesh()
5463 if ( isinstance( elements, list )):
5464 elemType = SMESH.ALL
5465 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5466 elements = self.editor.MakeIDSource(elements, elemType)
5467 unRegister.set( elements )
5468 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5469 toCopyElements,toCopyExistingBondary)
5470 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5473 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5474 toCopyAll=False, groups=[]):
5476 Create missing boundary elements around either the whole mesh or
5480 dimension: defines type of boundary elements to create, either of
5481 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5482 groupName: a name of group to store all boundary elements in,
5483 "" means not to create the group
5484 meshName: a name of a new mesh, which is a copy of the initial
5485 mesh + created boundary elements; "" means not to create the new mesh
5486 toCopyAll: if True, the whole initial mesh will be copied into
5487 the new mesh else only boundary elements will be copied into the new mesh
5488 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5491 tuple( long, mesh, group )
5492 - long - number of added boundary elements
5493 - mesh - the :class:`Mesh` where elements were added to
5494 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5497 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5499 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5500 return nb, mesh, group
5502 def RenumberNodes(self):
5504 Renumber mesh nodes to remove unused node IDs
5506 self.editor.RenumberNodes()
5508 def RenumberElements(self):
5510 Renumber mesh elements to remove unused element IDs
5512 self.editor.RenumberElements()
5514 def _getIdSourceList(self, arg, idType, unRegister):
5516 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5518 if arg and isinstance( arg, list ):
5519 if isinstance( arg[0], int ):
5520 arg = self.GetIDSource( arg, idType )
5521 unRegister.set( arg )
5522 elif isinstance( arg[0], Mesh ):
5523 arg[0] = arg[0].GetMesh()
5524 elif isinstance( arg, Mesh ):
5526 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5530 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5531 MakeGroups=False, TotalAngle=False):
5533 Generate new elements by rotation of the given elements and nodes around the axis
5536 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5537 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5538 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5539 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5540 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5541 which defines angle in degrees
5542 NbOfSteps: the number of steps
5543 Tolerance: tolerance
5544 MakeGroups: forces the generation of new groups from existing ones
5545 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5546 of all steps, else - size of each step
5549 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5552 unRegister = genObjUnRegister()
5553 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5554 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5555 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5557 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5558 Axis = self.smeshpyD.GetAxisStruct( Axis )
5559 if isinstance( Axis, list ):
5560 Axis = SMESH.AxisStruct( *Axis )
5562 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5563 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5564 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5565 self.mesh.SetParameters(Parameters)
5566 if TotalAngle and NbOfSteps:
5567 AngleInRadians /= NbOfSteps
5568 return self.editor.RotationSweepObjects( nodes, edges, faces,
5569 Axis, AngleInRadians,
5570 NbOfSteps, Tolerance, MakeGroups)
5572 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5573 MakeGroups=False, TotalAngle=False):
5575 Generate new elements by rotation of the elements around the axis
5578 IDsOfElements: the list of ids of elements to sweep
5579 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5580 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5581 NbOfSteps: the number of steps
5582 Tolerance: tolerance
5583 MakeGroups: forces the generation of new groups from existing ones
5584 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5585 of all steps, else - size of each step
5588 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5591 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5592 AngleInRadians, NbOfSteps, Tolerance,
5593 MakeGroups, TotalAngle)
5595 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5596 MakeGroups=False, TotalAngle=False):
5598 Generate new elements by rotation of the elements of object around the axis
5599 theObject object which elements should be sweeped.
5600 It can be a mesh, a sub mesh or a group.
5603 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5604 AngleInRadians: the angle of Rotation
5605 NbOfSteps: number of steps
5606 Tolerance: tolerance
5607 MakeGroups: forces the generation of new groups from existing ones
5608 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5609 of all steps, else - size of each step
5612 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5615 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5616 AngleInRadians, NbOfSteps, Tolerance,
5617 MakeGroups, TotalAngle )
5619 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5620 MakeGroups=False, TotalAngle=False):
5622 Generate new elements by rotation of the elements of object around the axis
5623 theObject object which elements should be sweeped.
5624 It can be a mesh, a sub mesh or a group.
5627 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5628 AngleInRadians: the angle of Rotation
5629 NbOfSteps: number of steps
5630 Tolerance: tolerance
5631 MakeGroups: forces the generation of new groups from existing ones
5632 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5633 of all steps, else - size of each step
5636 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5637 empty list otherwise
5640 return self.RotationSweepObjects([],theObject,[], Axis,
5641 AngleInRadians, NbOfSteps, Tolerance,
5642 MakeGroups, TotalAngle)
5644 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5645 MakeGroups=False, TotalAngle=False):
5647 Generate new elements by rotation of the elements of object around the axis
5648 theObject object which elements should be sweeped.
5649 It can be a mesh, a sub mesh or a group.
5652 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5653 AngleInRadians: the angle of Rotation
5654 NbOfSteps: number of steps
5655 Tolerance: tolerance
5656 MakeGroups: forces the generation of new groups from existing ones
5657 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5658 of all steps, else - size of each step
5661 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5664 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5665 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5667 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5668 scaleFactors=[], linearVariation=False, basePoint=[],
5669 angles=[], anglesVariation=False):
5671 Generate new elements by extrusion of the given elements and nodes
5674 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5675 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5676 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5677 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5678 the direction and value of extrusion for one step (the total extrusion
5679 length will be NbOfSteps * ||StepVector||)
5680 NbOfSteps: the number of steps
5681 MakeGroups: forces the generation of new groups from existing ones
5682 scaleFactors: optional scale factors to apply during extrusion
5683 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5684 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5685 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5686 nodes and elements being extruded is used as the scaling center.
5689 - a list of tree components of the point or
5692 angles: list of angles in radians. Nodes at each extrusion step are rotated
5693 around *basePoint*, additionally to previous steps.
5694 anglesVariation: forces the computation of rotation angles as linear
5695 variation of the given *angles* along path steps
5697 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5699 Example: :ref:`tui_extrusion`
5701 unRegister = genObjUnRegister()
5702 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5703 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5704 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5706 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5707 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5708 if isinstance( StepVector, list ):
5709 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5711 if isinstance( basePoint, int):
5712 xyz = self.GetNodeXYZ( basePoint )
5714 raise RuntimeError("Invalid node ID: %s" % basePoint)
5716 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5717 basePoint = self.geompyD.PointCoordinates( basePoint )
5719 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5720 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5721 angles,angleParameters,hasVars = ParseAngles(angles)
5722 Parameters = StepVector.PS.parameters + var_separator + \
5723 Parameters + var_separator + \
5724 scaleParameters + var_separator + angleParameters
5725 self.mesh.SetParameters(Parameters)
5727 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5728 StepVector, NbOfSteps, MakeGroups,
5729 scaleFactors, linearVariation, basePoint,
5730 angles, anglesVariation )
5733 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5735 Generate new elements by extrusion of the elements with given ids
5738 IDsOfElements: the list of ids of elements or nodes for extrusion
5739 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5740 the direction and value of extrusion for one step (the total extrusion
5741 length will be NbOfSteps * ||StepVector||)
5742 NbOfSteps: the number of steps
5743 MakeGroups: forces the generation of new groups from existing ones
5744 IsNodes: is True if elements with given ids are nodes
5747 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5749 Example: :ref:`tui_extrusion`
5752 if IsNodes: n = IDsOfElements
5753 else : e,f, = IDsOfElements,IDsOfElements
5754 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5756 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5757 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5759 Generate new elements by extrusion along the normal to a discretized surface or wire
5762 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5763 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5764 StepSize: length of one extrusion step (the total extrusion
5765 length will be *NbOfSteps* *StepSize*).
5766 NbOfSteps: number of extrusion steps.
5767 ByAverageNormal: if True each node is translated by *StepSize*
5768 along the average of the normal vectors to the faces sharing the node;
5769 else each node is translated along the same average normal till
5770 intersection with the plane got by translation of the face sharing
5771 the node along its own normal by *StepSize*.
5772 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5773 for every node of *Elements*.
5774 MakeGroups: forces generation of new groups from existing ones.
5775 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5776 is not yet implemented. This parameter is used if *Elements* contains
5777 both faces and edges, i.e. *Elements* is a Mesh.
5780 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5781 empty list otherwise.
5782 Example: :ref:`tui_extrusion`
5785 unRegister = genObjUnRegister()
5786 if isinstance( Elements, Mesh ):
5787 Elements = [ Elements.GetMesh() ]
5788 if isinstance( Elements, list ):
5790 raise RuntimeError("Elements empty!")
5791 if isinstance( Elements[0], Mesh ):
5792 Elements = [ Elements[0].GetMesh() ]
5793 if isinstance( Elements[0], int ):
5794 Elements = self.GetIDSource( Elements, SMESH.ALL )
5795 unRegister.set( Elements )
5796 if not isinstance( Elements, list ):
5797 Elements = [ Elements ]
5798 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5799 self.mesh.SetParameters(Parameters)
5800 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5801 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5803 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5805 Generate new elements by extrusion of the elements or nodes which belong to the object
5808 theObject: the object whose elements or nodes should be processed.
5809 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5810 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5811 the direction and value of extrusion for one step (the total extrusion
5812 length will be NbOfSteps * ||StepVector||)
5813 NbOfSteps: the number of steps
5814 MakeGroups: forces the generation of new groups from existing ones
5815 IsNodes: is True if elements to extrude are nodes
5818 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5819 Example: :ref:`tui_extrusion`
5823 if IsNodes: n = theObject
5824 else : e,f, = theObject,theObject
5825 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5827 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5829 Generate new elements by extrusion of edges which belong to the object
5832 theObject: object whose 1D elements should be processed.
5833 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5834 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5835 the direction and value of extrusion for one step (the total extrusion
5836 length will be NbOfSteps * ||StepVector||)
5837 NbOfSteps: the number of steps
5838 MakeGroups: to generate new groups from existing ones
5841 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5842 Example: :ref:`tui_extrusion`
5845 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5847 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5849 Generate new elements by extrusion of faces which belong to the object
5852 theObject: object whose 2D elements should be processed.
5853 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5854 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5855 the direction and value of extrusion for one step (the total extrusion
5856 length will be NbOfSteps * ||StepVector||)
5857 NbOfSteps: the number of steps
5858 MakeGroups: forces the generation of new groups from existing ones
5861 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5862 Example: :ref:`tui_extrusion`
5865 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5867 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5868 ExtrFlags, SewTolerance, MakeGroups=False):
5870 Generate new elements by extrusion of the elements with given ids
5873 IDsOfElements: is ids of elements
5874 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5875 the direction and value of extrusion for one step (the total extrusion
5876 length will be NbOfSteps * ||StepVector||)
5877 NbOfSteps: the number of steps
5878 ExtrFlags: sets flags for extrusion
5879 SewTolerance: uses for comparing locations of nodes if flag
5880 EXTRUSION_FLAG_SEW is set
5881 MakeGroups: forces the generation of new groups from existing ones
5884 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5887 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5888 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5889 if isinstance( StepVector, list ):
5890 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5891 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5892 ExtrFlags, SewTolerance, MakeGroups)
5894 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5895 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5896 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5897 ScaleFactors=[], ScalesVariation=False):
5899 Generate new elements by extrusion of the given elements and nodes along the path.
5900 The path of extrusion must be a meshed edge.
5903 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5904 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5905 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5906 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5907 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
5908 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5909 HasAngles: not used obsolete
5910 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5911 around *basePoint*, additionally to previous steps.
5912 LinearVariation: forces the computation of rotation angles as linear
5913 variation of the given Angles along path steps
5914 HasRefPoint: allows using the reference point
5915 RefPoint: optional scaling and rotation center (mass center of the extruded
5916 elements by default). The User can specify any point as the Reference Point.
5917 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5918 MakeGroups: forces the generation of new groups from existing ones
5919 ScaleFactors: optional scale factors to apply during extrusion
5920 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5921 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5924 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5925 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5926 Example: :ref:`tui_extrusion_along_path`
5929 unRegister = genObjUnRegister()
5930 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5931 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5932 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5934 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5935 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5936 if isinstance( RefPoint, list ):
5937 if not RefPoint: RefPoint = [0,0,0]
5938 RefPoint = SMESH.PointStruct( *RefPoint )
5939 if isinstance( PathObject, Mesh ):
5940 PathObject = PathObject.GetMesh()
5941 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5942 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5943 Parameters = AnglesParameters + var_separator + \
5944 RefPoint.parameters + var_separator + ScalesParameters
5945 self.mesh.SetParameters(Parameters)
5946 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5947 PathObject, PathShape, NodeStart,
5948 HasAngles, Angles, LinearVariation,
5949 HasRefPoint, RefPoint, MakeGroups,
5950 ScaleFactors, ScalesVariation)
5952 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5953 HasAngles=False, Angles=[], LinearVariation=False,
5954 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5955 ElemType=SMESH.FACE):
5957 Generate new elements by extrusion of the given elements.
5958 The path of extrusion must be a meshed edge.
5961 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5962 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5963 NodeStart: the start node from Path. Defines the direction of extrusion
5964 HasAngles: not used obsolete
5965 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5966 around *basePoint*, additionally to previous steps.
5967 LinearVariation: forces the computation of rotation angles as linear
5968 variation of the given Angles along path steps
5969 HasRefPoint: allows using the reference point
5970 RefPoint: the reference point around which the elements are rotated (the mass
5971 center of the elements by default).
5972 The User can specify any point as the Reference Point.
5973 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5974 MakeGroups: forces the generation of new groups from existing ones
5975 ElemType: type of elements for extrusion (if param Base is a mesh)
5978 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5979 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5980 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5982 Example: :ref:`tui_extrusion_along_path`
5986 if ElemType == SMESH.NODE: n = Base
5987 if ElemType == SMESH.EDGE: e = Base
5988 if ElemType == SMESH.FACE: f = Base
5989 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5990 HasAngles, Angles, LinearVariation,
5991 HasRefPoint, RefPoint, MakeGroups)
5992 if MakeGroups: return gr,er
5995 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5996 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5997 MakeGroups=False, LinearVariation=False):
5999 Generate new elements by extrusion of the given elements.
6000 The path of extrusion must be a meshed edge.
6003 IDsOfElements: ids of elements
6004 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
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>`
6021 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6022 Example: :ref:`tui_extrusion_along_path`
6025 if not IDsOfElements:
6026 IDsOfElements = [ self.GetMesh() ]
6027 n,e,f = [],IDsOfElements,IDsOfElements
6028 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
6029 NodeStart, HasAngles, Angles,
6031 HasRefPoint, RefPoint, MakeGroups)
6032 if MakeGroups: return gr,er
6035 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
6036 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6037 MakeGroups=False, LinearVariation=False):
6039 Generate new elements by extrusion of the elements which belong to the object.
6040 The path of extrusion must be a meshed edge.
6043 theObject: the object whose elements should be processed.
6044 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6045 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6046 PathShape: shape (edge) defines the sub-mesh for the path
6047 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6048 HasAngles: not used obsolete
6049 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6050 around *basePoint*, additionally to previous steps.
6051 HasRefPoint: allows using the reference point
6052 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6053 The User can specify any point as the Reference Point.
6054 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6055 MakeGroups: forces the generation of new groups from existing ones
6056 LinearVariation: forces the computation of rotation angles as linear
6057 variation of the given Angles along path steps
6060 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6061 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6062 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6063 Example: :ref:`tui_extrusion_along_path`
6066 n,e,f = [],theObject,theObject
6067 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6068 HasAngles, Angles, LinearVariation,
6069 HasRefPoint, RefPoint, MakeGroups)
6070 if MakeGroups: return gr,er
6073 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
6074 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6075 MakeGroups=False, LinearVariation=False):
6077 Generate new elements by extrusion of mesh segments which belong to the object.
6078 The path of extrusion must be a meshed edge.
6081 theObject: the object whose 1D elements should be processed.
6082 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6083 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6084 PathShape: shape (edge) defines the sub-mesh for the path
6085 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6086 HasAngles: not used obsolete
6087 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6088 around *basePoint*, additionally to previous steps.
6089 HasRefPoint: allows using the reference point
6090 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6091 The User can specify any point as the Reference Point.
6092 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6093 MakeGroups: forces the generation of new groups from existing ones
6094 LinearVariation: forces the computation of rotation angles as linear
6095 variation of the given Angles along path steps
6098 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6099 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6100 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6101 Example: :ref:`tui_extrusion_along_path`
6104 n,e,f = [],theObject,[]
6105 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6106 HasAngles, Angles, LinearVariation,
6107 HasRefPoint, RefPoint, MakeGroups)
6108 if MakeGroups: return gr,er
6111 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6112 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6113 MakeGroups=False, LinearVariation=False):
6115 Generate new elements by extrusion of faces which belong to the object.
6116 The path of extrusion must be a meshed edge.
6119 theObject: the object whose 2D elements should be processed.
6120 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6121 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6122 PathShape: shape (edge) defines the sub-mesh for the path
6123 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6124 HasAngles: not used obsolete
6125 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6126 around *basePoint*, additionally to previous steps.
6127 HasRefPoint: allows using the reference point
6128 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6129 The User can specify any point as the Reference Point.
6130 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6131 MakeGroups: forces the generation of new groups from existing ones
6132 LinearVariation: forces the computation of rotation angles as linear
6133 variation of the given Angles along path steps
6136 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6137 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6138 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6139 Example: :ref:`tui_extrusion_along_path`
6142 n,e,f = [],[],theObject
6143 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6144 HasAngles, Angles, LinearVariation,
6145 HasRefPoint, RefPoint, MakeGroups)
6146 if MakeGroups: return gr,er
6149 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6151 Create a symmetrical copy of mesh elements
6154 IDsOfElements: list of elements ids
6155 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6156 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6157 If the *Mirror* is a geom object this parameter is unnecessary
6158 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6159 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6162 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6165 if IDsOfElements == []:
6166 IDsOfElements = self.GetElementsId()
6167 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6168 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6169 theMirrorType = Mirror._mirrorType
6171 self.mesh.SetParameters(Mirror.parameters)
6172 if Copy and MakeGroups:
6173 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6174 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6177 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6179 Create a new mesh by a symmetrical copy of mesh elements
6182 IDsOfElements: the list of elements ids
6183 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6184 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6185 If the *Mirror* is a geom object this parameter is unnecessary
6186 MakeGroups: to generate new groups from existing ones
6187 NewMeshName: a name of the new mesh to create
6190 instance of class :class:`Mesh`
6193 if IDsOfElements == []:
6194 IDsOfElements = self.GetElementsId()
6195 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6196 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6197 theMirrorType = Mirror._mirrorType
6199 self.mesh.SetParameters(Mirror.parameters)
6200 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6201 MakeGroups, NewMeshName)
6202 return Mesh(self.smeshpyD,self.geompyD,mesh)
6204 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6206 Create a symmetrical copy of the object
6209 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6210 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6211 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6212 If the *Mirror* is a geom object this parameter is unnecessary
6213 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6214 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6217 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6220 if ( isinstance( theObject, Mesh )):
6221 theObject = theObject.GetMesh()
6222 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6223 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6224 theMirrorType = Mirror._mirrorType
6226 self.mesh.SetParameters(Mirror.parameters)
6227 if Copy and MakeGroups:
6228 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6229 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6232 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6234 Create a new mesh by a symmetrical copy of the object
6237 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6238 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6239 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6240 If the *Mirror* is a geom object this parameter is unnecessary
6241 MakeGroups: forces the generation of new groups from existing ones
6242 NewMeshName: the name of the new mesh to create
6245 instance of class :class:`Mesh`
6248 if ( isinstance( theObject, Mesh )):
6249 theObject = theObject.GetMesh()
6250 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6251 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6252 theMirrorType = Mirror._mirrorType
6254 self.mesh.SetParameters(Mirror.parameters)
6255 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6256 MakeGroups, NewMeshName)
6257 return Mesh( self.smeshpyD,self.geompyD,mesh )
6259 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6261 Translate the elements
6264 IDsOfElements: list of elements ids
6265 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6266 Copy: allows copying the translated elements
6267 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6270 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6273 if IDsOfElements == []:
6274 IDsOfElements = self.GetElementsId()
6275 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6276 Vector = self.smeshpyD.GetDirStruct(Vector)
6277 if isinstance( Vector, list ):
6278 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6279 self.mesh.SetParameters(Vector.PS.parameters)
6280 if Copy and MakeGroups:
6281 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6282 self.editor.Translate(IDsOfElements, Vector, Copy)
6285 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6287 Create a new mesh of translated elements
6290 IDsOfElements: list of elements ids
6291 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6292 MakeGroups: forces the generation of new groups from existing ones
6293 NewMeshName: the name of the newly created mesh
6296 instance of class :class:`Mesh`
6299 if IDsOfElements == []:
6300 IDsOfElements = self.GetElementsId()
6301 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6302 Vector = self.smeshpyD.GetDirStruct(Vector)
6303 if isinstance( Vector, list ):
6304 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6305 self.mesh.SetParameters(Vector.PS.parameters)
6306 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6307 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6309 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6311 Translate the object
6314 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6315 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6316 Copy: allows copying the translated elements
6317 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6320 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6323 if ( isinstance( theObject, Mesh )):
6324 theObject = theObject.GetMesh()
6325 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6326 Vector = self.smeshpyD.GetDirStruct(Vector)
6327 if isinstance( Vector, list ):
6328 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6329 self.mesh.SetParameters(Vector.PS.parameters)
6330 if Copy and MakeGroups:
6331 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6332 self.editor.TranslateObject(theObject, Vector, Copy)
6335 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6337 Create a new mesh from the translated object
6340 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6341 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6342 MakeGroups: forces the generation of new groups from existing ones
6343 NewMeshName: the name of the newly created mesh
6346 instance of class :class:`Mesh`
6349 if isinstance( theObject, Mesh ):
6350 theObject = theObject.GetMesh()
6351 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6352 Vector = self.smeshpyD.GetDirStruct(Vector)
6353 if isinstance( Vector, list ):
6354 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6355 self.mesh.SetParameters(Vector.PS.parameters)
6356 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6357 return Mesh( self.smeshpyD, self.geompyD, mesh )
6361 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6366 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6367 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6368 theScaleFact: list of 1-3 scale factors for axises
6369 Copy: allows copying the translated elements
6370 MakeGroups: forces the generation of new groups from existing
6374 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6375 empty list otherwise
6377 unRegister = genObjUnRegister()
6378 if ( isinstance( theObject, Mesh )):
6379 theObject = theObject.GetMesh()
6380 if ( isinstance( theObject, list )):
6381 theObject = self.GetIDSource(theObject, SMESH.ALL)
6382 unRegister.set( theObject )
6383 if ( isinstance( thePoint, list )):
6384 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6385 if ( isinstance( theScaleFact, float )):
6386 theScaleFact = [theScaleFact]
6387 if ( isinstance( theScaleFact, int )):
6388 theScaleFact = [ float(theScaleFact)]
6390 self.mesh.SetParameters(thePoint.parameters)
6392 if Copy and MakeGroups:
6393 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6394 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6397 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6399 Create a new mesh from the translated object
6402 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6403 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6404 theScaleFact: list of 1-3 scale factors for axises
6405 MakeGroups: forces the generation of new groups from existing ones
6406 NewMeshName: the name of the newly created mesh
6409 instance of class :class:`Mesh`
6411 unRegister = genObjUnRegister()
6412 if (isinstance(theObject, Mesh)):
6413 theObject = theObject.GetMesh()
6414 if ( isinstance( theObject, list )):
6415 theObject = self.GetIDSource(theObject,SMESH.ALL)
6416 unRegister.set( theObject )
6417 if ( isinstance( thePoint, list )):
6418 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6419 if ( isinstance( theScaleFact, float )):
6420 theScaleFact = [theScaleFact]
6421 if ( isinstance( theScaleFact, int )):
6422 theScaleFact = [ float(theScaleFact)]
6424 self.mesh.SetParameters(thePoint.parameters)
6425 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6426 MakeGroups, NewMeshName)
6427 return Mesh( self.smeshpyD, self.geompyD, mesh )
6431 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6436 IDsOfElements: list of elements ids
6437 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6438 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6439 Copy: allows copying the rotated elements
6440 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6443 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6447 if IDsOfElements == []:
6448 IDsOfElements = self.GetElementsId()
6449 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6450 Axis = self.smeshpyD.GetAxisStruct(Axis)
6451 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6452 Parameters = Axis.parameters + var_separator + Parameters
6453 self.mesh.SetParameters(Parameters)
6454 if Copy and MakeGroups:
6455 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6456 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6459 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6461 Create a new mesh of rotated elements
6464 IDsOfElements: list of element ids
6465 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6466 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6467 MakeGroups: forces the generation of new groups from existing ones
6468 NewMeshName: the name of the newly created mesh
6471 instance of class :class:`Mesh`
6474 if IDsOfElements == []:
6475 IDsOfElements = self.GetElementsId()
6476 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6477 Axis = self.smeshpyD.GetAxisStruct(Axis)
6478 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6479 Parameters = Axis.parameters + var_separator + Parameters
6480 self.mesh.SetParameters(Parameters)
6481 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6482 MakeGroups, NewMeshName)
6483 return Mesh( self.smeshpyD, self.geompyD, mesh )
6485 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6490 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6491 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6492 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6493 Copy: allows copying the rotated elements
6494 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6497 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6500 if (isinstance(theObject, Mesh)):
6501 theObject = theObject.GetMesh()
6502 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6503 Axis = self.smeshpyD.GetAxisStruct(Axis)
6504 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6505 Parameters = Axis.parameters + ":" + Parameters
6506 self.mesh.SetParameters(Parameters)
6507 if Copy and MakeGroups:
6508 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6509 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6512 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6514 Create a new mesh from the rotated object
6517 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6518 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6519 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6520 MakeGroups: forces the generation of new groups from existing ones
6521 NewMeshName: the name of the newly created mesh
6524 instance of class :class:`Mesh`
6527 if (isinstance( theObject, Mesh )):
6528 theObject = theObject.GetMesh()
6529 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6530 Axis = self.smeshpyD.GetAxisStruct(Axis)
6531 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6532 Parameters = Axis.parameters + ":" + Parameters
6533 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6534 MakeGroups, NewMeshName)
6535 self.mesh.SetParameters(Parameters)
6536 return Mesh( self.smeshpyD, self.geompyD, mesh )
6538 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6540 Create an offset mesh from the given 2D object
6543 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6544 theValue (float): signed offset size
6545 MakeGroups (boolean): forces the generation of new groups from existing ones
6546 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6547 False means to remove original elements.
6548 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6551 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6554 if isinstance( theObject, Mesh ):
6555 theObject = theObject.GetMesh()
6556 theValue,Parameters,hasVars = ParseParameters(Value)
6557 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6558 self.mesh.SetParameters(Parameters)
6560 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6563 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6565 Find groups of adjacent nodes within Tolerance.
6568 Tolerance (float): the value of tolerance
6569 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6570 corner and medium nodes in separate groups thus preventing
6571 their further merge.
6574 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6577 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6579 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6580 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6582 Find groups of adjacent nodes within Tolerance.
6585 Tolerance: the value of tolerance
6586 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6587 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6588 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6589 corner and medium nodes in separate groups thus preventing
6590 their further merge.
6593 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6596 unRegister = genObjUnRegister()
6597 if not isinstance( SubMeshOrGroup, list ):
6598 SubMeshOrGroup = [ SubMeshOrGroup ]
6599 for i,obj in enumerate( SubMeshOrGroup ):
6600 if isinstance( obj, Mesh ):
6601 SubMeshOrGroup = [ obj.GetMesh() ]
6603 if isinstance( obj, int ):
6604 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6605 unRegister.set( SubMeshOrGroup )
6608 if not isinstance( exceptNodes, list ):
6609 exceptNodes = [ exceptNodes ]
6610 if exceptNodes and isinstance( exceptNodes[0], int ):
6611 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6612 unRegister.set( exceptNodes )
6614 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6615 exceptNodes, SeparateCornerAndMediumNodes)
6617 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6622 GroupsOfNodes: a list of groups of nodes IDs for merging.
6623 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6624 in all elements and mesh groups by nodes 1 and 25 correspondingly
6625 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6626 If *NodesToKeep* does not include a node to keep for some group to merge,
6627 then the first node in the group is kept.
6628 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6632 This operation can create gaps in numeration of nodes or elements.
6633 Call :meth:`RenumberElements` to remove the gaps.
6635 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6637 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6639 Find the elements built on the same nodes.
6642 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6643 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6647 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6650 unRegister = genObjUnRegister()
6651 if MeshOrSubMeshOrGroup is None:
6652 MeshOrSubMeshOrGroup = [ self.mesh ]
6653 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6654 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6655 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6656 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6657 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6658 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6659 unRegister.set( MeshOrSubMeshOrGroup )
6660 for item in MeshOrSubMeshOrGroup:
6661 if isinstance( item, Mesh ):
6662 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6664 if not isinstance( exceptElements, list ):
6665 exceptElements = [ exceptElements ]
6666 if exceptElements and isinstance( exceptElements[0], int ):
6667 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6668 unRegister.set( exceptElements )
6670 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6672 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6674 Merge elements in each given group.
6677 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6678 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6679 replaced in all mesh groups by elements 1 and 25)
6680 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6681 If *ElementsToKeep* does not include an element to keep for some group to merge,
6682 then the first element in the group is kept.
6685 This operation can create gaps in numeration of elements.
6686 Call :meth:`RenumberElements` to remove the gaps.
6689 unRegister = genObjUnRegister()
6691 if not isinstance( ElementsToKeep, list ):
6692 ElementsToKeep = [ ElementsToKeep ]
6693 if isinstance( ElementsToKeep[0], int ):
6694 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6695 unRegister.set( ElementsToKeep )
6697 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6699 def MergeEqualElements(self):
6701 Leave one element and remove all other elements built on the same nodes.
6704 This operation can create gaps in numeration of elements.
6705 Call :meth:`RenumberElements` to remove the gaps.
6708 self.editor.MergeEqualElements()
6710 def FindFreeBorders(self, ClosedOnly=True):
6712 Returns all or only closed free borders
6715 list of SMESH.FreeBorder's
6718 return self.editor.FindFreeBorders( ClosedOnly )
6720 def FillHole(self, holeNodes, groupName=""):
6722 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6725 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6726 must describe all sequential nodes of the hole border. The first and the last
6727 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6728 groupName (string): name of a group to add new faces
6730 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6734 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6735 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6736 if not isinstance( holeNodes, SMESH.FreeBorder ):
6737 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6738 return self.editor.FillHole( holeNodes, groupName )
6740 def FindCoincidentFreeBorders (self, tolerance=0.):
6742 Return groups of FreeBorder's coincident within the given tolerance.
6745 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6746 size of elements adjacent to free borders being compared is used.
6749 SMESH.CoincidentFreeBorders structure
6752 return self.editor.FindCoincidentFreeBorders( tolerance )
6754 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6756 Sew FreeBorder's of each group
6759 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6760 where each enclosed list contains node IDs of a group of coincident free
6761 borders such that each consequent triple of IDs within a group describes
6762 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6763 last node of a border.
6764 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6765 groups of coincident free borders, each group including two borders.
6766 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6767 polygons if a node of opposite border falls on a face edge, else such
6768 faces are split into several ones.
6769 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6770 polyhedra if a node of opposite border falls on a volume edge, else such
6771 volumes, if any, remain intact and the mesh becomes non-conformal.
6774 a number of successfully sewed groups
6777 This operation can create gaps in numeration of nodes or elements.
6778 Call :meth:`RenumberElements` to remove the gaps.
6781 if freeBorders and isinstance( freeBorders, list ):
6782 # construct SMESH.CoincidentFreeBorders
6783 if isinstance( freeBorders[0], int ):
6784 freeBorders = [freeBorders]
6786 coincidentGroups = []
6787 for nodeList in freeBorders:
6788 if not nodeList or len( nodeList ) % 3:
6789 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6792 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6793 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6794 nodeList = nodeList[3:]
6796 coincidentGroups.append( group )
6798 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6800 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6802 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6803 FirstNodeID2, SecondNodeID2, LastNodeID2,
6804 CreatePolygons, CreatePolyedrs):
6809 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6812 This operation can create gaps in numeration of nodes or elements.
6813 Call :meth:`RenumberElements` to remove the gaps.
6816 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6817 FirstNodeID2, SecondNodeID2, LastNodeID2,
6818 CreatePolygons, CreatePolyedrs)
6820 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6821 FirstNodeID2, SecondNodeID2):
6823 Sew conform free borders
6826 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6829 This operation can create gaps in numeration of elements.
6830 Call :meth:`RenumberElements` to remove the gaps.
6833 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6834 FirstNodeID2, SecondNodeID2)
6836 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6837 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6842 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6845 This operation can create gaps in numeration of elements.
6846 Call :meth:`RenumberElements` to remove the gaps.
6849 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6850 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6852 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6853 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6854 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6856 Sew two sides of a mesh. The nodes belonging to Side1 are
6857 merged with the nodes of elements of Side2.
6858 The number of elements in theSide1 and in theSide2 must be
6859 equal and they should have similar nodal connectivity.
6860 The nodes to merge should belong to side borders and
6861 the first node should be linked to the second.
6864 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6867 This operation can create gaps in numeration of nodes.
6868 Call :meth:`RenumberElements` to remove the gaps.
6871 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6872 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6873 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6875 def ChangeElemNodes(self, ide, newIDs):
6877 Set new nodes for the given element. Number of nodes should be kept.
6884 False if the number of nodes does not correspond to the type of element
6887 return self.editor.ChangeElemNodes(ide, newIDs)
6889 def GetLastCreatedNodes(self):
6891 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6892 created, this method return the list of their IDs.
6893 If new nodes were not created - return empty list
6896 the list of integer values (can be empty)
6899 return self.editor.GetLastCreatedNodes()
6901 def GetLastCreatedElems(self):
6903 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6904 created this method return the list of their IDs.
6905 If new elements were not created - return empty list
6908 the list of integer values (can be empty)
6911 return self.editor.GetLastCreatedElems()
6913 def ClearLastCreated(self):
6915 Forget what nodes and elements were created by the last mesh edition operation
6918 self.editor.ClearLastCreated()
6920 def DoubleElements(self, theElements, theGroupName=""):
6922 Create duplicates of given elements, i.e. create new elements based on the
6923 same nodes as the given ones.
6926 theElements: container of elements to duplicate. It can be a
6927 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6928 or a list of element IDs. If *theElements* is
6929 a :class:`Mesh`, elements of highest dimension are duplicated
6930 theGroupName: a name of group to contain the generated elements.
6931 If a group with such a name already exists, the new elements
6932 are added to the existing group, else a new group is created.
6933 If *theGroupName* is empty, new elements are not added
6937 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6938 None if *theGroupName* == "".
6941 unRegister = genObjUnRegister()
6942 if isinstance( theElements, Mesh ):
6943 theElements = theElements.mesh
6944 elif isinstance( theElements, list ):
6945 theElements = self.GetIDSource( theElements, SMESH.ALL )
6946 unRegister.set( theElements )
6947 return self.editor.DoubleElements(theElements, theGroupName)
6949 def DoubleNodes(self, theNodes, theModifiedElems):
6951 Create a hole in a mesh by doubling the nodes of some particular elements
6954 theNodes: IDs of nodes to be doubled
6955 theModifiedElems: IDs of elements to be updated by the new (doubled)
6956 nodes. If list of element identifiers is empty then nodes are doubled but
6957 they not assigned to elements
6960 True if operation has been completed successfully, False otherwise
6963 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6965 def DoubleNode(self, theNodeId, theModifiedElems):
6967 Create a hole in a mesh by doubling the nodes of some particular elements.
6968 This method provided for convenience works as :meth:`DoubleNodes`.
6971 theNodeId: IDs of node to double
6972 theModifiedElems: IDs of elements to update
6975 True if operation has been completed successfully, False otherwise
6978 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6980 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6982 Create a hole in a mesh by doubling the nodes of some particular elements.
6983 This method provided for convenience works as :meth:`DoubleNodes`.
6986 theNodes: group of nodes to double.
6987 theModifiedElems: group of elements to update.
6988 theMakeGroup: forces the generation of a group containing new nodes.
6991 True or a created group if operation has been completed successfully,
6992 False or None otherwise
6996 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6997 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6999 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
7001 Create a hole in a mesh by doubling the nodes of some particular elements.
7002 This method provided for convenience works as :meth:`DoubleNodes`.
7005 theNodes: list of groups of nodes to double.
7006 theModifiedElems: list of groups of elements to update.
7007 theMakeGroup: forces the generation of a group containing new nodes.
7010 True if operation has been completed successfully, False otherwise
7014 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
7015 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
7017 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
7019 Create a hole in a mesh by doubling the nodes of some particular elements
7022 theElems: the list of elements (edges or faces) to replicate.
7023 The nodes for duplication could be found from these elements
7024 theNodesNot: list of nodes NOT to replicate
7025 theAffectedElems: the list of elements (cells and edges) to which the
7026 replicated nodes should be associated to
7029 True if operation has been completed successfully, False otherwise
7032 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
7034 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
7036 Create a hole in a mesh by doubling the nodes of some particular elements
7039 theElems: the list of elements (edges or faces) to replicate.
7040 The nodes for duplication could be found from these elements
7041 theNodesNot: list of nodes NOT to replicate
7042 theShape: shape to detect affected elements (element which geometric center
7043 located on or inside shape).
7044 The replicated nodes should be associated to affected elements.
7047 True if operation has been completed successfully, False otherwise
7050 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
7052 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
7053 theMakeGroup=False, theMakeNodeGroup=False):
7055 Create a hole in a mesh by doubling the nodes of some particular elements.
7056 This method provided for convenience works as :meth:`DoubleNodes`.
7059 theElems: group of of elements (edges or faces) to replicate.
7060 theNodesNot: group of nodes NOT to replicate.
7061 theAffectedElems: group of elements to which the replicated nodes
7062 should be associated to.
7063 theMakeGroup: forces the generation of a group containing new elements.
7064 theMakeNodeGroup: forces the generation of a group containing new nodes.
7067 True or created groups (one or two) if operation has been completed successfully,
7068 False or None otherwise
7071 if theMakeGroup or theMakeNodeGroup:
7072 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
7074 theMakeGroup, theMakeNodeGroup)
7075 if theMakeGroup and theMakeNodeGroup:
7078 return twoGroups[ int(theMakeNodeGroup) ]
7079 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7081 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7083 Create a hole in a mesh by doubling the nodes of some particular elements.
7084 This method provided for convenience works as :meth:`DoubleNodes`.
7087 theElems: group of of elements (edges or faces) to replicate
7088 theNodesNot: group of nodes not to replicate
7089 theShape: shape to detect affected elements (element which geometric center
7090 located on or inside shape).
7091 The replicated nodes should be associated to affected elements
7094 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7096 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7097 theMakeGroup=False, theMakeNodeGroup=False):
7099 Create a hole in a mesh by doubling the nodes of some particular elements.
7100 This method provided for convenience works as :meth:`DoubleNodes`.
7103 theElems: list of groups of elements (edges or faces) to replicate
7104 theNodesNot: list of groups of nodes NOT to replicate
7105 theAffectedElems: group of elements to which the replicated nodes
7106 should be associated to
7107 theMakeGroup: forces generation of a group containing new elements.
7108 theMakeNodeGroup: forces generation of a group containing new nodes
7111 True or created groups (one or two) if operation has been completed successfully,
7112 False or None otherwise
7115 if theMakeGroup or theMakeNodeGroup:
7116 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7118 theMakeGroup, theMakeNodeGroup)
7119 if theMakeGroup and theMakeNodeGroup:
7122 return twoGroups[ int(theMakeNodeGroup) ]
7123 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7125 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7127 Create a hole in a mesh by doubling the nodes of some particular elements.
7128 This method provided for convenience works as :meth:`DoubleNodes`.
7131 theElems: list of groups of elements (edges or faces) to replicate
7132 theNodesNot: list of groups of nodes NOT to replicate
7133 theShape: shape to detect affected elements (element which geometric center
7134 located on or inside shape).
7135 The replicated nodes should be associated to affected elements
7138 True if operation has been completed successfully, False otherwise
7141 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7143 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7145 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7146 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7149 theElems: list of groups of nodes or elements (edges or faces) to replicate
7150 theNodesNot: list of groups of nodes NOT to replicate
7151 theShape: shape to detect affected elements (element which geometric center
7152 located on or inside shape).
7153 The replicated nodes should be associated to affected elements
7156 groups of affected elements in order: volumes, faces, edges
7159 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7161 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7164 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7165 The list of groups must describe a partition of the mesh volumes.
7166 The nodes of the internal faces at the boundaries of the groups are doubled.
7167 In option, the internal faces are replaced by flat elements.
7168 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7171 theDomains: list of groups of volumes
7172 createJointElems: if True, create the elements
7173 onAllBoundaries: if True, the nodes and elements are also created on
7174 the boundary between *theDomains* and the rest mesh
7177 True if operation has been completed successfully, False otherwise
7180 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7182 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7184 Double nodes on some external faces and create flat elements.
7185 Flat elements are mainly used by some types of mechanic calculations.
7187 Each group of the list must be constituted of faces.
7188 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7191 theGroupsOfFaces: list of groups of faces
7194 True if operation has been completed successfully, False otherwise
7197 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7199 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7201 Identify all the elements around a geom shape, get the faces delimiting the hole
7203 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7205 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7207 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7208 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7209 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7210 If there are several paths connecting a pair of points, the shortest path is
7211 selected by the module. Position of the cutting plane is defined by the two
7212 points and an optional vector lying on the plane specified by a PolySegment.
7213 By default the vector is defined by Mesh module as following. A middle point
7214 of the two given points is computed. The middle point is projected to the mesh.
7215 The vector goes from the middle point to the projection point. In case of planar
7216 mesh, the vector is normal to the mesh.
7218 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7221 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7222 groupName: optional name of a group where created mesh segments will be added.
7225 editor = self.editor
7227 editor = self.mesh.GetMeshEditPreviewer()
7228 segmentsRes = editor.MakePolyLine( segments, groupName )
7229 for i, seg in enumerate( segmentsRes ):
7230 segments[i].vector = seg.vector
7232 return editor.GetPreviewData()
7235 def MakeSlot(self, segmentGroup, width ):
7237 Create a slot of given width around given 1D elements lying on a triangle mesh.
7238 The slot is constructed by cutting faces by cylindrical surfaces made
7239 around each segment. Segments are expected to be created by MakePolyLine().
7242 FaceEdge's located at the slot boundary
7244 return self.editor.MakeSlot( segmentGroup, width )
7246 def GetFunctor(self, funcType ):
7248 Return a cached numerical functor by its type.
7251 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7252 Note that not all items correspond to numerical functors.
7255 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7258 fn = self.functors[ funcType._v ]
7260 fn = self.smeshpyD.GetFunctor(funcType)
7261 fn.SetMesh(self.mesh)
7262 self.functors[ funcType._v ] = fn
7265 def FunctorValue(self, funcType, elemId, isElem=True):
7267 Return value of a functor for a given element
7270 funcType: an item of :class:`SMESH.FunctorType` enum.
7271 elemId: element or node ID
7272 isElem: *elemId* is ID of element or node
7275 the functor value or zero in case of invalid arguments
7278 fn = self.GetFunctor( funcType )
7279 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7280 val = fn.GetValue(elemId)
7285 def GetLength(self, elemId=None):
7287 Get length of given 1D elements or of all 1D mesh elements
7290 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.
7293 Sum of lengths of given elements
7298 length = self.smeshpyD.GetLength(self)
7299 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7300 length = self.smeshpyD.GetLength(elemId)
7303 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7305 length += self.smeshpyD.GetLength(obj)
7306 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7307 unRegister = genObjUnRegister()
7308 obj = self.GetIDSource( elemId )
7309 unRegister.set( obj )
7310 length = self.smeshpyD.GetLength( obj )
7312 length = self.FunctorValue(SMESH.FT_Length, elemId)
7315 def GetArea(self, elemId=None):
7317 Get area of given 2D elements or of all 2D mesh elements
7320 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.
7323 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7328 area = self.smeshpyD.GetArea(self)
7329 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7330 area = self.smeshpyD.GetArea(elemId)
7333 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7335 area += self.smeshpyD.GetArea(obj)
7336 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7337 unRegister = genObjUnRegister()
7338 obj = self.GetIDSource( elemId )
7339 unRegister.set( obj )
7340 area = self.smeshpyD.GetArea( obj )
7342 area = self.FunctorValue(SMESH.FT_Area, elemId)
7345 def GetVolume(self, elemId=None):
7347 Get volume of given 3D elements or of all 3D mesh elements
7350 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.
7353 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7358 volume= self.smeshpyD.GetVolume(self)
7359 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7360 volume= self.smeshpyD.GetVolume(elemId)
7363 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7365 volume+= self.smeshpyD.GetVolume(obj)
7366 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7367 unRegister = genObjUnRegister()
7368 obj = self.GetIDSource( elemId )
7369 unRegister.set( obj )
7370 volume= self.smeshpyD.GetVolume( obj )
7372 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7375 def GetAngle(self, node1, node2, node3 ):
7377 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7380 node1,node2,node3: IDs of the three nodes
7383 Angle in radians [0,PI]. -1 if failure case.
7385 p1 = self.GetNodeXYZ( node1 )
7386 p2 = self.GetNodeXYZ( node2 )
7387 p3 = self.GetNodeXYZ( node3 )
7388 if p1 and p2 and p3:
7389 return self.smeshpyD.GetAngle( p1,p2,p3 )
7393 def GetMaxElementLength(self, elemId):
7395 Get maximum element length.
7398 elemId: mesh element ID
7401 element's maximum length value
7404 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7405 ftype = SMESH.FT_MaxElementLength3D
7407 ftype = SMESH.FT_MaxElementLength2D
7408 return self.FunctorValue(ftype, elemId)
7410 def GetAspectRatio(self, elemId):
7412 Get aspect ratio of 2D or 3D element.
7415 elemId: mesh element ID
7418 element's aspect ratio value
7421 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7422 ftype = SMESH.FT_AspectRatio3D
7424 ftype = SMESH.FT_AspectRatio
7425 return self.FunctorValue(ftype, elemId)
7427 def GetWarping(self, elemId):
7429 Get warping angle of 2D element.
7432 elemId: mesh element ID
7435 element's warping angle value
7438 return self.FunctorValue(SMESH.FT_Warping, elemId)
7440 def GetMinimumAngle(self, elemId):
7442 Get minimum angle of 2D element.
7445 elemId: mesh element ID
7448 element's minimum angle value
7451 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7453 def GetTaper(self, elemId):
7455 Get taper of 2D element.
7458 elemId: mesh element ID
7461 element's taper value
7464 return self.FunctorValue(SMESH.FT_Taper, elemId)
7466 def GetSkew(self, elemId):
7468 Get skew of 2D element.
7471 elemId: mesh element ID
7474 element's skew value
7477 return self.FunctorValue(SMESH.FT_Skew, elemId)
7479 def GetMinMax(self, funType, meshPart=None):
7481 Return minimal and maximal value of a given functor.
7484 funType (SMESH.FunctorType): a functor type.
7485 Note that not all items of :class:`SMESH.FunctorType` corresponds
7486 to numerical functors.
7487 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7493 unRegister = genObjUnRegister()
7494 if isinstance( meshPart, list ):
7495 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7496 unRegister.set( meshPart )
7497 if isinstance( meshPart, Mesh ):
7498 meshPart = meshPart.mesh
7499 fun = self.GetFunctor( funType )
7502 if hasattr( meshPart, "SetMesh" ):
7503 meshPart.SetMesh( self.mesh ) # set mesh to filter
7504 hist = fun.GetLocalHistogram( 1, False, meshPart )
7506 hist = fun.GetHistogram( 1, False )
7508 return hist[0].min, hist[0].max
7511 pass # end of Mesh class
7514 class meshProxy(SMESH._objref_SMESH_Mesh):
7516 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7517 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7519 def __init__(self,*args):
7520 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7521 def __deepcopy__(self, memo=None):
7522 new = self.__class__(self)
7524 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7525 if len( args ) == 3:
7526 args += SMESH.ALL_NODES, True
7527 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7528 def ExportToMEDX(self, *args): # function removed
7529 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7530 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7531 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7532 def ExportToMED(self, *args): # function removed
7533 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7534 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7536 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7538 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7539 def ExportPartToMED(self, *args): # 'version' parameter removed
7540 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7541 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7542 def ExportMED(self, *args): # signature of method changed
7543 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7545 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7547 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7548 def ExportUNV(self, *args): # renumber arg added
7549 if len( args ) == 1:
7551 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
7552 def ExportDAT(self, *args): # renumber arg added
7553 if len( args ) == 1:
7555 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
7557 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7560 class submeshProxy(SMESH._objref_SMESH_subMesh):
7563 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7565 def __init__(self,*args):
7566 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7568 def __deepcopy__(self, memo=None):
7569 new = self.__class__(self)
7572 def Compute(self,refresh=False):
7574 Compute the sub-mesh and return the status of the computation
7577 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7582 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7583 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7587 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7589 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7591 if salome.sg.hasDesktop():
7592 if refresh: salome.sg.updateObjBrowser()
7597 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7600 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7602 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7603 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7606 def __init__(self,*args):
7607 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7609 def __getattr__(self, name ): # method called if an attribute not found
7610 if not self.mesh: # look for name() method in Mesh class
7611 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7612 if hasattr( self.mesh, name ):
7613 return getattr( self.mesh, name )
7614 if name == "ExtrusionAlongPathObjX":
7615 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7616 print("meshEditor: attribute '%s' NOT FOUND" % name)
7618 def __deepcopy__(self, memo=None):
7619 new = self.__class__(self)
7621 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7622 if len( args ) == 1: args += False,
7623 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7624 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7625 if len( args ) == 2: args += False,
7626 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7627 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7628 if len( args ) == 1:
7629 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7630 NodesToKeep = args[1]
7631 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7632 unRegister = genObjUnRegister()
7634 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7635 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7636 if not isinstance( NodesToKeep, list ):
7637 NodesToKeep = [ NodesToKeep ]
7638 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7640 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7642 class Pattern(SMESH._objref_SMESH_Pattern):
7644 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7645 variables in some methods
7648 def LoadFromFile(self, patternTextOrFile ):
7649 text = patternTextOrFile
7650 if os.path.exists( text ):
7651 text = open( patternTextOrFile ).read()
7653 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7655 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7656 decrFun = lambda i: i-1
7657 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7658 theMesh.SetParameters(Parameters)
7659 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7661 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7662 decrFun = lambda i: i-1
7663 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7664 theMesh.SetParameters(Parameters)
7665 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7667 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7668 if isinstance( mesh, Mesh ):
7669 mesh = mesh.GetMesh()
7670 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7672 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7674 Registering the new proxy for Pattern
7679 Private class used to bind methods creating algorithms to the class Mesh
7682 def __init__(self, method):
7684 self.defaultAlgoType = ""
7685 self.algoTypeToClass = {}
7686 self.method = method
7688 def add(self, algoClass):
7690 Store a python class of algorithm
7692 if inspect.isclass(algoClass) and \
7693 hasattr( algoClass, "algoType"):
7694 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7695 if not self.defaultAlgoType and \
7696 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7697 self.defaultAlgoType = algoClass.algoType
7698 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7700 def copy(self, mesh):
7702 Create a copy of self and assign mesh to the copy
7705 other = algoCreator( self.method )
7706 other.defaultAlgoType = self.defaultAlgoType
7707 other.algoTypeToClass = self.algoTypeToClass
7711 def __call__(self,algo="",geom=0,*args):
7713 Create an instance of algorithm
7717 if isinstance( algo, str ):
7719 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7720 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7725 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7727 elif not algoType and isinstance( geom, str ):
7732 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7734 elif isinstance( arg, str ) and not algoType:
7737 import traceback, sys
7738 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7739 sys.stderr.write( msg + '\n' )
7740 tb = traceback.extract_stack(None,2)
7741 traceback.print_list( [tb[0]] )
7743 algoType = self.defaultAlgoType
7744 if not algoType and self.algoTypeToClass:
7745 algoType = sorted( self.algoTypeToClass.keys() )[0]
7746 if algoType in self.algoTypeToClass:
7747 #print("Create algo",algoType)
7748 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7749 raise RuntimeError( "No class found for algo type %s" % algoType)
7752 class hypMethodWrapper:
7754 Private class used to substitute and store variable parameters of hypotheses.
7757 def __init__(self, hyp, method):
7759 self.method = method
7760 #print("REBIND:", method.__name__)
7763 def __call__(self,*args):
7765 call a method of hypothesis with calling SetVarParameter() before
7769 return self.method( self.hyp, *args ) # hypothesis method with no args
7771 #print("MethWrapper.__call__", self.method.__name__, args)
7773 parsed = ParseParameters(*args) # replace variables with their values
7774 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7775 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7776 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7777 # maybe there is a replaced string arg which is not variable
7778 result = self.method( self.hyp, *args )
7779 except ValueError as detail: # raised by ParseParameters()
7781 result = self.method( self.hyp, *args )
7782 except omniORB.CORBA.BAD_PARAM:
7783 raise ValueError(detail) # wrong variable name
7788 class genObjUnRegister:
7790 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7793 def __init__(self, genObj=None):
7794 self.genObjList = []
7798 def set(self, genObj):
7799 "Store one or a list of of SALOME.GenericObj'es"
7800 if isinstance( genObj, list ):
7801 self.genObjList.extend( genObj )
7803 self.genObjList.append( genObj )
7807 for genObj in self.genObjList:
7808 if genObj and hasattr( genObj, "UnRegister" ):
7811 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7813 Bind methods creating mesher plug-ins to the Mesh class
7816 # print("pluginName: ", pluginName)
7817 pluginBuilderName = pluginName + "Builder"
7819 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7820 except Exception as e:
7821 from salome_utils import verbose
7822 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7824 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7825 plugin = eval( pluginBuilderName )
7826 # print(" plugin:" , str(plugin))
7828 # add methods creating algorithms to Mesh
7829 for k in dir( plugin ):
7830 if k[0] == '_': continue
7831 algo = getattr( plugin, k )
7832 #print(" algo:", str(algo))
7833 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7834 #print(" meshMethod:" , str(algo.meshMethod))
7835 if not hasattr( Mesh, algo.meshMethod ):
7836 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7838 _mmethod = getattr( Mesh, algo.meshMethod )
7839 if hasattr( _mmethod, "add" ):