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)
1901 nbThreads: Number of threads to use for a parallel computation
1907 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1908 geom = self.mesh.GetShapeToMesh()
1911 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1913 ok = self.smeshpyD.Compute(self.mesh, geom)
1914 except SALOME.SALOME_Exception as ex:
1915 print("Mesh computation failed, exception caught:")
1916 print(" ", ex.details.text)
1919 print("Mesh computation failed, exception caught:")
1920 traceback.print_exc()
1924 # Treat compute errors
1925 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1927 for err in computeErrors:
1928 if self.mesh.HasShapeToMesh():
1929 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1931 stdErrors = ["OK", #COMPERR_OK
1932 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1933 "std::exception", #COMPERR_STD_EXCEPTION
1934 "OCC exception", #COMPERR_OCC_EXCEPTION
1935 "..", #COMPERR_SLM_EXCEPTION
1936 "Unknown exception", #COMPERR_EXCEPTION
1937 "Memory allocation problem", #COMPERR_MEMORY_PB
1938 "Algorithm failed", #COMPERR_ALGO_FAILED
1939 "Unexpected geometry", #COMPERR_BAD_SHAPE
1940 "Warning", #COMPERR_WARNING
1941 "Computation cancelled",#COMPERR_CANCELED
1942 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1944 if err.code < len(stdErrors): errText = stdErrors[err.code]
1946 errText = "code %s" % -err.code
1947 if errText: errText += ". "
1948 errText += err.comment
1949 if allReasons: allReasons += "\n"
1951 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1953 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1957 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1959 if err.isGlobalAlgo:
1967 reason = '%s %sD algorithm is missing' % (glob, dim)
1968 elif err.state == HYP_MISSING:
1969 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1970 % (glob, dim, name, dim))
1971 elif err.state == HYP_NOTCONFORM:
1972 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1973 elif err.state == HYP_BAD_PARAMETER:
1974 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1975 % ( glob, dim, name ))
1976 elif err.state == HYP_BAD_GEOMETRY:
1977 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1978 'geometry' % ( glob, dim, name ))
1979 elif err.state == HYP_HIDDEN_ALGO:
1980 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1981 'algorithm of upper dimension generating %sD mesh'
1982 % ( glob, dim, name, glob, dim ))
1984 reason = ("For unknown reason. "
1985 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1987 if allReasons: allReasons += "\n"
1988 allReasons += "- " + reason
1990 if not ok or allReasons != "":
1991 msg = '"' + GetName(self.mesh) + '"'
1992 if ok: msg += " has been computed with warnings"
1993 else: msg += " has not been computed"
1994 if allReasons != "": msg += ":"
2000 if salome.sg.hasDesktop():
2001 if not isinstance( refresh, list): # not a call from subMesh.Compute()
2002 if refresh: salome.sg.updateObjBrowser()
2006 def GetComputeErrors(self, shape=0 ):
2008 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
2012 shape = self.mesh.GetShapeToMesh()
2013 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
2015 def GetSubShapeName(self, subShapeID ):
2017 Return a name of a sub-shape by its ID.
2018 Possible variants (for *subShapeID* == 3):
2020 - **"Face_12"** - published sub-shape
2021 - **FACE #3** - not published sub-shape
2022 - **sub-shape #3** - invalid sub-shape ID
2023 - **#3** - error in this function
2026 subShapeID: a unique ID of a sub-shape
2029 a string describing the sub-shape
2033 if not self.mesh.HasShapeToMesh():
2037 mainIOR = salome.orb.object_to_string( self.GetShape() )
2039 mainSO = s.FindObjectIOR(mainIOR)
2042 shapeText = '"%s"' % mainSO.GetName()
2043 subIt = s.NewChildIterator(mainSO)
2045 subSO = subIt.Value()
2047 obj = subSO.GetObject()
2048 if not obj: continue
2049 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2052 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2055 if ids == subShapeID:
2056 shapeText = '"%s"' % subSO.GetName()
2059 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2061 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2063 shapeText = 'sub-shape #%s' % (subShapeID)
2065 shapeText = "#%s" % (subShapeID)
2068 def GetFailedShapes(self, publish=False):
2070 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2071 error of an algorithm
2074 publish: if *True*, the returned groups will be published in the study
2077 a list of GEOM groups each named after a failed algorithm
2082 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2083 for err in computeErrors:
2084 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2085 if not shape: continue
2086 if err.algoName in algo2shapes:
2087 algo2shapes[ err.algoName ].append( shape )
2089 algo2shapes[ err.algoName ] = [ shape ]
2093 for algoName, shapes in list(algo2shapes.items()):
2095 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2096 otherTypeShapes = []
2098 group = self.geompyD.CreateGroup( self.geom, groupType )
2099 for shape in shapes:
2100 if shape.GetShapeType() == shapes[0].GetShapeType():
2101 sameTypeShapes.append( shape )
2103 otherTypeShapes.append( shape )
2104 self.geompyD.UnionList( group, sameTypeShapes )
2106 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2108 group.SetName( algoName )
2109 groups.append( group )
2110 shapes = otherTypeShapes
2113 for group in groups:
2114 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2117 def GetMeshOrder(self):
2119 Return sub-mesh objects list in meshing order
2122 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2125 return self.mesh.GetMeshOrder()
2127 def SetMeshOrder(self, submeshes):
2129 Set priority of sub-meshes. It works in two ways:
2131 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2132 *several dimensions*, it sets the order in which the sub-meshes are computed.
2133 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2134 when looking for meshing parameters to apply to a sub-shape. To impose the
2135 order in which sub-meshes with uni-dimensional algorithms are computed,
2136 call **submesh.Compute()** in a desired order.
2139 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2141 Warning: the method is for setting the order for all sub-meshes at once:
2142 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2145 return self.mesh.SetMeshOrder(submeshes)
2147 def Clear(self, refresh=False):
2149 Remove all nodes and elements generated on geometry. Imported elements remain.
2152 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2156 if ( salome.sg.hasDesktop() ):
2157 if refresh: salome.sg.updateObjBrowser()
2159 def ClearSubMesh(self, geomId, refresh=False):
2161 Remove all nodes and elements of indicated shape
2164 geomId: the ID of a sub-shape to remove elements on
2165 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2168 self.mesh.ClearSubMesh(geomId)
2169 if salome.sg.hasDesktop():
2170 if refresh: salome.sg.updateObjBrowser()
2172 def AutomaticTetrahedralization(self, fineness=0):
2174 Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron
2177 fineness: [0.0,1.0] defines mesh fineness
2183 dim = self.MeshDimension()
2185 self.RemoveGlobalHypotheses()
2186 self.Segment().AutomaticLength(fineness)
2188 self.Triangle().LengthFromEdges()
2193 return self.Compute()
2195 def AutomaticHexahedralization(self, fineness=0):
2197 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2200 fineness: [0.0, 1.0] defines mesh fineness
2206 dim = self.MeshDimension()
2207 # assign the hypotheses
2208 self.RemoveGlobalHypotheses()
2209 self.Segment().AutomaticLength(fineness)
2216 return self.Compute()
2218 def AddHypothesis(self, hyp, geom=0):
2223 hyp: a hypothesis to assign
2224 geom: a subhape of mesh geometry
2227 :class:`SMESH.Hypothesis_Status`
2230 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2231 hyp, geom = geom, hyp
2232 if isinstance( hyp, Mesh_Algorithm ):
2233 hyp = hyp.GetAlgorithm()
2238 geom = self.mesh.GetShapeToMesh()
2241 if self.mesh.HasShapeToMesh():
2242 hyp_type = hyp.GetName()
2243 lib_name = hyp.GetLibName()
2244 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2245 # if checkAll and geom:
2246 # checkAll = geom.GetType() == 37
2248 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2250 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2251 status = self.mesh.AddHypothesis(geom, hyp)
2253 status = HYP_BAD_GEOMETRY, ""
2254 hyp_name = GetName( hyp )
2257 geom_name = geom.GetName()
2258 isAlgo = hyp._narrow( SMESH_Algo )
2259 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2262 def IsUsedHypothesis(self, hyp, geom):
2264 Return True if an algorithm or hypothesis is assigned to a given shape
2267 hyp: an algorithm or hypothesis to check
2268 geom: a subhape of mesh geometry
2274 if not hyp: # or not geom
2276 if isinstance( hyp, Mesh_Algorithm ):
2277 hyp = hyp.GetAlgorithm()
2279 hyps = self.GetHypothesisList(geom)
2281 if h.GetId() == hyp.GetId():
2285 def RemoveHypothesis(self, hyp, geom=0):
2287 Unassign a hypothesis
2290 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2291 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2294 :class:`SMESH.Hypothesis_Status`
2299 if isinstance( hyp, Mesh_Algorithm ):
2300 hyp = hyp.GetAlgorithm()
2306 if self.IsUsedHypothesis( hyp, shape ):
2307 return self.mesh.RemoveHypothesis( shape, hyp )
2308 hypName = GetName( hyp )
2309 geoName = GetName( shape )
2310 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2313 def GetHypothesisList(self, geom):
2315 Get the list of hypotheses added on a geometry
2318 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2321 the sequence of :class:`SMESH.SMESH_Hypothesis`
2324 return self.mesh.GetHypothesisList( geom )
2326 def RemoveGlobalHypotheses(self):
2328 Remove all global hypotheses
2331 current_hyps = self.mesh.GetHypothesisList( self.geom )
2332 for hyp in current_hyps:
2333 self.mesh.RemoveHypothesis( self.geom, hyp )
2337 def ExportMEDCoupling(self, *args, **kwargs):
2339 Export the mesh in a memory representation.
2342 auto_groups (boolean): parameter for creating/not creating
2343 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2344 the typical use is auto_groups=False.
2345 overwrite (boolean): parameter for overwriting/not overwriting the file
2346 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2347 to export instead of the mesh
2348 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2350 - 1D if all mesh nodes lie on OX coordinate axis, or
2351 - 2D if all mesh nodes lie on XOY coordinate plane, or
2352 - 3D in the rest cases.
2354 If *autoDimension* is *False*, the space dimension is always 3.
2355 fields: list of GEOM fields defined on the shape to mesh.
2356 geomAssocFields: each character of this string means a need to export a
2357 corresponding field; correspondence between fields and characters
2360 - 'v' stands for "_vertices_" field;
2361 - 'e' stands for "_edges_" field;
2362 - 'f' stands for "_faces_" field;
2363 - 's' stands for "_solids_" field.
2365 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2366 close to zero within a given tolerance, the coordinate is set to zero.
2367 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2368 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2370 auto_groups = args[0] if len(args) > 0 else False
2371 meshPart = args[1] if len(args) > 1 else None
2372 autoDimension = args[2] if len(args) > 2 else True
2373 fields = args[3] if len(args) > 3 else []
2374 geomAssocFields = args[4] if len(args) > 4 else ''
2375 z_tolerance = args[5] if len(args) > 5 else -1.
2376 saveNumbers = args[6] if len(args) > 6 else True
2377 # process keywords arguments
2378 auto_groups = kwargs.get("auto_groups", auto_groups)
2379 meshPart = kwargs.get("meshPart", meshPart)
2380 autoDimension = kwargs.get("autoDimension", autoDimension)
2381 fields = kwargs.get("fields", fields)
2382 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2383 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2384 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2386 # invoke engine's function
2387 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2388 unRegister = genObjUnRegister()
2389 if isinstance( meshPart, list ):
2390 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2391 unRegister.set( meshPart )
2393 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2394 self.mesh.SetParameters(Parameters)
2396 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2397 fields, geomAssocFields, z_tolerance,
2400 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2401 return medcoupling.MEDFileData.New(dab)
2403 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2405 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2406 return medcoupling.MEDFileMesh.New(dab)
2408 def ExportMED(self, *args, **kwargs):
2410 Export the mesh in a file in MED format
2411 allowing to overwrite the file if it exists or add the exported data to its contents
2414 fileName: is the file name
2415 auto_groups (boolean): parameter for creating/not creating
2416 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2417 the typical use is auto_groups=False.
2418 version (int): define the version (xy, where version is x.y.z) of MED file format.
2419 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2420 The rules of compatibility to write a mesh in an older version than
2421 the current version depend on the current version. For instance,
2422 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2423 or 3.2.1 or 3.3.1 formats.
2424 If the version is equal to -1, the version is not changed (default).
2425 overwrite (boolean): parameter for overwriting/not overwriting the file
2426 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2427 to export instead of the mesh
2428 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2430 - 1D if all mesh nodes lie on OX coordinate axis, or
2431 - 2D if all mesh nodes lie on XOY coordinate plane, or
2432 - 3D in the rest cases.
2434 If *autoDimension* is *False*, the space dimension is always 3.
2435 fields: list of GEOM fields defined on the shape to mesh.
2436 geomAssocFields: each character of this string means a need to export a
2437 corresponding field; correspondence between fields and characters
2440 - 'v' stands for "_vertices_" field;
2441 - 'e' stands for "_edges_" field;
2442 - 'f' stands for "_faces_" field;
2443 - 's' stands for "_solids_" field.
2445 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2446 close to zero within a given tolerance, the coordinate is set to zero.
2447 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2448 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2450 # process positional arguments
2451 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2453 auto_groups = args[1] if len(args) > 1 else False
2454 version = args[2] if len(args) > 2 else -1
2455 overwrite = args[3] if len(args) > 3 else True
2456 meshPart = args[4] if len(args) > 4 else None
2457 autoDimension = args[5] if len(args) > 5 else True
2458 fields = args[6] if len(args) > 6 else []
2459 geomAssocFields = args[7] if len(args) > 7 else ''
2460 z_tolerance = args[8] if len(args) > 8 else -1.
2461 saveNumbers = args[9] if len(args) > 9 else True
2462 # process keywords arguments
2463 auto_groups = kwargs.get("auto_groups", auto_groups)
2464 version = kwargs.get("version", version)
2465 version = kwargs.get("minor", version)
2466 overwrite = kwargs.get("overwrite", overwrite)
2467 meshPart = kwargs.get("meshPart", meshPart)
2468 autoDimension = kwargs.get("autoDimension", autoDimension)
2469 fields = kwargs.get("fields", fields)
2470 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2471 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2472 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2474 if isinstance( meshPart, Mesh):
2475 meshPart = meshPart.GetMesh()
2477 # invoke engine's function
2478 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2479 unRegister = genObjUnRegister()
2480 if isinstance( meshPart, list ):
2481 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2482 unRegister.set( meshPart )
2484 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2485 self.mesh.SetParameters(Parameters)
2487 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2488 version, overwrite, autoDimension,
2489 fields, geomAssocFields, z_tolerance, saveNumbers )
2491 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2493 def ExportDAT(self, f, meshPart=None, renumber=True):
2495 Export the mesh in a file in DAT format
2499 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2500 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2503 if meshPart or not renumber:
2504 unRegister = genObjUnRegister()
2505 if isinstance( meshPart, list ):
2506 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2507 unRegister.set( meshPart )
2508 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2510 self.mesh.ExportDAT( f, renumber )
2512 def ExportUNV(self, f, meshPart=None, renumber=True):
2514 Export the mesh in a file in UNV format
2518 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2519 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2522 if meshPart or not renumber:
2523 unRegister = genObjUnRegister()
2524 if isinstance( meshPart, list ):
2525 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2526 unRegister.set( meshPart )
2527 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2529 self.mesh.ExportUNV( f, renumber )
2531 def ExportSTL(self, f, ascii=1, meshPart=None):
2533 Export the mesh in a file in STL format
2537 ascii: defines the file encoding
2538 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2542 unRegister = genObjUnRegister()
2543 if isinstance( meshPart, list ):
2544 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2545 unRegister.set( meshPart )
2546 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2548 self.mesh.ExportSTL(f, ascii)
2550 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2552 Export the mesh in a file in CGNS format
2556 overwrite: boolean parameter for overwriting/not overwriting the file
2557 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2558 groupElemsByType: if True all elements of same entity type are exported at ones,
2559 else elements are exported in order of their IDs which can cause creation
2560 of multiple cgns sections
2563 unRegister = genObjUnRegister()
2564 if isinstance( meshPart, list ):
2565 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2566 unRegister.set( meshPart )
2567 if isinstance( meshPart, Mesh ):
2568 meshPart = meshPart.mesh
2570 meshPart = self.mesh
2571 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2573 def ExportGMF(self, f, meshPart=None):
2575 Export the mesh in a file in GMF format.
2576 GMF files must have .mesh extension for the ASCII format and .meshb for
2577 the bynary format. Other extensions are not allowed.
2581 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2584 unRegister = genObjUnRegister()
2585 if isinstance( meshPart, list ):
2586 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2587 unRegister.set( meshPart )
2588 if isinstance( meshPart, Mesh ):
2589 meshPart = meshPart.mesh
2591 meshPart = self.mesh
2592 self.mesh.ExportGMF(meshPart, f, True)
2594 def ExportToMED(self, *args, **kwargs):
2596 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2597 Export the mesh in a file in MED format
2598 allowing to overwrite the file if it exists or add the exported data to its contents
2601 fileName: the file name
2602 opt (boolean): parameter for creating/not creating
2603 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2604 overwrite: boolean parameter for overwriting/not overwriting the file
2605 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2607 - 1D if all mesh nodes lie on OX coordinate axis, or
2608 - 2D if all mesh nodes lie on XOY coordinate plane, or
2609 - 3D in the rest cases.
2611 If **autoDimension** is *False*, the space dimension is always 3.
2614 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2615 # process positional arguments
2616 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2618 auto_groups = args[1] if len(args) > 1 else False
2619 overwrite = args[2] if len(args) > 2 else True
2620 autoDimension = args[3] if len(args) > 3 else True
2621 # process keywords arguments
2622 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2623 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2624 overwrite = kwargs.get("overwrite", overwrite)
2625 autoDimension = kwargs.get("autoDimension", autoDimension)
2627 # invoke engine's function
2628 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2630 def ExportToMEDX(self, *args, **kwargs):
2632 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2633 Export the mesh in a file in MED format
2636 fileName: the file name
2637 opt (boolean): parameter for creating/not creating
2638 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2639 overwrite: boolean parameter for overwriting/not overwriting the file
2640 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2642 - 1D if all mesh nodes lie on OX coordinate axis, or
2643 - 2D if all mesh nodes lie on XOY coordinate plane, or
2644 - 3D in the rest cases.
2646 If **autoDimension** is *False*, the space dimension is always 3.
2649 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2650 # process positional arguments
2651 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2653 auto_groups = args[1] if len(args) > 1 else False
2654 overwrite = args[2] if len(args) > 2 else True
2655 autoDimension = args[3] if len(args) > 3 else True
2656 # process keywords arguments
2657 auto_groups = kwargs.get("auto_groups", auto_groups)
2658 overwrite = kwargs.get("overwrite", overwrite)
2659 autoDimension = kwargs.get("autoDimension", autoDimension)
2661 # invoke engine's function
2662 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2666 def Append(self, meshes, uniteIdenticalGroups = True,
2667 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2669 Append given meshes into this mesh.
2670 All groups of input meshes will be created in this mesh.
2673 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2674 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2675 mergeNodesAndElements: if True, equal nodes and elements are merged
2676 mergeTolerance: tolerance for merging nodes
2677 allGroups: forces creation of groups corresponding to every input mesh
2679 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2680 mergeNodesAndElements, mergeTolerance, allGroups,
2681 meshToAppendTo = self.GetMesh() )
2683 # Operations with groups:
2684 # ----------------------
2685 def CreateEmptyGroup(self, elementType, name):
2687 Create an empty standalone mesh group
2690 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2691 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2692 name: the name of the mesh group
2695 :class:`SMESH.SMESH_Group`
2698 return self.mesh.CreateGroup(elementType, name)
2700 def Group(self, grp, name=""):
2702 Create a mesh group based on the geometric object *grp*
2703 and give it a *name*.
2704 If *name* is not defined the name of the geometric group is used
2707 Works like :meth:`GroupOnGeom`.
2710 grp: a geometric group, a vertex, an edge, a face or a solid
2711 name: the name of the mesh group
2714 :class:`SMESH.SMESH_GroupOnGeom`
2717 return self.GroupOnGeom(grp, name)
2719 def GroupOnGeom(self, grp, name="", typ=None):
2721 Create a mesh group based on the geometrical object *grp*
2722 and give it a *name*.
2723 if *name* is not defined the name of the geometric group is used
2726 grp: a geometrical group, a vertex, an edge, a face or a solid
2727 name: the name of the mesh group
2728 typ: the type of elements in the group; either of
2729 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2730 automatically detected by the type of the geometry
2733 :class:`SMESH.SMESH_GroupOnGeom`
2736 AssureGeomPublished( self, grp, name )
2738 name = grp.GetName()
2740 typ = self._groupTypeFromShape( grp )
2741 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2743 def _groupTypeFromShape( self, shape ):
2745 Pivate method to get a type of group on geometry
2747 tgeo = str(shape.GetShapeType())
2748 if tgeo == "VERTEX":
2750 elif tgeo == "EDGE" or tgeo == "WIRE":
2752 elif tgeo == "FACE" or tgeo == "SHELL":
2754 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2756 elif tgeo == "COMPOUND":
2758 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2760 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2761 # simplification of access in geomBuilder: omniORB.registerObjref
2762 from SHAPERSTUDY_utils import getEngine
2765 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2767 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2768 return self._groupTypeFromShape( sub[0] )
2770 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2773 def GroupOnFilter(self, typ, name, filter):
2775 Create a mesh group with given *name* based on the *filter*.
2776 It is a special type of group dynamically updating it's contents during
2780 typ: the type of elements in the group; either of
2781 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2782 name: the name of the mesh group
2783 filter (SMESH.Filter): the filter defining group contents
2786 :class:`SMESH.SMESH_GroupOnFilter`
2789 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2791 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2793 Create a mesh group by the given ids of elements
2796 groupName: the name of the mesh group
2797 elementType: the type of elements in the group; either of
2798 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2799 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2802 :class:`SMESH.SMESH_Group`
2805 group = self.mesh.CreateGroup(elementType, groupName)
2806 if isinstance( elemIDs, Mesh ):
2807 elemIDs = elemIDs.GetMesh()
2808 if hasattr( elemIDs, "GetIDs" ):
2809 if hasattr( elemIDs, "SetMesh" ):
2810 elemIDs.SetMesh( self.GetMesh() )
2811 group.AddFrom( elemIDs )
2819 CritType=FT_Undefined,
2822 UnaryOp=FT_Undefined,
2825 Create a mesh group by the given conditions
2828 groupName: the name of the mesh group
2829 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2830 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2831 Note that the items starting from FT_LessThan are not suitable for CritType.
2832 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2833 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2834 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2835 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2836 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2839 :class:`SMESH.SMESH_GroupOnFilter`
2842 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2843 group = self.MakeGroupByCriterion(groupName, aCriterion)
2846 def MakeGroupByCriterion(self, groupName, Criterion):
2848 Create a mesh group by the given criterion
2851 groupName: the name of the mesh group
2852 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2855 :class:`SMESH.SMESH_GroupOnFilter`
2858 :meth:`smeshBuilder.GetCriterion`
2861 return self.MakeGroupByCriteria( groupName, [Criterion] )
2863 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2865 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2868 groupName: the name of the mesh group
2869 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2870 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2873 :class:`SMESH.SMESH_GroupOnFilter`
2876 :meth:`smeshBuilder.GetCriterion`
2879 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2880 group = self.MakeGroupByFilter(groupName, aFilter)
2883 def MakeGroupByFilter(self, groupName, theFilter):
2885 Create a mesh group by the given filter
2888 groupName (string): the name of the mesh group
2889 theFilter (SMESH.Filter): the filter
2892 :class:`SMESH.SMESH_GroupOnFilter`
2895 :meth:`smeshBuilder.GetFilter`
2898 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2899 #theFilter.SetMesh( self.mesh )
2900 #group.AddFrom( theFilter )
2901 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2904 def RemoveGroup(self, group):
2909 group (SMESH.SMESH_GroupBase): group to remove
2912 self.mesh.RemoveGroup(group)
2914 def RemoveGroupWithContents(self, group):
2916 Remove a group with its contents
2919 group (SMESH.SMESH_GroupBase): group to remove
2922 This operation can create gaps in numeration of nodes or elements.
2923 Call :meth:`RenumberElements` to remove the gaps.
2926 self.mesh.RemoveGroupWithContents(group)
2928 def GetGroups(self, elemType = SMESH.ALL):
2930 Get the list of groups existing in the mesh in the order of creation
2931 (starting from the oldest one)
2934 elemType (SMESH.ElementType): type of elements the groups contain;
2935 by default groups of elements of all types are returned
2938 a list of :class:`SMESH.SMESH_GroupBase`
2941 groups = self.mesh.GetGroups()
2942 if elemType == SMESH.ALL:
2946 if g.GetType() == elemType:
2947 typedGroups.append( g )
2954 Get the number of groups existing in the mesh
2957 the quantity of groups as an integer value
2960 return self.mesh.NbGroups()
2962 def GetGroupNames(self):
2964 Get the list of names of groups existing in the mesh
2970 groups = self.GetGroups()
2972 for group in groups:
2973 names.append(group.GetName())
2976 def GetGroupByName(self, name, elemType = None):
2978 Find groups by name and type
2981 name (string): name of the group of interest
2982 elemType (SMESH.ElementType): type of elements the groups contain;
2983 by default one group of any type is returned;
2984 if elemType == SMESH.ALL then all groups of any type are returned
2987 a list of :class:`SMESH.SMESH_GroupBase`
2991 for group in self.GetGroups():
2992 if group.GetName() == name:
2993 if elemType is None:
2995 if ( elemType == SMESH.ALL or
2996 group.GetType() == elemType ):
2997 groups.append( group )
3000 def UnionGroups(self, group1, group2, name):
3002 Produce a union of two groups.
3003 A new group is created. All mesh elements that are
3004 present in the initial groups are added to the new one
3007 group1 (SMESH.SMESH_GroupBase): a group
3008 group2 (SMESH.SMESH_GroupBase): another group
3011 instance of :class:`SMESH.SMESH_Group`
3014 return self.mesh.UnionGroups(group1, group2, name)
3016 def UnionListOfGroups(self, groups, name):
3018 Produce a union list of groups.
3019 New group is created. All mesh elements that are present in
3020 initial groups are added to the new one
3023 groups: list of :class:`SMESH.SMESH_GroupBase`
3026 instance of :class:`SMESH.SMESH_Group`
3028 return self.mesh.UnionListOfGroups(groups, name)
3030 def IntersectGroups(self, group1, group2, name):
3032 Prodice an intersection of two groups.
3033 A new group is created. All mesh elements that are common
3034 for the two initial groups are added to the new one.
3037 group1 (SMESH.SMESH_GroupBase): a group
3038 group2 (SMESH.SMESH_GroupBase): another group
3041 instance of :class:`SMESH.SMESH_Group`
3044 return self.mesh.IntersectGroups(group1, group2, name)
3046 def IntersectListOfGroups(self, groups, name):
3048 Produce an intersection of groups.
3049 New group is created. All mesh elements that are present in all
3050 initial groups simultaneously are added to the new one
3053 groups: a list of :class:`SMESH.SMESH_GroupBase`
3056 instance of :class:`SMESH.SMESH_Group`
3058 return self.mesh.IntersectListOfGroups(groups, name)
3060 def CutGroups(self, main_group, tool_group, name):
3062 Produce a cut of two groups.
3063 A new group is created. All mesh elements that are present in
3064 the main group but are not present in the tool group are added to the new one
3067 main_group (SMESH.SMESH_GroupBase): a group to cut from
3068 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3071 an instance of :class:`SMESH.SMESH_Group`
3074 return self.mesh.CutGroups(main_group, tool_group, name)
3076 def CutListOfGroups(self, main_groups, tool_groups, name):
3078 Produce a cut of groups.
3079 A new group is created. All mesh elements that are present in main groups
3080 but do not present in tool groups are added to the new one
3083 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3084 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3087 an instance of :class:`SMESH.SMESH_Group`
3090 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3092 def CreateDimGroup(self, groups, elemType, name,
3093 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3095 Create a standalone group of entities basing on nodes of other groups.
3098 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3099 elemType: a type of elements to include to the new group; either of
3100 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3101 name: a name of the new group.
3102 nbCommonNodes: a criterion of inclusion of an element to the new group
3103 basing on number of element nodes common with reference *groups*.
3104 Meaning of possible values are:
3106 - SMESH.ALL_NODES - include if all nodes are common,
3107 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3108 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3109 - SMEHS.MAJORITY - include if half of nodes or more are common.
3110 underlyingOnly: if *True* (default), an element is included to the
3111 new group provided that it is based on nodes of an element of *groups*;
3112 in this case the reference *groups* are supposed to be of higher dimension
3113 than *elemType*, which can be useful for example to get all faces lying on
3114 volumes of the reference *groups*.
3117 an instance of :class:`SMESH.SMESH_Group`
3120 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3122 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3124 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3126 Distribute all faces of the mesh among groups using sharp edges and optionally
3127 existing 1D elements as group boundaries.
3130 sharpAngle: edge is considered sharp if an angle between normals of
3131 adjacent faces is more than \a sharpAngle in degrees.
3132 createEdges (boolean): to create 1D elements for detected sharp edges.
3133 useExistingEdges (boolean): to use existing edges as group boundaries
3135 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3137 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3138 self.mesh.SetParameters(Parameters)
3139 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3141 def ConvertToStandalone(self, group):
3143 Convert group on geom into standalone group
3146 return self.mesh.ConvertToStandalone(group)
3148 # Get some info about mesh:
3149 # ------------------------
3151 def GetLog(self, clearAfterGet):
3153 Return the log of nodes and elements added or removed
3154 since the previous clear of the log.
3157 clearAfterGet: log is emptied after Get (safe if concurrents access)
3160 list of SMESH.log_block structures { commandType, number, coords, indexes }
3163 return self.mesh.GetLog(clearAfterGet)
3167 Clear the log of nodes and elements added or removed since the previous
3168 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3171 self.mesh.ClearLog()
3173 def SetAutoColor(self, theAutoColor):
3175 Toggle auto color mode on the object.
3176 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3179 theAutoColor (boolean): the flag which toggles auto color mode.
3182 self.mesh.SetAutoColor(theAutoColor)
3184 def GetAutoColor(self):
3186 Get flag of object auto color mode.
3192 return self.mesh.GetAutoColor()
3199 integer value, which is the internal Id of the mesh
3202 return self.mesh.GetId()
3204 def HasDuplicatedGroupNamesMED(self):
3206 Check the group names for duplications.
3207 Consider the maximum group name length stored in MED file.
3213 return self.mesh.HasDuplicatedGroupNamesMED()
3215 def GetMeshEditor(self):
3217 Obtain the mesh editor tool
3220 an instance of :class:`SMESH.SMESH_MeshEditor`
3225 def GetIDSource(self, ids, elemType = SMESH.ALL):
3227 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3228 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3232 elemType: type of elements; this parameter is used to distinguish
3233 IDs of nodes from IDs of elements; by default ids are treated as
3234 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3237 an instance of :class:`SMESH.SMESH_IDSource`
3240 call UnRegister() for the returned object as soon as it is no more useful::
3242 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3243 mesh.DoSomething( idSrc )
3247 if isinstance( ids, int ):
3249 return self.editor.MakeIDSource(ids, elemType)
3252 # Get information about mesh contents:
3253 # ------------------------------------
3255 def GetMeshInfo(self, obj = None):
3257 Get the mesh statistic.
3260 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3263 if not obj: obj = self.mesh
3264 return self.smeshpyD.GetMeshInfo(obj)
3268 Return the number of nodes in the mesh
3274 return self.mesh.NbNodes()
3276 def NbElements(self):
3278 Return the number of elements in the mesh
3284 return self.mesh.NbElements()
3286 def Nb0DElements(self):
3288 Return the number of 0d elements in the mesh
3294 return self.mesh.Nb0DElements()
3298 Return the number of ball discrete elements in the mesh
3304 return self.mesh.NbBalls()
3308 Return the number of edges in the mesh
3314 return self.mesh.NbEdges()
3316 def NbEdgesOfOrder(self, elementOrder):
3318 Return the number of edges with the given order in the mesh
3321 elementOrder: the order of elements
3322 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3328 return self.mesh.NbEdgesOfOrder(elementOrder)
3332 Return the number of faces in the mesh
3338 return self.mesh.NbFaces()
3340 def NbFacesOfOrder(self, elementOrder):
3342 Return the number of faces with the given order in the mesh
3345 elementOrder: the order of elements
3346 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3352 return self.mesh.NbFacesOfOrder(elementOrder)
3354 def NbTriangles(self):
3356 Return the number of triangles in the mesh
3362 return self.mesh.NbTriangles()
3364 def NbTrianglesOfOrder(self, elementOrder):
3366 Return the number of triangles with the given order in the mesh
3369 elementOrder: is the order of elements
3370 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3376 return self.mesh.NbTrianglesOfOrder(elementOrder)
3378 def NbBiQuadTriangles(self):
3380 Return the number of biquadratic triangles in the mesh
3386 return self.mesh.NbBiQuadTriangles()
3388 def NbQuadrangles(self):
3390 Return the number of quadrangles in the mesh
3396 return self.mesh.NbQuadrangles()
3398 def NbQuadranglesOfOrder(self, elementOrder):
3400 Return the number of quadrangles with the given order in the mesh
3403 elementOrder: the order of elements
3404 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3410 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3412 def NbBiQuadQuadrangles(self):
3414 Return the number of biquadratic quadrangles in the mesh
3420 return self.mesh.NbBiQuadQuadrangles()
3422 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3424 Return the number of polygons of given order in the mesh
3427 elementOrder: the order of elements
3428 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3434 return self.mesh.NbPolygonsOfOrder(elementOrder)
3436 def NbVolumes(self):
3438 Return the number of volumes in the mesh
3444 return self.mesh.NbVolumes()
3447 def NbVolumesOfOrder(self, elementOrder):
3449 Return the number of volumes with the given order in the mesh
3452 elementOrder: the order of elements
3453 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3459 return self.mesh.NbVolumesOfOrder(elementOrder)
3463 Return the number of tetrahedrons in the mesh
3469 return self.mesh.NbTetras()
3471 def NbTetrasOfOrder(self, elementOrder):
3473 Return the number of tetrahedrons with the given order in the mesh
3476 elementOrder: the order of elements
3477 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3483 return self.mesh.NbTetrasOfOrder(elementOrder)
3487 Return the number of hexahedrons in the mesh
3493 return self.mesh.NbHexas()
3495 def NbHexasOfOrder(self, elementOrder):
3497 Return the number of hexahedrons with the given order in the mesh
3500 elementOrder: the order of elements
3501 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3507 return self.mesh.NbHexasOfOrder(elementOrder)
3509 def NbTriQuadraticHexas(self):
3511 Return the number of triquadratic hexahedrons in the mesh
3517 return self.mesh.NbTriQuadraticHexas()
3519 def NbPyramids(self):
3521 Return the number of pyramids in the mesh
3527 return self.mesh.NbPyramids()
3529 def NbPyramidsOfOrder(self, elementOrder):
3531 Return the number of pyramids with the given order in the mesh
3534 elementOrder: the order of elements
3535 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3541 return self.mesh.NbPyramidsOfOrder(elementOrder)
3545 Return the number of prisms in the mesh
3551 return self.mesh.NbPrisms()
3553 def NbPrismsOfOrder(self, elementOrder):
3555 Return the number of prisms with the given order in the mesh
3558 elementOrder: the order of elements
3559 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3565 return self.mesh.NbPrismsOfOrder(elementOrder)
3567 def NbHexagonalPrisms(self):
3569 Return the number of hexagonal prisms in the mesh
3575 return self.mesh.NbHexagonalPrisms()
3577 def NbPolyhedrons(self):
3579 Return the number of polyhedrons in the mesh
3585 return self.mesh.NbPolyhedrons()
3587 def NbSubMesh(self):
3589 Return the number of submeshes in the mesh
3595 return self.mesh.NbSubMesh()
3597 def GetElementsId(self):
3599 Return the list of all mesh elements IDs
3602 the list of integer values
3605 :meth:`GetElementsByType`
3608 return self.mesh.GetElementsId()
3610 def GetElementsByType(self, elementType):
3612 Return the list of IDs of mesh elements with the given type
3615 elementType (SMESH.ElementType): the required type of elements
3618 list of integer values
3621 return self.mesh.GetElementsByType(elementType)
3623 def GetNodesId(self):
3625 Return the list of mesh nodes IDs
3628 the list of integer values
3631 return self.mesh.GetNodesId()
3633 # Get the information about mesh elements:
3634 # ------------------------------------
3636 def GetElementType(self, id, iselem=True):
3638 Return the type of mesh element or node
3641 the value from :class:`SMESH.ElementType` enumeration.
3642 Return SMESH.ALL if element or node with the given ID does not exist
3645 return self.mesh.GetElementType(id, iselem)
3647 def GetElementGeomType(self, id):
3649 Return the geometric type of mesh element
3652 the value from :class:`SMESH.EntityType` enumeration.
3655 return self.mesh.GetElementGeomType(id)
3657 def GetElementShape(self, id):
3659 Return the shape type of mesh element
3662 the value from :class:`SMESH.GeometryType` enumeration.
3665 return self.mesh.GetElementShape(id)
3667 def GetSubMeshElementsId(self, Shape):
3669 Return the list of sub-mesh elements IDs
3672 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3673 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3676 list of integer values
3679 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3680 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3683 return self.mesh.GetSubMeshElementsId(ShapeID)
3685 def GetSubMeshNodesId(self, Shape, all):
3687 Return the list of sub-mesh nodes IDs
3690 Shape: a geom object (sub-shape).
3691 *Shape* must be the sub-shape of a :meth:`GetShape`
3692 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3695 list of integer values
3698 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3699 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3702 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3704 def GetSubMeshElementType(self, Shape):
3706 Return type of elements on given shape
3709 Shape: a geom object (sub-shape).
3710 *Shape* must be a sub-shape of a ShapeToMesh()
3713 :class:`SMESH.ElementType`
3716 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3717 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3720 return self.mesh.GetSubMeshElementType(ShapeID)
3724 Get the mesh description
3730 return self.mesh.Dump()
3733 # Get the information about nodes and elements of a mesh by its IDs:
3734 # -----------------------------------------------------------
3736 def GetNodeXYZ(self, id):
3738 Get XYZ coordinates of a node.
3739 If there is no node for the given ID - return an empty list
3742 list of float values
3745 return self.mesh.GetNodeXYZ(id)
3747 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3749 Return list of IDs of inverse elements for the given node.
3750 If there is no node for the given ID - return an empty list
3754 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3757 list of integer values
3760 return self.mesh.GetNodeInverseElements(id,elemType)
3762 def GetNodePosition(self,NodeID):
3764 Return the position of a node on the shape
3767 :class:`SMESH.NodePosition`
3770 return self.mesh.GetNodePosition(NodeID)
3772 def GetElementPosition(self,ElemID):
3774 Return the position of an element on the shape
3777 :class:`SMESH.ElementPosition`
3780 return self.mesh.GetElementPosition(ElemID)
3782 def GetShapeID(self, id):
3784 Return the ID of the shape, on which the given node was generated.
3787 an integer value > 0 or -1 if there is no node for the given
3788 ID or the node is not assigned to any geometry
3791 return self.mesh.GetShapeID(id)
3793 def GetShapeIDForElem(self,id):
3795 Return the ID of the shape, on which the given element was generated.
3798 an integer value > 0 or -1 if there is no element for the given
3799 ID or the element is not assigned to any geometry
3802 return self.mesh.GetShapeIDForElem(id)
3804 def GetElemNbNodes(self, id):
3806 Return the number of nodes of the given element
3809 an integer value > 0 or -1 if there is no element for the given ID
3812 return self.mesh.GetElemNbNodes(id)
3814 def GetElemNode(self, id, index):
3816 Return the node ID the given (zero based) index for the given element.
3818 * If there is no element for the given ID - return -1.
3819 * If there is no node for the given index - return -2.
3822 id (int): element ID
3823 index (int): node index within the element
3826 an integer value (ID)
3829 :meth:`GetElemNodes`
3832 return self.mesh.GetElemNode(id, index)
3834 def GetElemNodes(self, id):
3836 Return the IDs of nodes of the given element
3839 a list of integer values
3842 return self.mesh.GetElemNodes(id)
3844 def IsMediumNode(self, elementID, nodeID):
3846 Return true if the given node is the medium node in the given quadratic element
3849 return self.mesh.IsMediumNode(elementID, nodeID)
3851 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3853 Return true if the given node is the medium node in one of quadratic elements
3856 nodeID: ID of the node
3857 elementType: the type of elements to check a state of the node, either of
3858 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3861 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3863 def ElemNbEdges(self, id):
3865 Return the number of edges for the given element
3868 return self.mesh.ElemNbEdges(id)
3870 def ElemNbFaces(self, id):
3872 Return the number of faces for the given element
3875 return self.mesh.ElemNbFaces(id)
3877 def GetElemFaceNodes(self,elemId, faceIndex):
3879 Return nodes of given face (counted from zero) for given volumic element.
3882 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3884 def GetFaceNormal(self, faceId, normalized=False):
3886 Return three components of normal of given mesh face
3887 (or an empty array in KO case)
3890 return self.mesh.GetFaceNormal(faceId,normalized)
3892 def FindElementByNodes(self, nodes):
3894 Return an element based on all given nodes.
3897 return self.mesh.FindElementByNodes(nodes)
3899 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3901 Return elements including all given nodes.
3904 return self.mesh.GetElementsByNodes( nodes, elemType )
3906 def IsPoly(self, id):
3908 Return true if the given element is a polygon
3911 return self.mesh.IsPoly(id)
3913 def IsQuadratic(self, id):
3915 Return true if the given element is quadratic
3918 return self.mesh.IsQuadratic(id)
3920 def GetBallDiameter(self, id):
3922 Return diameter of a ball discrete element or zero in case of an invalid *id*
3925 return self.mesh.GetBallDiameter(id)
3927 def BaryCenter(self, id):
3929 Return XYZ coordinates of the barycenter of the given element.
3930 If there is no element for the given ID - return an empty list
3933 a list of three double values
3936 :meth:`smeshBuilder.GetGravityCenter`
3939 return self.mesh.BaryCenter(id)
3941 def GetIdsFromFilter(self, filter, meshParts=[] ):
3943 Pass mesh elements through the given filter and return IDs of fitting elements
3946 filter: :class:`SMESH.Filter`
3947 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3953 :meth:`SMESH.Filter.GetIDs`
3954 :meth:`SMESH.Filter.GetElementsIdFromParts`
3957 filter.SetMesh( self.mesh )
3960 if isinstance( meshParts, Mesh ):
3961 filter.SetMesh( meshParts.GetMesh() )
3962 return theFilter.GetIDs()
3963 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3964 meshParts = [ meshParts ]
3965 return filter.GetElementsIdFromParts( meshParts )
3967 return filter.GetIDs()
3969 # Get mesh measurements information:
3970 # ------------------------------------
3972 def GetFreeBorders(self):
3974 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3975 Return a list of special structures (borders).
3978 a list of :class:`SMESH.FreeEdges.Border`
3981 aFilterMgr = self.smeshpyD.CreateFilterManager()
3982 aPredicate = aFilterMgr.CreateFreeEdges()
3983 aPredicate.SetMesh(self.mesh)
3984 aBorders = aPredicate.GetBorders()
3985 aFilterMgr.UnRegister()
3988 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3990 Get minimum distance between two nodes, elements or distance to the origin
3993 id1: first node/element id
3994 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3995 isElem1: *True* if *id1* is element id, *False* if it is node id
3996 isElem2: *True* if *id2* is element id, *False* if it is node id
3999 minimum distance value
4001 :meth:`GetMinDistance`
4004 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
4005 return aMeasure.value
4007 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
4009 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
4012 id1: first node/element id
4013 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
4014 isElem1: *True* if *id1* is element id, *False* if it is node id
4015 isElem2: *True* if *id2* is element id, *False* if it is node id
4018 :class:`SMESH.Measure` structure
4024 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
4026 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
4029 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
4031 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4036 aMeasurements = self.smeshpyD.CreateMeasurements()
4037 aMeasure = aMeasurements.MinDistance(id1, id2)
4038 genObjUnRegister([aMeasurements,id1, id2])
4041 def BoundingBox(self, objects=None, isElem=False):
4043 Get bounding box of the specified object(s)
4046 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4047 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4048 *False* specifies that *objects* are nodes
4051 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4054 :meth:`GetBoundingBox()`
4057 result = self.GetBoundingBox(objects, isElem)
4061 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4064 def GetBoundingBox(self, objects=None, isElem=False):
4066 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4069 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4070 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4071 False means that *objects* are nodes
4074 :class:`SMESH.Measure` structure
4077 :meth:`BoundingBox()`
4081 objects = [self.mesh]
4082 elif isinstance(objects, tuple):
4083 objects = list(objects)
4084 if not isinstance(objects, list):
4086 if len(objects) > 0 and isinstance(objects[0], int):
4089 unRegister = genObjUnRegister()
4091 if isinstance(o, Mesh):
4092 srclist.append(o.mesh)
4093 elif hasattr(o, "_narrow"):
4094 src = o._narrow(SMESH.SMESH_IDSource)
4095 if src: srclist.append(src)
4097 elif isinstance(o, list):
4099 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4101 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4102 unRegister.set( srclist[-1] )
4105 aMeasurements = self.smeshpyD.CreateMeasurements()
4106 unRegister.set( aMeasurements )
4107 aMeasure = aMeasurements.BoundingBox(srclist)
4110 # Mesh edition (SMESH_MeshEditor functionality):
4111 # ---------------------------------------------
4113 def RemoveElements(self, IDsOfElements):
4115 Remove the elements from the mesh by ids
4118 IDsOfElements: is a list of ids of elements to remove
4124 This operation can create gaps in numeration of elements.
4125 Call :meth:`RenumberElements` to remove the gaps.
4128 return self.editor.RemoveElements(IDsOfElements)
4130 def RemoveNodes(self, IDsOfNodes):
4132 Remove nodes from mesh by ids
4135 IDsOfNodes: is a list of ids of nodes to remove
4141 This operation can create gaps in numeration of nodes.
4142 Call :meth:`RenumberElements` to remove the gaps.
4145 return self.editor.RemoveNodes(IDsOfNodes)
4147 def RemoveNodeWithReconnection(self, nodeID ):
4149 Remove a node along with changing surrounding faces to cover a hole.
4152 nodeID: ID of node to remove
4155 return self.editor.RemoveNodeWithReconnection( nodeID )
4157 def RemoveOrphanNodes(self):
4159 Remove all orphan (free) nodes from mesh
4162 number of the removed nodes
4165 This operation can create gaps in numeration of nodes.
4166 Call :meth:`RenumberElements` to remove the gaps.
4169 return self.editor.RemoveOrphanNodes()
4171 def AddNode(self, x, y, z):
4173 Add a node to the mesh by coordinates
4179 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4180 if hasVars: self.mesh.SetParameters(Parameters)
4181 return self.editor.AddNode( x, y, z)
4183 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4185 Create a 0D element on a node with given number.
4188 IDOfNode: the ID of node for creation of the element.
4189 DuplicateElements: to add one more 0D element to a node or not
4192 ID of the new 0D element
4195 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4197 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4199 Create 0D elements on all nodes of the given elements except those
4200 nodes on which a 0D element already exists.
4203 theObject: an object on whose nodes 0D elements will be created.
4204 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4205 theGroupName: optional name of a group to add 0D elements created
4206 and/or found on nodes of *theObject*.
4207 DuplicateElements: to add one more 0D element to a node or not
4210 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4211 IDs of new and/or found 0D elements. IDs of 0D elements
4212 can be retrieved from the returned object by
4213 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4216 unRegister = genObjUnRegister()
4217 if isinstance( theObject, Mesh ):
4218 theObject = theObject.GetMesh()
4219 elif isinstance( theObject, list ):
4220 theObject = self.GetIDSource( theObject, SMESH.ALL )
4221 unRegister.set( theObject )
4222 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4224 def AddBall(self, IDOfNode, diameter):
4226 Create a ball element on a node with given ID.
4229 IDOfNode: the ID of node for creation of the element.
4230 diameter: the bal diameter.
4233 ID of the new ball element
4236 return self.editor.AddBall( IDOfNode, diameter )
4238 def AddEdge(self, IDsOfNodes):
4240 Create a linear or quadratic edge (this is determined
4241 by the number of given nodes).
4244 IDsOfNodes: list of node IDs for creation of the element.
4245 The order of nodes in this list should correspond to
4246 the :ref:`connectivity convention <connectivity_page>`.
4252 return self.editor.AddEdge(IDsOfNodes)
4254 def AddFace(self, IDsOfNodes):
4256 Create a linear or quadratic face (this is determined
4257 by the number of given nodes).
4260 IDsOfNodes: list of node IDs for creation of the element.
4261 The order of nodes in this list should correspond to
4262 the :ref:`connectivity convention <connectivity_page>`.
4268 return self.editor.AddFace(IDsOfNodes)
4270 def AddPolygonalFace(self, IdsOfNodes):
4272 Add a polygonal face defined by a list of node IDs
4275 IdsOfNodes: the list of node IDs for creation of the element.
4281 return self.editor.AddPolygonalFace(IdsOfNodes)
4283 def AddQuadPolygonalFace(self, IdsOfNodes):
4285 Add a quadratic polygonal face defined by a list of node IDs
4288 IdsOfNodes: the list of node IDs for creation of the element;
4289 corner nodes follow first.
4295 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4297 def AddVolume(self, IDsOfNodes):
4299 Create both simple and quadratic volume (this is determined
4300 by the number of given nodes).
4303 IDsOfNodes: list of node IDs for creation of the element.
4304 The order of nodes in this list should correspond to
4305 the :ref:`connectivity convention <connectivity_page>`.
4308 ID of the new volumic element
4311 return self.editor.AddVolume(IDsOfNodes)
4313 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4315 Create a volume of many faces, giving nodes for each face.
4318 IdsOfNodes: list of node IDs for volume creation, face by face.
4319 Quantities: list of integer values, Quantities[i]
4320 gives the quantity of nodes in face number i.
4323 ID of the new volumic element
4326 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4328 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4330 Create a volume of many faces, giving the IDs of the existing faces.
4333 The created volume will refer only to the nodes
4334 of the given faces, not to the faces themselves.
4337 IdsOfFaces: the list of face IDs for volume creation.
4340 ID of the new volumic element
4343 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4346 def SetNodeOnVertex(self, NodeID, Vertex):
4348 Bind a node to a vertex
4352 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4355 True if succeed else raises an exception
4358 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4359 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4363 self.editor.SetNodeOnVertex(NodeID, VertexID)
4364 except SALOME.SALOME_Exception as inst:
4365 raise ValueError(inst.details.text)
4369 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4371 Store the node position on an edge
4375 Edge: an edge (GEOM.GEOM_Object) or edge ID
4376 paramOnEdge: a parameter on the edge where the node is located
4379 True if succeed else raises an exception
4382 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4383 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4387 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4388 except SALOME.SALOME_Exception as inst:
4389 raise ValueError(inst.details.text)
4392 def SetNodeOnFace(self, NodeID, Face, u, v):
4394 Store node position on a face
4398 Face: a face (GEOM.GEOM_Object) or face ID
4399 u: U parameter on the face where the node is located
4400 v: V parameter on the face where the node is located
4403 True if succeed else raises an exception
4406 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4407 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4411 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4412 except SALOME.SALOME_Exception as inst:
4413 raise ValueError(inst.details.text)
4416 def SetNodeInVolume(self, NodeID, Solid):
4418 Bind a node to a solid
4422 Solid: a solid (GEOM.GEOM_Object) or solid ID
4425 True if succeed else raises an exception
4428 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4429 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4433 self.editor.SetNodeInVolume(NodeID, SolidID)
4434 except SALOME.SALOME_Exception as inst:
4435 raise ValueError(inst.details.text)
4438 def SetMeshElementOnShape(self, ElementID, Shape):
4440 Bind an element to a shape
4443 ElementID: an element ID
4444 Shape: a shape (GEOM.GEOM_Object) or shape ID
4447 True if succeed else raises an exception
4450 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4451 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4455 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4456 except SALOME.SALOME_Exception as inst:
4457 raise ValueError(inst.details.text)
4461 def MoveNode(self, NodeID, x, y, z):
4463 Move the node with the given id
4466 NodeID: the id of the node
4467 x: a new X coordinate
4468 y: a new Y coordinate
4469 z: a new Z coordinate
4472 True if succeed else False
4475 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4476 if hasVars: self.mesh.SetParameters(Parameters)
4477 return self.editor.MoveNode(NodeID, x, y, z)
4479 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4481 Find the node closest to a point and moves it to a point location
4484 x: the X coordinate of a point
4485 y: the Y coordinate of a point
4486 z: the Z coordinate of a point
4487 NodeID: if specified (>0), the node with this ID is moved,
4488 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4491 the ID of a moved node
4494 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4495 if hasVars: self.mesh.SetParameters(Parameters)
4496 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4498 def FindNodeClosestTo(self, x, y, z):
4500 Find the node closest to a point
4503 x: the X coordinate of a point
4504 y: the Y coordinate of a point
4505 z: the Z coordinate of a point
4511 return self.editor.FindNodeClosestTo(x, y, z)
4513 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4515 Find the elements where a point lays IN or ON
4518 x,y,z (float): coordinates of the point
4519 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4520 means elements of any type excluding nodes, discrete and 0D elements.
4521 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4524 list of IDs of found elements
4527 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4529 return self.editor.FindElementsByPoint(x, y, z, elementType)
4531 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4533 Project a point to a mesh object.
4534 Return ID of an element of given type where the given point is projected
4535 and coordinates of the projection point.
4536 In the case if nothing found, return -1 and []
4538 if isinstance( meshObject, Mesh ):
4539 meshObject = meshObject.GetMesh()
4541 meshObject = self.GetMesh()
4542 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4544 def GetPointState(self, x, y, z):
4546 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4547 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4548 UNKNOWN state means that either mesh is wrong or the analysis fails.
4551 return self.editor.GetPointState(x, y, z)
4553 def IsManifold(self):
4555 Check if a 2D mesh is manifold
4558 return self.editor.IsManifold()
4560 def IsCoherentOrientation2D(self):
4562 Check if orientation of 2D elements is coherent
4565 return self.editor.IsCoherentOrientation2D()
4567 def Get1DBranches( self, edges, startNode = 0 ):
4569 Partition given 1D elements into groups of contiguous edges.
4570 A node where number of meeting edges != 2 is a group end.
4571 An optional startNode is used to orient groups it belongs to.
4574 A list of edge groups and a list of corresponding node groups,
4575 where the group is a list of IDs of edges or nodes, like follows
4576 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4577 If a group is closed, the first and last nodes of the group are same.
4579 if isinstance( edges, Mesh ):
4580 edges = edges.GetMesh()
4581 unRegister = genObjUnRegister()
4582 if isinstance( edges, list ):
4583 edges = self.GetIDSource( edges, SMESH.EDGE )
4584 unRegister.set( edges )
4585 return self.editor.Get1DBranches( edges, startNode )
4587 def FindSharpEdges( self, angle, addExisting=False ):
4589 Return sharp edges of faces and non-manifold ones.
4590 Optionally add existing edges.
4593 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4594 addExisting: to return existing edges (1D elements) as well
4597 list of FaceEdge structures
4599 angle = ParseParameters( angle )[0]
4600 return self.editor.FindSharpEdges( angle, addExisting )
4602 def MeshToPassThroughAPoint(self, x, y, z):
4604 Find the node closest to a point and moves it to a point location
4607 x: the X coordinate of a point
4608 y: the Y coordinate of a point
4609 z: the Z coordinate of a point
4612 the ID of a moved node
4615 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4617 def InverseDiag(self, NodeID1, NodeID2):
4619 Replace two neighbour triangles sharing Node1-Node2 link
4620 with the triangles built on the same 4 nodes but having other common link.
4623 NodeID1: the ID of the first node
4624 NodeID2: the ID of the second node
4627 False if proper faces were not found
4629 return self.editor.InverseDiag(NodeID1, NodeID2)
4631 def DeleteDiag(self, NodeID1, NodeID2):
4633 Replace two neighbour triangles sharing *Node1-Node2* link
4634 with a quadrangle built on the same 4 nodes.
4637 NodeID1: ID of the first node
4638 NodeID2: ID of the second node
4641 False if proper faces were not found
4644 This operation can create gaps in numeration of elements.
4645 Call :meth:`RenumberElements` to remove the gaps.
4648 return self.editor.DeleteDiag(NodeID1, NodeID2)
4650 def AddNodeOnSegment(self, Node1, Node2, position = 0.5):
4652 Replace each triangle bound by Node1-Node2 segment with
4653 two triangles by connecting a node made on the link with a node
4654 opposite to the link.
4657 Node1: ID of the first node
4658 Node2: ID of the second node
4659 position: location [0,1] of the new node on the segment
4661 return self.editor.AddNodeOnSegment(Node1, Node2, position)
4663 def AddNodeOnFace(self, face, x, y, z):
4665 Split a face into triangles by adding a new node onto the face
4666 and connecting the new node with face nodes
4669 face: ID of the face
4670 x,y,z: coordinates of the new node
4672 return self.editor.AddNodeOnFace(face, x, y, z)
4674 def Reorient(self, IDsOfElements=None):
4676 Reorient elements by ids
4679 IDsOfElements: if undefined reorients all mesh elements
4682 True if succeed else False
4685 if IDsOfElements == None:
4686 IDsOfElements = self.GetElementsId()
4687 return self.editor.Reorient(IDsOfElements)
4689 def ReorientObject(self, theObject):
4691 Reorient all elements of the object
4694 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4697 True if succeed else False
4700 if ( isinstance( theObject, Mesh )):
4701 theObject = theObject.GetMesh()
4702 return self.editor.ReorientObject(theObject)
4704 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4706 Reorient faces contained in *the2DObject*.
4709 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4710 theDirection: a desired direction of normal of *theFace*.
4711 It can be either a GEOM vector or a list of coordinates [x,y,z].
4712 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4713 compared with theDirection. It can be either ID of face or a point
4714 by which the face will be found. The point can be given as either
4715 a GEOM vertex or a list of point coordinates.
4718 number of reoriented faces
4721 unRegister = genObjUnRegister()
4723 if isinstance( the2DObject, Mesh ):
4724 the2DObject = the2DObject.GetMesh()
4725 if isinstance( the2DObject, list ):
4726 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4727 unRegister.set( the2DObject )
4728 # check theDirection
4729 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4730 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4731 if isinstance( theDirection, list ):
4732 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4733 # prepare theFace and thePoint
4734 theFace = theFaceOrPoint
4735 thePoint = PointStruct(0,0,0)
4736 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4737 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4739 if isinstance( theFaceOrPoint, list ):
4740 thePoint = PointStruct( *theFaceOrPoint )
4742 if isinstance( theFaceOrPoint, PointStruct ):
4743 thePoint = theFaceOrPoint
4745 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4747 def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4749 Reorient faces contained in a list of *objectFaces*
4750 equally to faces contained in a list of *referenceFaces*.
4753 objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4754 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.
4757 number of reoriented faces.
4759 if not isinstance( objectFaces, list ):
4760 objectFaces = [ objectFaces ]
4761 for i,obj2D in enumerate( objectFaces ):
4762 if isinstance( obj2D, Mesh ):
4763 objectFaces[i] = obj2D.GetMesh()
4764 if not isinstance( referenceFaces, list ):
4765 referenceFaces = [ referenceFaces ]
4767 return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4770 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4772 Reorient faces according to adjacent volumes.
4775 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4776 either IDs of faces or face groups.
4777 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4778 theOutsideNormal: to orient faces to have their normals
4779 pointing either *outside* or *inside* the adjacent volumes.
4782 number of reoriented faces.
4785 unRegister = genObjUnRegister()
4787 if not isinstance( the2DObject, list ):
4788 the2DObject = [ the2DObject ]
4789 elif the2DObject and isinstance( the2DObject[0], int ):
4790 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4791 unRegister.set( the2DObject )
4792 the2DObject = [ the2DObject ]
4793 for i,obj2D in enumerate( the2DObject ):
4794 if isinstance( obj2D, Mesh ):
4795 the2DObject[i] = obj2D.GetMesh()
4796 if isinstance( obj2D, list ):
4797 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4798 unRegister.set( the2DObject[i] )
4800 if isinstance( the3DObject, Mesh ):
4801 the3DObject = the3DObject.GetMesh()
4802 if isinstance( the3DObject, list ):
4803 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4804 unRegister.set( the3DObject )
4805 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4807 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4809 Fuse the neighbouring triangles into quadrangles.
4812 IDsOfElements: The triangles to be fused.
4813 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4814 applied to possible quadrangles to choose a neighbour to fuse with.
4815 Note that not all items of :class:`SMESH.FunctorType` corresponds
4816 to numerical functors.
4817 MaxAngle: is the maximum angle between element normals at which the fusion
4818 is still performed; theMaxAngle is measured in radians.
4819 Also it could be a name of variable which defines angle in degrees.
4822 True in case of success, False otherwise.
4825 This operation can create gaps in numeration of elements.
4826 Call :meth:`RenumberElements` to remove the gaps.
4829 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4830 self.mesh.SetParameters(Parameters)
4831 if not IDsOfElements:
4832 IDsOfElements = self.GetElementsId()
4833 Functor = self.smeshpyD.GetFunctor(theCriterion)
4834 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4836 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4838 Fuse the neighbouring triangles of the object into quadrangles
4841 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4842 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4843 applied to possible quadrangles to choose a neighbour to fuse with.
4844 Note that not all items of :class:`SMESH.FunctorType` corresponds
4845 to numerical functors.
4846 MaxAngle: a max angle between element normals at which the fusion
4847 is still performed; theMaxAngle is measured in radians.
4850 True in case of success, False otherwise.
4853 This operation can create gaps in numeration of elements.
4854 Call :meth:`RenumberElements` to remove the gaps.
4857 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4858 self.mesh.SetParameters(Parameters)
4859 if isinstance( theObject, Mesh ):
4860 theObject = theObject.GetMesh()
4861 Functor = self.smeshpyD.GetFunctor(theCriterion)
4862 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4864 def QuadToTri (self, IDsOfElements, theCriterion = None):
4866 Split quadrangles into triangles.
4869 IDsOfElements: the faces to be splitted.
4870 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4871 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4872 value, then quadrangles will be split by the smallest diagonal.
4873 Note that not all items of :class:`SMESH.FunctorType` corresponds
4874 to numerical functors.
4877 True in case of success, False otherwise.
4880 This operation can create gaps in numeration of elements.
4881 Call :meth:`RenumberElements` to remove the gaps.
4883 if IDsOfElements == []:
4884 IDsOfElements = self.GetElementsId()
4885 if theCriterion is None:
4886 theCriterion = FT_MaxElementLength2D
4887 Functor = self.smeshpyD.GetFunctor(theCriterion)
4888 return self.editor.QuadToTri(IDsOfElements, Functor)
4890 def QuadToTriObject (self, theObject, theCriterion = None):
4892 Split quadrangles into triangles.
4895 theObject: the object from which the list of elements is taken,
4896 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4897 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4898 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4899 value, then quadrangles will be split by the smallest diagonal.
4900 Note that not all items of :class:`SMESH.FunctorType` corresponds
4901 to numerical functors.
4904 True in case of success, False otherwise.
4907 This operation can create gaps in numeration of elements.
4908 Call :meth:`RenumberElements` to remove the gaps.
4910 if ( isinstance( theObject, Mesh )):
4911 theObject = theObject.GetMesh()
4912 if theCriterion is None:
4913 theCriterion = FT_MaxElementLength2D
4914 Functor = self.smeshpyD.GetFunctor(theCriterion)
4915 return self.editor.QuadToTriObject(theObject, Functor)
4917 def QuadTo4Tri (self, theElements=[]):
4919 Split each of given quadrangles into 4 triangles. A node is added at the center of
4923 theElements: the faces to be splitted. This can be either
4924 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4925 or a list of face IDs. By default all quadrangles are split
4928 This operation can create gaps in numeration of elements.
4929 Call :meth:`RenumberElements` to remove the gaps.
4931 unRegister = genObjUnRegister()
4932 if isinstance( theElements, Mesh ):
4933 theElements = theElements.mesh
4934 elif not theElements:
4935 theElements = self.mesh
4936 elif isinstance( theElements, list ):
4937 theElements = self.GetIDSource( theElements, SMESH.FACE )
4938 unRegister.set( theElements )
4939 return self.editor.QuadTo4Tri( theElements )
4941 def SplitQuad (self, IDsOfElements, Diag13):
4943 Split quadrangles into triangles.
4946 IDsOfElements: the faces to be splitted
4947 Diag13 (boolean): is used to choose a diagonal for splitting.
4950 True in case of success, False otherwise.
4953 This operation can create gaps in numeration of elements.
4954 Call :meth:`RenumberElements` to remove the gaps.
4956 if IDsOfElements == []:
4957 IDsOfElements = self.GetElementsId()
4958 return self.editor.SplitQuad(IDsOfElements, Diag13)
4960 def SplitQuadObject (self, theObject, Diag13):
4962 Split quadrangles into triangles.
4965 theObject: the object from which the list of elements is taken,
4966 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4967 Diag13 (boolean): is used to choose a diagonal for splitting.
4970 True in case of success, False otherwise.
4973 This operation can create gaps in numeration of elements.
4974 Call :meth:`RenumberElements` to remove the gaps.
4976 if ( isinstance( theObject, Mesh )):
4977 theObject = theObject.GetMesh()
4978 return self.editor.SplitQuadObject(theObject, Diag13)
4980 def BestSplit (self, IDOfQuad, theCriterion):
4982 Find a better splitting of the given quadrangle.
4985 IDOfQuad: the ID of the quadrangle to be splitted.
4986 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4987 choose a diagonal for splitting.
4988 Note that not all items of :class:`SMESH.FunctorType` corresponds
4989 to numerical functors.
4992 * 1 if 1-3 diagonal is better,
4993 * 2 if 2-4 diagonal is better,
4994 * 0 if error occurs.
4997 This operation can create gaps in numeration of elements.
4998 Call :meth:`RenumberElements` to remove the gaps.
5000 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
5002 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
5004 Split volumic elements into tetrahedrons
5007 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5008 method: flags passing splitting method:
5009 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
5010 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
5013 This operation can create gaps in numeration of elements.
5014 Call :meth:`RenumberElements` to remove the gaps.
5016 unRegister = genObjUnRegister()
5017 if isinstance( elems, Mesh ):
5018 elems = elems.GetMesh()
5019 if ( isinstance( elems, list )):
5020 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5021 unRegister.set( elems )
5022 self.editor.SplitVolumesIntoTetra(elems, method)
5025 def SplitBiQuadraticIntoLinear(self, elems=None):
5027 Split bi-quadratic elements into linear ones without creation of additional nodes:
5029 - bi-quadratic triangle will be split into 3 linear quadrangles;
5030 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
5031 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
5033 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
5034 will be split in order to keep the mesh conformal.
5037 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
5038 if None (default), all bi-quadratic elements will be split
5041 This operation can create gaps in numeration of elements.
5042 Call :meth:`RenumberElements` to remove the gaps.
5044 unRegister = genObjUnRegister()
5045 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
5046 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
5047 unRegister.set( elems )
5049 elems = [ self.GetMesh() ]
5050 if isinstance( elems, Mesh ):
5051 elems = [ elems.GetMesh() ]
5052 if not isinstance( elems, list ):
5054 self.editor.SplitBiQuadraticIntoLinear( elems )
5056 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
5057 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
5059 Split hexahedra into prisms
5062 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5063 startHexPoint: a point used to find a hexahedron for which *facetNormal*
5064 gives a normal vector defining facets to split into triangles.
5065 *startHexPoint* can be either a triple of coordinates or a vertex.
5066 facetNormal: a normal to a facet to split into triangles of a
5067 hexahedron found by *startHexPoint*.
5068 *facetNormal* can be either a triple of coordinates or an edge.
5069 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
5070 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
5071 allDomains: if :code:`False`, only hexahedra adjacent to one closest
5072 to *startHexPoint* are split, else *startHexPoint*
5073 is used to find the facet to split in all domains present in *elems*.
5076 This operation can create gaps in numeration of elements.
5077 Call :meth:`RenumberElements` to remove the gaps.
5080 unRegister = genObjUnRegister()
5081 if isinstance( elems, Mesh ):
5082 elems = elems.GetMesh()
5083 if ( isinstance( elems, list )):
5084 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5085 unRegister.set( elems )
5088 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5089 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5090 elif isinstance( startHexPoint, list ):
5091 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5094 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5095 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5096 elif isinstance( facetNormal, list ):
5097 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5100 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5102 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5104 def SplitQuadsNearTriangularFacets(self):
5106 Split quadrangle faces near triangular facets of volumes
5109 This operation can create gaps in numeration of elements.
5110 Call :meth:`RenumberElements` to remove the gaps.
5112 faces_array = self.GetElementsByType(SMESH.FACE)
5113 for face_id in faces_array:
5114 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5115 quad_nodes = self.mesh.GetElemNodes(face_id)
5116 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5117 isVolumeFound = False
5118 for node1_elem in node1_elems:
5119 if not isVolumeFound:
5120 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5121 nb_nodes = self.GetElemNbNodes(node1_elem)
5122 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5123 volume_elem = node1_elem
5124 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5125 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5126 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5127 isVolumeFound = True
5128 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5129 self.SplitQuad([face_id], False) # diagonal 2-4
5130 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5131 isVolumeFound = True
5132 self.SplitQuad([face_id], True) # diagonal 1-3
5133 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5134 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5135 isVolumeFound = True
5136 self.SplitQuad([face_id], True) # diagonal 1-3
5138 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5140 Split hexahedrons into tetrahedrons.
5142 This operation uses :doc:`pattern_mapping` functionality for splitting.
5145 theObject: the object from which the list of hexahedrons is taken;
5146 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5147 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5148 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5149 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5150 key-point will be mapped into *theNode001*-th node of each volume.
5151 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5154 True in case of success, False otherwise.
5157 This operation can create gaps in numeration of elements.
5158 Call :meth:`RenumberElements` to remove the gaps.
5166 # (0,0,1) 4.---------.7 * |
5173 # (0,0,0) 0.---------.3
5174 pattern_tetra = "!!! Nb of points: \n 8 \n\
5184 !!! Indices of points of 6 tetras: \n\
5192 pattern = self.smeshpyD.GetPattern()
5193 isDone = pattern.LoadFromFile(pattern_tetra)
5195 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5198 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5199 isDone = pattern.MakeMesh(self.mesh, False, False)
5200 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5202 # split quafrangle faces near triangular facets of volumes
5203 self.SplitQuadsNearTriangularFacets()
5207 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5209 Split hexahedrons into prisms.
5211 Uses the :doc:`pattern_mapping` functionality for splitting.
5214 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5215 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5216 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5217 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5218 will be mapped into the *theNode001* -th node of each volume.
5219 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5222 True in case of success, False otherwise.
5225 This operation can create gaps in numeration of elements.
5226 Call :meth:`RenumberElements` to remove the gaps.
5228 # Pattern: 5.---------.6
5233 # (0,0,1) 4.---------.7 |
5240 # (0,0,0) 0.---------.3
5241 pattern_prism = "!!! Nb of points: \n 8 \n\
5251 !!! Indices of points of 2 prisms: \n\
5255 pattern = self.smeshpyD.GetPattern()
5256 isDone = pattern.LoadFromFile(pattern_prism)
5258 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5261 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5262 isDone = pattern.MakeMesh(self.mesh, False, False)
5263 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5265 # Split quafrangle faces near triangular facets of volumes
5266 self.SplitQuadsNearTriangularFacets()
5270 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5271 MaxNbOfIterations, MaxAspectRatio, Method):
5276 IDsOfElements: the list if ids of elements to smooth
5277 IDsOfFixedNodes: the list of ids of fixed nodes.
5278 Note that nodes built on edges and boundary nodes are always fixed.
5279 MaxNbOfIterations: the maximum number of iterations
5280 MaxAspectRatio: varies in range [1.0, inf]
5281 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5282 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5285 True in case of success, False otherwise.
5288 if IDsOfElements == []:
5289 IDsOfElements = self.GetElementsId()
5290 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5291 self.mesh.SetParameters(Parameters)
5292 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5293 MaxNbOfIterations, MaxAspectRatio, Method)
5295 def SmoothObject(self, theObject, IDsOfFixedNodes,
5296 MaxNbOfIterations, MaxAspectRatio, Method):
5298 Smooth elements which belong to the given object
5301 theObject: the object to smooth
5302 IDsOfFixedNodes: the list of ids of fixed nodes.
5303 Note that nodes built on edges and boundary nodes are always fixed.
5304 MaxNbOfIterations: the maximum number of iterations
5305 MaxAspectRatio: varies in range [1.0, inf]
5306 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5307 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5310 True in case of success, False otherwise.
5313 if ( isinstance( theObject, Mesh )):
5314 theObject = theObject.GetMesh()
5315 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5316 MaxNbOfIterations, MaxAspectRatio, Method)
5318 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5319 MaxNbOfIterations, MaxAspectRatio, Method):
5321 Parametrically smooth the given elements
5324 IDsOfElements: the list if ids of elements to smooth
5325 IDsOfFixedNodes: the list of ids of fixed nodes.
5326 Note that nodes built on edges and boundary nodes are always fixed.
5327 MaxNbOfIterations: the maximum number of iterations
5328 MaxAspectRatio: varies in range [1.0, inf]
5329 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5330 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5333 True in case of success, False otherwise.
5336 if IDsOfElements == []:
5337 IDsOfElements = self.GetElementsId()
5338 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5339 self.mesh.SetParameters(Parameters)
5340 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5341 MaxNbOfIterations, MaxAspectRatio, Method)
5343 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5344 MaxNbOfIterations, MaxAspectRatio, Method):
5346 Parametrically smooth the elements which belong to the given object
5349 theObject: the object to smooth
5350 IDsOfFixedNodes: the list of ids of fixed nodes.
5351 Note that nodes built on edges and boundary nodes are always fixed.
5352 MaxNbOfIterations: the maximum number of iterations
5353 MaxAspectRatio: varies in range [1.0, inf]
5354 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5355 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5358 True in case of success, False otherwise.
5361 if ( isinstance( theObject, Mesh )):
5362 theObject = theObject.GetMesh()
5363 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5364 MaxNbOfIterations, MaxAspectRatio, Method)
5366 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5368 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5369 them with quadratic with the same id.
5372 theForce3d: method of new node creation:
5374 * False - the medium node lies at the geometrical entity from which the mesh element is built
5375 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5376 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5377 theToBiQuad: If True, converts the mesh to bi-quadratic
5380 :class:`SMESH.ComputeError` which can hold a warning
5383 If *theSubMesh* is provided, the mesh can become non-conformal
5386 This operation can create gaps in numeration of nodes or elements.
5387 Call :meth:`RenumberElements` to remove the gaps.
5390 if isinstance( theSubMesh, Mesh ):
5391 theSubMesh = theSubMesh.mesh
5393 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5396 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5398 self.editor.ConvertToQuadratic(theForce3d)
5399 error = self.editor.GetLastError()
5400 if error and error.comment:
5401 print(error.comment)
5404 def ConvertFromQuadratic(self, theSubMesh=None):
5406 Convert the mesh from quadratic to ordinary,
5407 deletes old quadratic elements,
5408 replacing them with ordinary mesh elements with the same id.
5411 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5414 If *theSubMesh* is provided, the mesh can become non-conformal
5417 This operation can create gaps in numeration of nodes or elements.
5418 Call :meth:`RenumberElements` to remove the gaps.
5422 self.editor.ConvertFromQuadraticObject(theSubMesh)
5424 return self.editor.ConvertFromQuadratic()
5426 def Make2DMeshFrom3D(self):
5428 Create 2D mesh as skin on boundary faces of a 3D mesh
5431 True if operation has been completed successfully, False otherwise
5434 return self.editor.Make2DMeshFrom3D()
5436 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5437 toCopyElements=False, toCopyExistingBondary=False):
5439 Create missing boundary elements
5442 elements: elements whose boundary is to be checked:
5443 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5444 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5445 dimension: defines type of boundary elements to create, either of
5446 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5447 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5448 groupName: a name of group to store created boundary elements in,
5449 "" means not to create the group
5450 meshName: a name of new mesh to store created boundary elements in,
5451 "" means not to create the new mesh
5452 toCopyElements: if True, the checked elements will be copied into
5453 the new mesh else only boundary elements will be copied into the new mesh
5454 toCopyExistingBondary: if True, not only new but also pre-existing
5455 boundary elements will be copied into the new mesh
5458 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5461 unRegister = genObjUnRegister()
5462 if isinstance( elements, Mesh ):
5463 elements = elements.GetMesh()
5464 if ( isinstance( elements, list )):
5465 elemType = SMESH.ALL
5466 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5467 elements = self.editor.MakeIDSource(elements, elemType)
5468 unRegister.set( elements )
5469 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5470 toCopyElements,toCopyExistingBondary)
5471 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5474 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5475 toCopyAll=False, groups=[]):
5477 Create missing boundary elements around either the whole mesh or
5481 dimension: defines type of boundary elements to create, either of
5482 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5483 groupName: a name of group to store all boundary elements in,
5484 "" means not to create the group
5485 meshName: a name of a new mesh, which is a copy of the initial
5486 mesh + created boundary elements; "" means not to create the new mesh
5487 toCopyAll: if True, the whole initial mesh will be copied into
5488 the new mesh else only boundary elements will be copied into the new mesh
5489 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5492 tuple( long, mesh, group )
5493 - long - number of added boundary elements
5494 - mesh - the :class:`Mesh` where elements were added to
5495 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5498 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5500 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5501 return nb, mesh, group
5503 def RenumberNodes(self):
5505 Renumber mesh nodes to remove unused node IDs
5507 self.editor.RenumberNodes()
5509 def RenumberElements(self):
5511 Renumber mesh elements to remove unused element IDs
5513 self.editor.RenumberElements()
5515 def _getIdSourceList(self, arg, idType, unRegister):
5517 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5519 if arg and isinstance( arg, list ):
5520 if isinstance( arg[0], int ):
5521 arg = self.GetIDSource( arg, idType )
5522 unRegister.set( arg )
5523 elif isinstance( arg[0], Mesh ):
5524 arg[0] = arg[0].GetMesh()
5525 elif isinstance( arg, Mesh ):
5527 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5531 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5532 MakeGroups=False, TotalAngle=False):
5534 Generate new elements by rotation of the given elements and nodes around the axis
5537 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5538 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5539 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5540 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5541 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5542 which defines angle in degrees
5543 NbOfSteps: the number of steps
5544 Tolerance: tolerance
5545 MakeGroups: forces the generation of new groups from existing ones
5546 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5547 of all steps, else - size of each step
5550 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5553 unRegister = genObjUnRegister()
5554 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5555 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5556 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5558 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5559 Axis = self.smeshpyD.GetAxisStruct( Axis )
5560 if isinstance( Axis, list ):
5561 Axis = SMESH.AxisStruct( *Axis )
5563 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5564 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5565 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5566 self.mesh.SetParameters(Parameters)
5567 if TotalAngle and NbOfSteps:
5568 AngleInRadians /= NbOfSteps
5569 return self.editor.RotationSweepObjects( nodes, edges, faces,
5570 Axis, AngleInRadians,
5571 NbOfSteps, Tolerance, MakeGroups)
5573 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5574 MakeGroups=False, TotalAngle=False):
5576 Generate new elements by rotation of the elements around the axis
5579 IDsOfElements: the list of ids of elements to sweep
5580 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5581 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5582 NbOfSteps: the number of steps
5583 Tolerance: tolerance
5584 MakeGroups: forces the generation of new groups from existing ones
5585 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5586 of all steps, else - size of each step
5589 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5592 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5593 AngleInRadians, NbOfSteps, Tolerance,
5594 MakeGroups, TotalAngle)
5596 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5597 MakeGroups=False, TotalAngle=False):
5599 Generate new elements by rotation of the elements of object around the axis
5600 theObject object which elements should be sweeped.
5601 It can be a mesh, a sub mesh or a group.
5604 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5605 AngleInRadians: the angle of Rotation
5606 NbOfSteps: number of steps
5607 Tolerance: tolerance
5608 MakeGroups: forces the generation of new groups from existing ones
5609 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5610 of all steps, else - size of each step
5613 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5616 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5617 AngleInRadians, NbOfSteps, Tolerance,
5618 MakeGroups, TotalAngle )
5620 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5621 MakeGroups=False, TotalAngle=False):
5623 Generate new elements by rotation of the elements of object around the axis
5624 theObject object which elements should be sweeped.
5625 It can be a mesh, a sub mesh or a group.
5628 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5629 AngleInRadians: the angle of Rotation
5630 NbOfSteps: number of steps
5631 Tolerance: tolerance
5632 MakeGroups: forces the generation of new groups from existing ones
5633 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5634 of all steps, else - size of each step
5637 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5638 empty list otherwise
5641 return self.RotationSweepObjects([],theObject,[], Axis,
5642 AngleInRadians, NbOfSteps, Tolerance,
5643 MakeGroups, TotalAngle)
5645 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5646 MakeGroups=False, TotalAngle=False):
5648 Generate new elements by rotation of the elements of object around the axis
5649 theObject object which elements should be sweeped.
5650 It can be a mesh, a sub mesh or a group.
5653 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5654 AngleInRadians: the angle of Rotation
5655 NbOfSteps: number of steps
5656 Tolerance: tolerance
5657 MakeGroups: forces the generation of new groups from existing ones
5658 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5659 of all steps, else - size of each step
5662 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5665 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5666 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5668 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5669 scaleFactors=[], linearVariation=False, basePoint=[],
5670 angles=[], anglesVariation=False):
5672 Generate new elements by extrusion of the given elements and nodes
5675 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5676 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5677 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5678 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5679 the direction and value of extrusion for one step (the total extrusion
5680 length will be NbOfSteps * ||StepVector||)
5681 NbOfSteps: the number of steps
5682 MakeGroups: forces the generation of new groups from existing ones
5683 scaleFactors: optional scale factors to apply during extrusion
5684 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5685 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5686 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5687 nodes and elements being extruded is used as the scaling center.
5690 - a list of tree components of the point or
5693 angles: list of angles in radians. Nodes at each extrusion step are rotated
5694 around *basePoint*, additionally to previous steps.
5695 anglesVariation: forces the computation of rotation angles as linear
5696 variation of the given *angles* along path steps
5698 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5700 Example: :ref:`tui_extrusion`
5702 unRegister = genObjUnRegister()
5703 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5704 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5705 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5707 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5708 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5709 if isinstance( StepVector, list ):
5710 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5712 if isinstance( basePoint, int):
5713 xyz = self.GetNodeXYZ( basePoint )
5715 raise RuntimeError("Invalid node ID: %s" % basePoint)
5717 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5718 basePoint = self.geompyD.PointCoordinates( basePoint )
5720 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5721 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5722 angles,angleParameters,hasVars = ParseAngles(angles)
5723 Parameters = StepVector.PS.parameters + var_separator + \
5724 Parameters + var_separator + \
5725 scaleParameters + var_separator + angleParameters
5726 self.mesh.SetParameters(Parameters)
5728 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5729 StepVector, NbOfSteps, MakeGroups,
5730 scaleFactors, linearVariation, basePoint,
5731 angles, anglesVariation )
5734 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5736 Generate new elements by extrusion of the elements with given ids
5739 IDsOfElements: the list of ids of elements or nodes for extrusion
5740 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5741 the direction and value of extrusion for one step (the total extrusion
5742 length will be NbOfSteps * ||StepVector||)
5743 NbOfSteps: the number of steps
5744 MakeGroups: forces the generation of new groups from existing ones
5745 IsNodes: is True if elements with given ids are nodes
5748 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5750 Example: :ref:`tui_extrusion`
5753 if IsNodes: n = IDsOfElements
5754 else : e,f, = IDsOfElements,IDsOfElements
5755 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5757 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5758 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5760 Generate new elements by extrusion along the normal to a discretized surface or wire
5763 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5764 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5765 StepSize: length of one extrusion step (the total extrusion
5766 length will be *NbOfSteps* *StepSize*).
5767 NbOfSteps: number of extrusion steps.
5768 ByAverageNormal: if True each node is translated by *StepSize*
5769 along the average of the normal vectors to the faces sharing the node;
5770 else each node is translated along the same average normal till
5771 intersection with the plane got by translation of the face sharing
5772 the node along its own normal by *StepSize*.
5773 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5774 for every node of *Elements*.
5775 MakeGroups: forces generation of new groups from existing ones.
5776 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5777 is not yet implemented. This parameter is used if *Elements* contains
5778 both faces and edges, i.e. *Elements* is a Mesh.
5781 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5782 empty list otherwise.
5783 Example: :ref:`tui_extrusion`
5786 unRegister = genObjUnRegister()
5787 if isinstance( Elements, Mesh ):
5788 Elements = [ Elements.GetMesh() ]
5789 if isinstance( Elements, list ):
5791 raise RuntimeError("Elements empty!")
5792 if isinstance( Elements[0], Mesh ):
5793 Elements = [ Elements[0].GetMesh() ]
5794 if isinstance( Elements[0], int ):
5795 Elements = self.GetIDSource( Elements, SMESH.ALL )
5796 unRegister.set( Elements )
5797 if not isinstance( Elements, list ):
5798 Elements = [ Elements ]
5799 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5800 self.mesh.SetParameters(Parameters)
5801 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5802 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5804 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5806 Generate new elements by extrusion of the elements or nodes which belong to the object
5809 theObject: the object whose elements or nodes should be processed.
5810 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5811 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5812 the direction and value of extrusion for one step (the total extrusion
5813 length will be NbOfSteps * ||StepVector||)
5814 NbOfSteps: the number of steps
5815 MakeGroups: forces the generation of new groups from existing ones
5816 IsNodes: is True if elements to extrude are nodes
5819 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5820 Example: :ref:`tui_extrusion`
5824 if IsNodes: n = theObject
5825 else : e,f, = theObject,theObject
5826 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5828 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5830 Generate new elements by extrusion of edges which belong to the object
5833 theObject: object whose 1D elements should be processed.
5834 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5835 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5836 the direction and value of extrusion for one step (the total extrusion
5837 length will be NbOfSteps * ||StepVector||)
5838 NbOfSteps: the number of steps
5839 MakeGroups: to generate new groups from existing ones
5842 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5843 Example: :ref:`tui_extrusion`
5846 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5848 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5850 Generate new elements by extrusion of faces which belong to the object
5853 theObject: object whose 2D elements should be processed.
5854 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5855 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5856 the direction and value of extrusion for one step (the total extrusion
5857 length will be NbOfSteps * ||StepVector||)
5858 NbOfSteps: the number of steps
5859 MakeGroups: forces the generation of new groups from existing ones
5862 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5863 Example: :ref:`tui_extrusion`
5866 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5868 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5869 ExtrFlags, SewTolerance, MakeGroups=False):
5871 Generate new elements by extrusion of the elements with given ids
5874 IDsOfElements: is ids of elements
5875 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5876 the direction and value of extrusion for one step (the total extrusion
5877 length will be NbOfSteps * ||StepVector||)
5878 NbOfSteps: the number of steps
5879 ExtrFlags: sets flags for extrusion
5880 SewTolerance: uses for comparing locations of nodes if flag
5881 EXTRUSION_FLAG_SEW is set
5882 MakeGroups: forces the generation of new groups from existing ones
5885 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5888 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5889 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5890 if isinstance( StepVector, list ):
5891 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5892 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5893 ExtrFlags, SewTolerance, MakeGroups)
5895 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5896 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5897 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5898 ScaleFactors=[], ScalesVariation=False):
5900 Generate new elements by extrusion of the given elements and nodes along the path.
5901 The path of extrusion must be a meshed edge.
5904 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5905 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5906 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5907 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5908 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
5909 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5910 HasAngles: not used obsolete
5911 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5912 around *basePoint*, additionally to previous steps.
5913 LinearVariation: forces the computation of rotation angles as linear
5914 variation of the given Angles along path steps
5915 HasRefPoint: allows using the reference point
5916 RefPoint: optional scaling and rotation center (mass center of the extruded
5917 elements by default). The User can specify any point as the Reference Point.
5918 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5919 MakeGroups: forces the generation of new groups from existing ones
5920 ScaleFactors: optional scale factors to apply during extrusion
5921 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5922 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5925 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5926 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5927 Example: :ref:`tui_extrusion_along_path`
5930 unRegister = genObjUnRegister()
5931 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5932 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5933 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5935 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5936 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5937 if isinstance( RefPoint, list ):
5938 if not RefPoint: RefPoint = [0,0,0]
5939 RefPoint = SMESH.PointStruct( *RefPoint )
5940 if isinstance( PathObject, Mesh ):
5941 PathObject = PathObject.GetMesh()
5942 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5943 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5944 Parameters = AnglesParameters + var_separator + \
5945 RefPoint.parameters + var_separator + ScalesParameters
5946 self.mesh.SetParameters(Parameters)
5947 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5948 PathObject, PathShape, NodeStart,
5949 HasAngles, Angles, LinearVariation,
5950 HasRefPoint, RefPoint, MakeGroups,
5951 ScaleFactors, ScalesVariation)
5953 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5954 HasAngles=False, Angles=[], LinearVariation=False,
5955 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5956 ElemType=SMESH.FACE):
5958 Generate new elements by extrusion of the given elements.
5959 The path of extrusion must be a meshed edge.
5962 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5963 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5964 NodeStart: the start node from Path. Defines the direction of extrusion
5965 HasAngles: not used obsolete
5966 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5967 around *basePoint*, additionally to previous steps.
5968 LinearVariation: forces the computation of rotation angles as linear
5969 variation of the given Angles along path steps
5970 HasRefPoint: allows using the reference point
5971 RefPoint: the reference point around which the elements are rotated (the mass
5972 center of the elements by default).
5973 The User can specify any point as the Reference Point.
5974 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5975 MakeGroups: forces the generation of new groups from existing ones
5976 ElemType: type of elements for extrusion (if param Base is a mesh)
5979 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5980 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5981 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5983 Example: :ref:`tui_extrusion_along_path`
5987 if ElemType == SMESH.NODE: n = Base
5988 if ElemType == SMESH.EDGE: e = Base
5989 if ElemType == SMESH.FACE: f = Base
5990 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5991 HasAngles, Angles, LinearVariation,
5992 HasRefPoint, RefPoint, MakeGroups)
5993 if MakeGroups: return gr,er
5996 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5997 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5998 MakeGroups=False, LinearVariation=False):
6000 Generate new elements by extrusion of the given elements.
6001 The path of extrusion must be a meshed edge.
6004 IDsOfElements: ids of elements
6005 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
6006 PathShape: shape (edge) defines the sub-mesh for the path
6007 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6008 HasAngles: not used obsolete
6009 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6010 around *basePoint*, additionally to previous steps.
6011 HasRefPoint: allows using the reference point
6012 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6013 The User can specify any point as the Reference Point.
6014 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6015 MakeGroups: forces the generation of new groups from existing ones
6016 LinearVariation: forces the computation of rotation angles as linear
6017 variation of the given Angles along path steps
6020 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6021 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6022 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6023 Example: :ref:`tui_extrusion_along_path`
6026 if not IDsOfElements:
6027 IDsOfElements = [ self.GetMesh() ]
6028 n,e,f = [],IDsOfElements,IDsOfElements
6029 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
6030 NodeStart, HasAngles, Angles,
6032 HasRefPoint, RefPoint, MakeGroups)
6033 if MakeGroups: return gr,er
6036 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
6037 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6038 MakeGroups=False, LinearVariation=False):
6040 Generate new elements by extrusion of the elements which belong to the object.
6041 The path of extrusion must be a meshed edge.
6044 theObject: the object whose elements should be processed.
6045 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6046 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6047 PathShape: shape (edge) defines the sub-mesh for the path
6048 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6049 HasAngles: not used obsolete
6050 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6051 around *basePoint*, additionally to previous steps.
6052 HasRefPoint: allows using the reference point
6053 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6054 The User can specify any point as the Reference Point.
6055 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6056 MakeGroups: forces the generation of new groups from existing ones
6057 LinearVariation: forces the computation of rotation angles as linear
6058 variation of the given Angles along path steps
6061 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6062 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6063 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6064 Example: :ref:`tui_extrusion_along_path`
6067 n,e,f = [],theObject,theObject
6068 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6069 HasAngles, Angles, LinearVariation,
6070 HasRefPoint, RefPoint, MakeGroups)
6071 if MakeGroups: return gr,er
6074 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
6075 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6076 MakeGroups=False, LinearVariation=False):
6078 Generate new elements by extrusion of mesh segments which belong to the object.
6079 The path of extrusion must be a meshed edge.
6082 theObject: the object whose 1D elements should be processed.
6083 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6084 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6085 PathShape: shape (edge) defines the sub-mesh for the path
6086 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6087 HasAngles: not used obsolete
6088 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6089 around *basePoint*, additionally to previous steps.
6090 HasRefPoint: allows using the reference point
6091 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6092 The User can specify any point as the Reference Point.
6093 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6094 MakeGroups: forces the generation of new groups from existing ones
6095 LinearVariation: forces the computation of rotation angles as linear
6096 variation of the given Angles along path steps
6099 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6100 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6101 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6102 Example: :ref:`tui_extrusion_along_path`
6105 n,e,f = [],theObject,[]
6106 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6107 HasAngles, Angles, LinearVariation,
6108 HasRefPoint, RefPoint, MakeGroups)
6109 if MakeGroups: return gr,er
6112 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6113 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6114 MakeGroups=False, LinearVariation=False):
6116 Generate new elements by extrusion of faces which belong to the object.
6117 The path of extrusion must be a meshed edge.
6120 theObject: the object whose 2D elements should be processed.
6121 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6122 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6123 PathShape: shape (edge) defines the sub-mesh for the path
6124 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6125 HasAngles: not used obsolete
6126 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6127 around *basePoint*, additionally to previous steps.
6128 HasRefPoint: allows using the reference point
6129 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6130 The User can specify any point as the Reference Point.
6131 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6132 MakeGroups: forces the generation of new groups from existing ones
6133 LinearVariation: forces the computation of rotation angles as linear
6134 variation of the given Angles along path steps
6137 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6138 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6139 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6140 Example: :ref:`tui_extrusion_along_path`
6143 n,e,f = [],[],theObject
6144 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6145 HasAngles, Angles, LinearVariation,
6146 HasRefPoint, RefPoint, MakeGroups)
6147 if MakeGroups: return gr,er
6150 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6152 Create a symmetrical copy of mesh elements
6155 IDsOfElements: list of elements ids
6156 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6157 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6158 If the *Mirror* is a geom object this parameter is unnecessary
6159 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6160 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6163 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6166 if IDsOfElements == []:
6167 IDsOfElements = self.GetElementsId()
6168 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6169 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6170 theMirrorType = Mirror._mirrorType
6172 self.mesh.SetParameters(Mirror.parameters)
6173 if Copy and MakeGroups:
6174 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6175 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6178 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6180 Create a new mesh by a symmetrical copy of mesh elements
6183 IDsOfElements: the list of elements ids
6184 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6185 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6186 If the *Mirror* is a geom object this parameter is unnecessary
6187 MakeGroups: to generate new groups from existing ones
6188 NewMeshName: a name of the new mesh to create
6191 instance of class :class:`Mesh`
6194 if IDsOfElements == []:
6195 IDsOfElements = self.GetElementsId()
6196 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6197 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6198 theMirrorType = Mirror._mirrorType
6200 self.mesh.SetParameters(Mirror.parameters)
6201 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6202 MakeGroups, NewMeshName)
6203 return Mesh(self.smeshpyD,self.geompyD,mesh)
6205 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6207 Create a symmetrical copy of the object
6210 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6211 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6212 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6213 If the *Mirror* is a geom object this parameter is unnecessary
6214 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6215 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6218 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6221 if ( isinstance( theObject, Mesh )):
6222 theObject = theObject.GetMesh()
6223 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6224 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6225 theMirrorType = Mirror._mirrorType
6227 self.mesh.SetParameters(Mirror.parameters)
6228 if Copy and MakeGroups:
6229 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6230 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6233 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6235 Create a new mesh by a symmetrical copy of the object
6238 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6239 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6240 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6241 If the *Mirror* is a geom object this parameter is unnecessary
6242 MakeGroups: forces the generation of new groups from existing ones
6243 NewMeshName: the name of the new mesh to create
6246 instance of class :class:`Mesh`
6249 if ( isinstance( theObject, Mesh )):
6250 theObject = theObject.GetMesh()
6251 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6252 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6253 theMirrorType = Mirror._mirrorType
6255 self.mesh.SetParameters(Mirror.parameters)
6256 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6257 MakeGroups, NewMeshName)
6258 return Mesh( self.smeshpyD,self.geompyD,mesh )
6260 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6262 Translate the elements
6265 IDsOfElements: list of elements ids
6266 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6267 Copy: allows copying the translated elements
6268 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6271 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6274 if IDsOfElements == []:
6275 IDsOfElements = self.GetElementsId()
6276 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6277 Vector = self.smeshpyD.GetDirStruct(Vector)
6278 if isinstance( Vector, list ):
6279 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6280 self.mesh.SetParameters(Vector.PS.parameters)
6281 if Copy and MakeGroups:
6282 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6283 self.editor.Translate(IDsOfElements, Vector, Copy)
6286 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6288 Create a new mesh of translated elements
6291 IDsOfElements: list of elements ids
6292 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6293 MakeGroups: forces the generation of new groups from existing ones
6294 NewMeshName: the name of the newly created mesh
6297 instance of class :class:`Mesh`
6300 if IDsOfElements == []:
6301 IDsOfElements = self.GetElementsId()
6302 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6303 Vector = self.smeshpyD.GetDirStruct(Vector)
6304 if isinstance( Vector, list ):
6305 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6306 self.mesh.SetParameters(Vector.PS.parameters)
6307 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6308 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6310 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6312 Translate the object
6315 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6316 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6317 Copy: allows copying the translated elements
6318 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6321 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6324 if ( isinstance( theObject, Mesh )):
6325 theObject = theObject.GetMesh()
6326 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6327 Vector = self.smeshpyD.GetDirStruct(Vector)
6328 if isinstance( Vector, list ):
6329 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6330 self.mesh.SetParameters(Vector.PS.parameters)
6331 if Copy and MakeGroups:
6332 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6333 self.editor.TranslateObject(theObject, Vector, Copy)
6336 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6338 Create a new mesh from the translated object
6341 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6342 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6343 MakeGroups: forces the generation of new groups from existing ones
6344 NewMeshName: the name of the newly created mesh
6347 instance of class :class:`Mesh`
6350 if isinstance( theObject, Mesh ):
6351 theObject = theObject.GetMesh()
6352 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6353 Vector = self.smeshpyD.GetDirStruct(Vector)
6354 if isinstance( Vector, list ):
6355 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6356 self.mesh.SetParameters(Vector.PS.parameters)
6357 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6358 return Mesh( self.smeshpyD, self.geompyD, mesh )
6362 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6367 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6368 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6369 theScaleFact: list of 1-3 scale factors for axises
6370 Copy: allows copying the translated elements
6371 MakeGroups: forces the generation of new groups from existing
6375 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6376 empty list otherwise
6378 unRegister = genObjUnRegister()
6379 if ( isinstance( theObject, Mesh )):
6380 theObject = theObject.GetMesh()
6381 if ( isinstance( theObject, list )):
6382 theObject = self.GetIDSource(theObject, SMESH.ALL)
6383 unRegister.set( theObject )
6384 if ( isinstance( thePoint, list )):
6385 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6386 if ( isinstance( theScaleFact, float )):
6387 theScaleFact = [theScaleFact]
6388 if ( isinstance( theScaleFact, int )):
6389 theScaleFact = [ float(theScaleFact)]
6391 self.mesh.SetParameters(thePoint.parameters)
6393 if Copy and MakeGroups:
6394 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6395 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6398 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6400 Create a new mesh from the translated object
6403 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6404 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6405 theScaleFact: list of 1-3 scale factors for axises
6406 MakeGroups: forces the generation of new groups from existing ones
6407 NewMeshName: the name of the newly created mesh
6410 instance of class :class:`Mesh`
6412 unRegister = genObjUnRegister()
6413 if (isinstance(theObject, Mesh)):
6414 theObject = theObject.GetMesh()
6415 if ( isinstance( theObject, list )):
6416 theObject = self.GetIDSource(theObject,SMESH.ALL)
6417 unRegister.set( theObject )
6418 if ( isinstance( thePoint, list )):
6419 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6420 if ( isinstance( theScaleFact, float )):
6421 theScaleFact = [theScaleFact]
6422 if ( isinstance( theScaleFact, int )):
6423 theScaleFact = [ float(theScaleFact)]
6425 self.mesh.SetParameters(thePoint.parameters)
6426 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6427 MakeGroups, NewMeshName)
6428 return Mesh( self.smeshpyD, self.geompyD, mesh )
6432 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6437 IDsOfElements: list of elements ids
6438 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6439 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6440 Copy: allows copying the rotated elements
6441 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6444 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6448 if IDsOfElements == []:
6449 IDsOfElements = self.GetElementsId()
6450 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6451 Axis = self.smeshpyD.GetAxisStruct(Axis)
6452 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6453 Parameters = Axis.parameters + var_separator + Parameters
6454 self.mesh.SetParameters(Parameters)
6455 if Copy and MakeGroups:
6456 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6457 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6460 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6462 Create a new mesh of rotated elements
6465 IDsOfElements: list of element ids
6466 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6467 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6468 MakeGroups: forces the generation of new groups from existing ones
6469 NewMeshName: the name of the newly created mesh
6472 instance of class :class:`Mesh`
6475 if IDsOfElements == []:
6476 IDsOfElements = self.GetElementsId()
6477 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6478 Axis = self.smeshpyD.GetAxisStruct(Axis)
6479 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6480 Parameters = Axis.parameters + var_separator + Parameters
6481 self.mesh.SetParameters(Parameters)
6482 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6483 MakeGroups, NewMeshName)
6484 return Mesh( self.smeshpyD, self.geompyD, mesh )
6486 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6491 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6492 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6493 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6494 Copy: allows copying the rotated elements
6495 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6498 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6501 if (isinstance(theObject, Mesh)):
6502 theObject = theObject.GetMesh()
6503 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6504 Axis = self.smeshpyD.GetAxisStruct(Axis)
6505 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6506 Parameters = Axis.parameters + ":" + Parameters
6507 self.mesh.SetParameters(Parameters)
6508 if Copy and MakeGroups:
6509 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6510 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6513 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6515 Create a new mesh from the rotated object
6518 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6519 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6520 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6521 MakeGroups: forces the generation of new groups from existing ones
6522 NewMeshName: the name of the newly created mesh
6525 instance of class :class:`Mesh`
6528 if (isinstance( theObject, Mesh )):
6529 theObject = theObject.GetMesh()
6530 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6531 Axis = self.smeshpyD.GetAxisStruct(Axis)
6532 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6533 Parameters = Axis.parameters + ":" + Parameters
6534 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6535 MakeGroups, NewMeshName)
6536 self.mesh.SetParameters(Parameters)
6537 return Mesh( self.smeshpyD, self.geompyD, mesh )
6539 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6541 Create an offset mesh from the given 2D object
6544 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6545 theValue (float): signed offset size
6546 MakeGroups (boolean): forces the generation of new groups from existing ones
6547 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6548 False means to remove original elements.
6549 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6552 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6555 if isinstance( theObject, Mesh ):
6556 theObject = theObject.GetMesh()
6557 theValue,Parameters,hasVars = ParseParameters(Value)
6558 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6559 self.mesh.SetParameters(Parameters)
6561 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6564 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6566 Find groups of adjacent nodes within Tolerance.
6569 Tolerance (float): the value of tolerance
6570 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6571 corner and medium nodes in separate groups thus preventing
6572 their further merge.
6575 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6578 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6580 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6581 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6583 Find groups of adjacent nodes within Tolerance.
6586 Tolerance: the value of tolerance
6587 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6588 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6589 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6590 corner and medium nodes in separate groups thus preventing
6591 their further merge.
6594 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6597 unRegister = genObjUnRegister()
6598 if not isinstance( SubMeshOrGroup, list ):
6599 SubMeshOrGroup = [ SubMeshOrGroup ]
6600 for i,obj in enumerate( SubMeshOrGroup ):
6601 if isinstance( obj, Mesh ):
6602 SubMeshOrGroup = [ obj.GetMesh() ]
6604 if isinstance( obj, int ):
6605 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6606 unRegister.set( SubMeshOrGroup )
6609 if not isinstance( exceptNodes, list ):
6610 exceptNodes = [ exceptNodes ]
6611 if exceptNodes and isinstance( exceptNodes[0], int ):
6612 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6613 unRegister.set( exceptNodes )
6615 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6616 exceptNodes, SeparateCornerAndMediumNodes)
6618 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6623 GroupsOfNodes: a list of groups of nodes IDs for merging.
6624 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6625 in all elements and mesh groups by nodes 1 and 25 correspondingly
6626 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6627 If *NodesToKeep* does not include a node to keep for some group to merge,
6628 then the first node in the group is kept.
6629 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6633 This operation can create gaps in numeration of nodes or elements.
6634 Call :meth:`RenumberElements` to remove the gaps.
6636 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6638 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6640 Find the elements built on the same nodes.
6643 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6644 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6648 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6651 unRegister = genObjUnRegister()
6652 if MeshOrSubMeshOrGroup is None:
6653 MeshOrSubMeshOrGroup = [ self.mesh ]
6654 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6655 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6656 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6657 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6658 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6659 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6660 unRegister.set( MeshOrSubMeshOrGroup )
6661 for item in MeshOrSubMeshOrGroup:
6662 if isinstance( item, Mesh ):
6663 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6665 if not isinstance( exceptElements, list ):
6666 exceptElements = [ exceptElements ]
6667 if exceptElements and isinstance( exceptElements[0], int ):
6668 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6669 unRegister.set( exceptElements )
6671 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6673 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6675 Merge elements in each given group.
6678 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6679 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6680 replaced in all mesh groups by elements 1 and 25)
6681 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6682 If *ElementsToKeep* does not include an element to keep for some group to merge,
6683 then the first element in the group is kept.
6686 This operation can create gaps in numeration of elements.
6687 Call :meth:`RenumberElements` to remove the gaps.
6690 unRegister = genObjUnRegister()
6692 if not isinstance( ElementsToKeep, list ):
6693 ElementsToKeep = [ ElementsToKeep ]
6694 if isinstance( ElementsToKeep[0], int ):
6695 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6696 unRegister.set( ElementsToKeep )
6698 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6700 def MergeEqualElements(self):
6702 Leave one element and remove all other elements built on the same nodes.
6705 This operation can create gaps in numeration of elements.
6706 Call :meth:`RenumberElements` to remove the gaps.
6709 self.editor.MergeEqualElements()
6711 def FindFreeBorders(self, ClosedOnly=True):
6713 Returns all or only closed free borders
6716 list of SMESH.FreeBorder's
6719 return self.editor.FindFreeBorders( ClosedOnly )
6721 def FillHole(self, holeNodes, groupName=""):
6723 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6726 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6727 must describe all sequential nodes of the hole border. The first and the last
6728 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6729 groupName (string): name of a group to add new faces
6731 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6735 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6736 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6737 if not isinstance( holeNodes, SMESH.FreeBorder ):
6738 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6739 return self.editor.FillHole( holeNodes, groupName )
6741 def FindCoincidentFreeBorders (self, tolerance=0.):
6743 Return groups of FreeBorder's coincident within the given tolerance.
6746 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6747 size of elements adjacent to free borders being compared is used.
6750 SMESH.CoincidentFreeBorders structure
6753 return self.editor.FindCoincidentFreeBorders( tolerance )
6755 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6757 Sew FreeBorder's of each group
6760 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6761 where each enclosed list contains node IDs of a group of coincident free
6762 borders such that each consequent triple of IDs within a group describes
6763 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6764 last node of a border.
6765 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6766 groups of coincident free borders, each group including two borders.
6767 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6768 polygons if a node of opposite border falls on a face edge, else such
6769 faces are split into several ones.
6770 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6771 polyhedra if a node of opposite border falls on a volume edge, else such
6772 volumes, if any, remain intact and the mesh becomes non-conformal.
6775 a number of successfully sewed groups
6778 This operation can create gaps in numeration of nodes or elements.
6779 Call :meth:`RenumberElements` to remove the gaps.
6782 if freeBorders and isinstance( freeBorders, list ):
6783 # construct SMESH.CoincidentFreeBorders
6784 if isinstance( freeBorders[0], int ):
6785 freeBorders = [freeBorders]
6787 coincidentGroups = []
6788 for nodeList in freeBorders:
6789 if not nodeList or len( nodeList ) % 3:
6790 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6793 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6794 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6795 nodeList = nodeList[3:]
6797 coincidentGroups.append( group )
6799 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6801 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6803 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6804 FirstNodeID2, SecondNodeID2, LastNodeID2,
6805 CreatePolygons, CreatePolyedrs):
6810 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6813 This operation can create gaps in numeration of nodes or elements.
6814 Call :meth:`RenumberElements` to remove the gaps.
6817 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6818 FirstNodeID2, SecondNodeID2, LastNodeID2,
6819 CreatePolygons, CreatePolyedrs)
6821 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6822 FirstNodeID2, SecondNodeID2):
6824 Sew conform free borders
6827 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6830 This operation can create gaps in numeration of elements.
6831 Call :meth:`RenumberElements` to remove the gaps.
6834 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6835 FirstNodeID2, SecondNodeID2)
6837 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6838 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6843 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6846 This operation can create gaps in numeration of elements.
6847 Call :meth:`RenumberElements` to remove the gaps.
6850 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6851 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6853 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6854 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6855 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6857 Sew two sides of a mesh. The nodes belonging to Side1 are
6858 merged with the nodes of elements of Side2.
6859 The number of elements in theSide1 and in theSide2 must be
6860 equal and they should have similar nodal connectivity.
6861 The nodes to merge should belong to side borders and
6862 the first node should be linked to the second.
6865 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6868 This operation can create gaps in numeration of nodes.
6869 Call :meth:`RenumberElements` to remove the gaps.
6872 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6873 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6874 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6876 def ChangeElemNodes(self, ide, newIDs):
6878 Set new nodes for the given element. Number of nodes should be kept.
6885 False if the number of nodes does not correspond to the type of element
6888 return self.editor.ChangeElemNodes(ide, newIDs)
6890 def GetLastCreatedNodes(self):
6892 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6893 created, this method return the list of their IDs.
6894 If new nodes were not created - return empty list
6897 the list of integer values (can be empty)
6900 return self.editor.GetLastCreatedNodes()
6902 def GetLastCreatedElems(self):
6904 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6905 created this method return the list of their IDs.
6906 If new elements were not created - return empty list
6909 the list of integer values (can be empty)
6912 return self.editor.GetLastCreatedElems()
6914 def ClearLastCreated(self):
6916 Forget what nodes and elements were created by the last mesh edition operation
6919 self.editor.ClearLastCreated()
6921 def DoubleElements(self, theElements, theGroupName=""):
6923 Create duplicates of given elements, i.e. create new elements based on the
6924 same nodes as the given ones.
6927 theElements: container of elements to duplicate. It can be a
6928 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6929 or a list of element IDs. If *theElements* is
6930 a :class:`Mesh`, elements of highest dimension are duplicated
6931 theGroupName: a name of group to contain the generated elements.
6932 If a group with such a name already exists, the new elements
6933 are added to the existing group, else a new group is created.
6934 If *theGroupName* is empty, new elements are not added
6938 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6939 None if *theGroupName* == "".
6942 unRegister = genObjUnRegister()
6943 if isinstance( theElements, Mesh ):
6944 theElements = theElements.mesh
6945 elif isinstance( theElements, list ):
6946 theElements = self.GetIDSource( theElements, SMESH.ALL )
6947 unRegister.set( theElements )
6948 return self.editor.DoubleElements(theElements, theGroupName)
6950 def DoubleNodes(self, theNodes, theModifiedElems):
6952 Create a hole in a mesh by doubling the nodes of some particular elements
6955 theNodes: IDs of nodes to be doubled
6956 theModifiedElems: IDs of elements to be updated by the new (doubled)
6957 nodes. If list of element identifiers is empty then nodes are doubled but
6958 they not assigned to elements
6961 True if operation has been completed successfully, False otherwise
6964 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6966 def DoubleNode(self, theNodeId, theModifiedElems):
6968 Create a hole in a mesh by doubling the nodes of some particular elements.
6969 This method provided for convenience works as :meth:`DoubleNodes`.
6972 theNodeId: IDs of node to double
6973 theModifiedElems: IDs of elements to update
6976 True if operation has been completed successfully, False otherwise
6979 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6981 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6983 Create a hole in a mesh by doubling the nodes of some particular elements.
6984 This method provided for convenience works as :meth:`DoubleNodes`.
6987 theNodes: group of nodes to double.
6988 theModifiedElems: group of elements to update.
6989 theMakeGroup: forces the generation of a group containing new nodes.
6992 True or a created group if operation has been completed successfully,
6993 False or None otherwise
6997 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6998 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
7000 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
7002 Create a hole in a mesh by doubling the nodes of some particular elements.
7003 This method provided for convenience works as :meth:`DoubleNodes`.
7006 theNodes: list of groups of nodes to double.
7007 theModifiedElems: list of groups of elements to update.
7008 theMakeGroup: forces the generation of a group containing new nodes.
7011 True if operation has been completed successfully, False otherwise
7015 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
7016 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
7018 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
7020 Create a hole in a mesh by doubling the nodes of some particular elements
7023 theElems: the list of elements (edges or faces) to replicate.
7024 The nodes for duplication could be found from these elements
7025 theNodesNot: list of nodes NOT to replicate
7026 theAffectedElems: the list of elements (cells and edges) to which the
7027 replicated nodes should be associated to
7030 True if operation has been completed successfully, False otherwise
7033 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
7035 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
7037 Create a hole in a mesh by doubling the nodes of some particular elements
7040 theElems: the list of elements (edges or faces) to replicate.
7041 The nodes for duplication could be found from these elements
7042 theNodesNot: list of nodes NOT to replicate
7043 theShape: shape to detect affected elements (element which geometric center
7044 located on or inside shape).
7045 The replicated nodes should be associated to affected elements.
7048 True if operation has been completed successfully, False otherwise
7051 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
7053 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
7054 theMakeGroup=False, theMakeNodeGroup=False):
7056 Create a hole in a mesh by doubling the nodes of some particular elements.
7057 This method provided for convenience works as :meth:`DoubleNodes`.
7060 theElems: group of of elements (edges or faces) to replicate.
7061 theNodesNot: group of nodes NOT to replicate.
7062 theAffectedElems: group of elements to which the replicated nodes
7063 should be associated to.
7064 theMakeGroup: forces the generation of a group containing new elements.
7065 theMakeNodeGroup: forces the generation of a group containing new nodes.
7068 True or created groups (one or two) if operation has been completed successfully,
7069 False or None otherwise
7072 if theMakeGroup or theMakeNodeGroup:
7073 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
7075 theMakeGroup, theMakeNodeGroup)
7076 if theMakeGroup and theMakeNodeGroup:
7079 return twoGroups[ int(theMakeNodeGroup) ]
7080 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7082 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7084 Create a hole in a mesh by doubling the nodes of some particular elements.
7085 This method provided for convenience works as :meth:`DoubleNodes`.
7088 theElems: group of of elements (edges or faces) to replicate
7089 theNodesNot: group of nodes not to replicate
7090 theShape: shape to detect affected elements (element which geometric center
7091 located on or inside shape).
7092 The replicated nodes should be associated to affected elements
7095 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7097 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7098 theMakeGroup=False, theMakeNodeGroup=False):
7100 Create a hole in a mesh by doubling the nodes of some particular elements.
7101 This method provided for convenience works as :meth:`DoubleNodes`.
7104 theElems: list of groups of elements (edges or faces) to replicate
7105 theNodesNot: list of groups of nodes NOT to replicate
7106 theAffectedElems: group of elements to which the replicated nodes
7107 should be associated to
7108 theMakeGroup: forces generation of a group containing new elements.
7109 theMakeNodeGroup: forces generation of a group containing new nodes
7112 True or created groups (one or two) if operation has been completed successfully,
7113 False or None otherwise
7116 if theMakeGroup or theMakeNodeGroup:
7117 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7119 theMakeGroup, theMakeNodeGroup)
7120 if theMakeGroup and theMakeNodeGroup:
7123 return twoGroups[ int(theMakeNodeGroup) ]
7124 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7126 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7128 Create a hole in a mesh by doubling the nodes of some particular elements.
7129 This method provided for convenience works as :meth:`DoubleNodes`.
7132 theElems: list of groups of elements (edges or faces) to replicate
7133 theNodesNot: list of groups of nodes NOT to replicate
7134 theShape: shape to detect affected elements (element which geometric center
7135 located on or inside shape).
7136 The replicated nodes should be associated to affected elements
7139 True if operation has been completed successfully, False otherwise
7142 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7144 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7146 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7147 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7150 theElems: list of groups of nodes or elements (edges or faces) to replicate
7151 theNodesNot: list of groups of nodes NOT to replicate
7152 theShape: shape to detect affected elements (element which geometric center
7153 located on or inside shape).
7154 The replicated nodes should be associated to affected elements
7157 groups of affected elements in order: volumes, faces, edges
7160 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7162 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7165 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7166 The list of groups must describe a partition of the mesh volumes.
7167 The nodes of the internal faces at the boundaries of the groups are doubled.
7168 In option, the internal faces are replaced by flat elements.
7169 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7172 theDomains: list of groups of volumes
7173 createJointElems: if True, create the elements
7174 onAllBoundaries: if True, the nodes and elements are also created on
7175 the boundary between *theDomains* and the rest mesh
7178 True if operation has been completed successfully, False otherwise
7181 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7183 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7185 Double nodes on some external faces and create flat elements.
7186 Flat elements are mainly used by some types of mechanic calculations.
7188 Each group of the list must be constituted of faces.
7189 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7192 theGroupsOfFaces: list of groups of faces
7195 True if operation has been completed successfully, False otherwise
7198 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7200 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7202 Identify all the elements around a geom shape, get the faces delimiting the hole
7204 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7206 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7208 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7209 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7210 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7211 If there are several paths connecting a pair of points, the shortest path is
7212 selected by the module. Position of the cutting plane is defined by the two
7213 points and an optional vector lying on the plane specified by a PolySegment.
7214 By default the vector is defined by Mesh module as following. A middle point
7215 of the two given points is computed. The middle point is projected to the mesh.
7216 The vector goes from the middle point to the projection point. In case of planar
7217 mesh, the vector is normal to the mesh.
7219 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7222 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7223 groupName: optional name of a group where created mesh segments will be added.
7226 editor = self.editor
7228 editor = self.mesh.GetMeshEditPreviewer()
7229 segmentsRes = editor.MakePolyLine( segments, groupName )
7230 for i, seg in enumerate( segmentsRes ):
7231 segments[i].vector = seg.vector
7233 return editor.GetPreviewData()
7236 def MakeSlot(self, segmentGroup, width ):
7238 Create a slot of given width around given 1D elements lying on a triangle mesh.
7239 The slot is constructed by cutting faces by cylindrical surfaces made
7240 around each segment. Segments are expected to be created by MakePolyLine().
7243 FaceEdge's located at the slot boundary
7245 return self.editor.MakeSlot( segmentGroup, width )
7247 def GetFunctor(self, funcType ):
7249 Return a cached numerical functor by its type.
7252 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7253 Note that not all items correspond to numerical functors.
7256 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7259 fn = self.functors[ funcType._v ]
7261 fn = self.smeshpyD.GetFunctor(funcType)
7262 fn.SetMesh(self.mesh)
7263 self.functors[ funcType._v ] = fn
7266 def FunctorValue(self, funcType, elemId, isElem=True):
7268 Return value of a functor for a given element
7271 funcType: an item of :class:`SMESH.FunctorType` enum.
7272 elemId: element or node ID
7273 isElem: *elemId* is ID of element or node
7276 the functor value or zero in case of invalid arguments
7279 fn = self.GetFunctor( funcType )
7280 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7281 val = fn.GetValue(elemId)
7286 def GetLength(self, elemId=None):
7288 Get length of given 1D elements or of all 1D mesh elements
7291 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.
7294 Sum of lengths of given elements
7299 length = self.smeshpyD.GetLength(self)
7300 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7301 length = self.smeshpyD.GetLength(elemId)
7304 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7306 length += self.smeshpyD.GetLength(obj)
7307 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7308 unRegister = genObjUnRegister()
7309 obj = self.GetIDSource( elemId )
7310 unRegister.set( obj )
7311 length = self.smeshpyD.GetLength( obj )
7313 length = self.FunctorValue(SMESH.FT_Length, elemId)
7316 def GetArea(self, elemId=None):
7318 Get area of given 2D elements or of all 2D mesh elements
7321 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.
7324 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7329 area = self.smeshpyD.GetArea(self)
7330 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7331 area = self.smeshpyD.GetArea(elemId)
7334 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7336 area += self.smeshpyD.GetArea(obj)
7337 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7338 unRegister = genObjUnRegister()
7339 obj = self.GetIDSource( elemId )
7340 unRegister.set( obj )
7341 area = self.smeshpyD.GetArea( obj )
7343 area = self.FunctorValue(SMESH.FT_Area, elemId)
7346 def GetVolume(self, elemId=None):
7348 Get volume of given 3D elements or of all 3D mesh elements
7351 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.
7354 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7359 volume= self.smeshpyD.GetVolume(self)
7360 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7361 volume= self.smeshpyD.GetVolume(elemId)
7364 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7366 volume+= self.smeshpyD.GetVolume(obj)
7367 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7368 unRegister = genObjUnRegister()
7369 obj = self.GetIDSource( elemId )
7370 unRegister.set( obj )
7371 volume= self.smeshpyD.GetVolume( obj )
7373 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7376 def GetAngle(self, node1, node2, node3 ):
7378 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7381 node1,node2,node3: IDs of the three nodes
7384 Angle in radians [0,PI]. -1 if failure case.
7386 p1 = self.GetNodeXYZ( node1 )
7387 p2 = self.GetNodeXYZ( node2 )
7388 p3 = self.GetNodeXYZ( node3 )
7389 if p1 and p2 and p3:
7390 return self.smeshpyD.GetAngle( p1,p2,p3 )
7394 def GetMaxElementLength(self, elemId):
7396 Get maximum element length.
7399 elemId: mesh element ID
7402 element's maximum length value
7405 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7406 ftype = SMESH.FT_MaxElementLength3D
7408 ftype = SMESH.FT_MaxElementLength2D
7409 return self.FunctorValue(ftype, elemId)
7411 def GetAspectRatio(self, elemId):
7413 Get aspect ratio of 2D or 3D element.
7416 elemId: mesh element ID
7419 element's aspect ratio value
7422 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7423 ftype = SMESH.FT_AspectRatio3D
7425 ftype = SMESH.FT_AspectRatio
7426 return self.FunctorValue(ftype, elemId)
7428 def GetWarping(self, elemId):
7430 Get warping angle of 2D element.
7433 elemId: mesh element ID
7436 element's warping angle value
7439 return self.FunctorValue(SMESH.FT_Warping, elemId)
7441 def GetMinimumAngle(self, elemId):
7443 Get minimum angle of 2D element.
7446 elemId: mesh element ID
7449 element's minimum angle value
7452 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7454 def GetTaper(self, elemId):
7456 Get taper of 2D element.
7459 elemId: mesh element ID
7462 element's taper value
7465 return self.FunctorValue(SMESH.FT_Taper, elemId)
7467 def GetSkew(self, elemId):
7469 Get skew of 2D element.
7472 elemId: mesh element ID
7475 element's skew value
7478 return self.FunctorValue(SMESH.FT_Skew, elemId)
7480 def GetMinMax(self, funType, meshPart=None):
7482 Return minimal and maximal value of a given functor.
7485 funType (SMESH.FunctorType): a functor type.
7486 Note that not all items of :class:`SMESH.FunctorType` corresponds
7487 to numerical functors.
7488 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7494 unRegister = genObjUnRegister()
7495 if isinstance( meshPart, list ):
7496 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7497 unRegister.set( meshPart )
7498 if isinstance( meshPart, Mesh ):
7499 meshPart = meshPart.mesh
7500 fun = self.GetFunctor( funType )
7503 if hasattr( meshPart, "SetMesh" ):
7504 meshPart.SetMesh( self.mesh ) # set mesh to filter
7505 hist = fun.GetLocalHistogram( 1, False, meshPart )
7507 hist = fun.GetHistogram( 1, False )
7509 return hist[0].min, hist[0].max
7512 pass # end of Mesh class
7515 class meshProxy(SMESH._objref_SMESH_Mesh):
7517 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7518 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7520 def __init__(self,*args):
7521 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7522 def __deepcopy__(self, memo=None):
7523 new = self.__class__(self)
7525 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7526 if len( args ) == 3:
7527 args += SMESH.ALL_NODES, True
7528 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7529 def ExportToMEDX(self, *args): # function removed
7530 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7531 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7532 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7533 def ExportToMED(self, *args): # function removed
7534 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7535 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7537 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7539 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7540 def ExportPartToMED(self, *args): # 'version' parameter removed
7541 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7542 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7543 def ExportMED(self, *args): # signature of method changed
7544 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7546 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7548 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7549 def ExportUNV(self, *args): # renumber arg added
7550 if len( args ) == 1:
7552 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
7553 def ExportDAT(self, *args): # renumber arg added
7554 if len( args ) == 1:
7556 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
7558 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7561 class submeshProxy(SMESH._objref_SMESH_subMesh):
7564 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7566 def __init__(self,*args):
7567 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7569 def __deepcopy__(self, memo=None):
7570 new = self.__class__(self)
7573 def Compute(self,refresh=False):
7575 Compute the sub-mesh and return the status of the computation
7578 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7583 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7584 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7588 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7590 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7592 if salome.sg.hasDesktop():
7593 if refresh: salome.sg.updateObjBrowser()
7598 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7601 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7603 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7604 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7607 def __init__(self,*args):
7608 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7610 def __getattr__(self, name ): # method called if an attribute not found
7611 if not self.mesh: # look for name() method in Mesh class
7612 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7613 if hasattr( self.mesh, name ):
7614 return getattr( self.mesh, name )
7615 if name == "ExtrusionAlongPathObjX":
7616 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7617 print("meshEditor: attribute '%s' NOT FOUND" % name)
7619 def __deepcopy__(self, memo=None):
7620 new = self.__class__(self)
7622 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7623 if len( args ) == 1: args += False,
7624 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7625 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7626 if len( args ) == 2: args += False,
7627 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7628 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7629 if len( args ) == 1:
7630 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7631 NodesToKeep = args[1]
7632 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7633 unRegister = genObjUnRegister()
7635 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7636 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7637 if not isinstance( NodesToKeep, list ):
7638 NodesToKeep = [ NodesToKeep ]
7639 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7641 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7643 class Pattern(SMESH._objref_SMESH_Pattern):
7645 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7646 variables in some methods
7649 def LoadFromFile(self, patternTextOrFile ):
7650 text = patternTextOrFile
7651 if os.path.exists( text ):
7652 text = open( patternTextOrFile ).read()
7654 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7656 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7657 decrFun = lambda i: i-1
7658 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7659 theMesh.SetParameters(Parameters)
7660 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7662 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7663 decrFun = lambda i: i-1
7664 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7665 theMesh.SetParameters(Parameters)
7666 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7668 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7669 if isinstance( mesh, Mesh ):
7670 mesh = mesh.GetMesh()
7671 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7673 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7675 Registering the new proxy for Pattern
7680 Private class used to bind methods creating algorithms to the class Mesh
7683 def __init__(self, method):
7685 self.defaultAlgoType = ""
7686 self.algoTypeToClass = {}
7687 self.method = method
7689 def add(self, algoClass):
7691 Store a python class of algorithm
7693 if inspect.isclass(algoClass) and \
7694 hasattr( algoClass, "algoType"):
7695 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7696 if not self.defaultAlgoType and \
7697 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7698 self.defaultAlgoType = algoClass.algoType
7699 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7701 def copy(self, mesh):
7703 Create a copy of self and assign mesh to the copy
7706 other = algoCreator( self.method )
7707 other.defaultAlgoType = self.defaultAlgoType
7708 other.algoTypeToClass = self.algoTypeToClass
7712 def __call__(self,algo="",geom=0,*args):
7714 Create an instance of algorithm
7718 if isinstance( algo, str ):
7720 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7721 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7726 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7728 elif not algoType and isinstance( geom, str ):
7733 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7735 elif isinstance( arg, str ) and not algoType:
7738 import traceback, sys
7739 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7740 sys.stderr.write( msg + '\n' )
7741 tb = traceback.extract_stack(None,2)
7742 traceback.print_list( [tb[0]] )
7744 algoType = self.defaultAlgoType
7745 if not algoType and self.algoTypeToClass:
7746 algoType = sorted( self.algoTypeToClass.keys() )[0]
7747 if algoType in self.algoTypeToClass:
7748 #print("Create algo",algoType)
7749 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7750 raise RuntimeError( "No class found for algo type %s" % algoType)
7753 class hypMethodWrapper:
7755 Private class used to substitute and store variable parameters of hypotheses.
7758 def __init__(self, hyp, method):
7760 self.method = method
7761 #print("REBIND:", method.__name__)
7764 def __call__(self,*args):
7766 call a method of hypothesis with calling SetVarParameter() before
7770 return self.method( self.hyp, *args ) # hypothesis method with no args
7772 #print("MethWrapper.__call__", self.method.__name__, args)
7774 parsed = ParseParameters(*args) # replace variables with their values
7775 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7776 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7777 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7778 # maybe there is a replaced string arg which is not variable
7779 result = self.method( self.hyp, *args )
7780 except ValueError as detail: # raised by ParseParameters()
7782 result = self.method( self.hyp, *args )
7783 except omniORB.CORBA.BAD_PARAM:
7784 raise ValueError(detail) # wrong variable name
7789 class genObjUnRegister:
7791 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7794 def __init__(self, genObj=None):
7795 self.genObjList = []
7799 def set(self, genObj):
7800 "Store one or a list of of SALOME.GenericObj'es"
7801 if isinstance( genObj, list ):
7802 self.genObjList.extend( genObj )
7804 self.genObjList.append( genObj )
7808 for genObj in self.genObjList:
7809 if genObj and hasattr( genObj, "UnRegister" ):
7812 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7814 Bind methods creating mesher plug-ins to the Mesh class
7817 # print("pluginName: ", pluginName)
7818 pluginBuilderName = pluginName + "Builder"
7820 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7821 except Exception as e:
7822 from salome_utils import verbose
7823 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7825 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7826 plugin = eval( pluginBuilderName )
7827 # print(" plugin:" , str(plugin))
7829 # add methods creating algorithms to Mesh
7830 for k in dir( plugin ):
7831 if k[0] == '_': continue
7832 algo = getattr( plugin, k )
7833 #print(" algo:", str(algo))
7834 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7835 #print(" meshMethod:" , str(algo.meshMethod))
7836 if not hasattr( Mesh, algo.meshMethod ):
7837 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7839 _mmethod = getattr( Mesh, algo.meshMethod )
7840 if hasattr( _mmethod, "add" ):