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, 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 greater than 1")
1884 self.mesh.SetNbThreads(nbThreads)
1885 return self.Compute(geom=geom, discardModifs=discardModifs, refresh=refresh)
1887 def Compute(self, geom=0, discardModifs=False, refresh=False):
1889 Compute the mesh and return the status of the computation
1892 geom: geomtrical shape on which mesh data should be computed
1893 discardModifs: if True and the mesh has been edited since
1894 a last total re-compute and that may prevent successful partial re-compute,
1895 then the mesh is cleaned before Compute()
1896 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1897 nbThreads: Number of threads to use for a parallel computation
1903 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1904 geom = self.mesh.GetShapeToMesh()
1907 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1909 ok = self.smeshpyD.Compute(self.mesh, geom)
1910 except SALOME.SALOME_Exception as ex:
1911 print("Mesh computation failed, exception caught:")
1912 print(" ", ex.details.text)
1915 print("Mesh computation failed, exception caught:")
1916 traceback.print_exc()
1920 # Treat compute errors
1921 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1923 for err in computeErrors:
1924 if self.mesh.HasShapeToMesh():
1925 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1927 stdErrors = ["OK", #COMPERR_OK
1928 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1929 "std::exception", #COMPERR_STD_EXCEPTION
1930 "OCC exception", #COMPERR_OCC_EXCEPTION
1931 "..", #COMPERR_SLM_EXCEPTION
1932 "Unknown exception", #COMPERR_EXCEPTION
1933 "Memory allocation problem", #COMPERR_MEMORY_PB
1934 "Algorithm failed", #COMPERR_ALGO_FAILED
1935 "Unexpected geometry", #COMPERR_BAD_SHAPE
1936 "Warning", #COMPERR_WARNING
1937 "Computation cancelled",#COMPERR_CANCELED
1938 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1940 if err.code < len(stdErrors): errText = stdErrors[err.code]
1942 errText = "code %s" % -err.code
1943 if errText: errText += ". "
1944 errText += err.comment
1945 if allReasons: allReasons += "\n"
1947 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1949 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1953 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1955 if err.isGlobalAlgo:
1963 reason = '%s %sD algorithm is missing' % (glob, dim)
1964 elif err.state == HYP_MISSING:
1965 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1966 % (glob, dim, name, dim))
1967 elif err.state == HYP_NOTCONFORM:
1968 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1969 elif err.state == HYP_BAD_PARAMETER:
1970 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1971 % ( glob, dim, name ))
1972 elif err.state == HYP_BAD_GEOMETRY:
1973 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1974 'geometry' % ( glob, dim, name ))
1975 elif err.state == HYP_HIDDEN_ALGO:
1976 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1977 'algorithm of upper dimension generating %sD mesh'
1978 % ( glob, dim, name, glob, dim ))
1980 reason = ("For unknown reason. "
1981 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1983 if allReasons: allReasons += "\n"
1984 allReasons += "- " + reason
1986 if not ok or allReasons != "":
1987 msg = '"' + GetName(self.mesh) + '"'
1988 if ok: msg += " has been computed with warnings"
1989 else: msg += " has not been computed"
1990 if allReasons != "": msg += ":"
1996 if salome.sg.hasDesktop():
1997 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1998 if refresh: salome.sg.updateObjBrowser()
2002 def GetComputeErrors(self, shape=0 ):
2004 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
2008 shape = self.mesh.GetShapeToMesh()
2009 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
2011 def GetSubShapeName(self, subShapeID ):
2013 Return a name of a sub-shape by its ID.
2014 Possible variants (for *subShapeID* == 3):
2016 - **"Face_12"** - published sub-shape
2017 - **FACE #3** - not published sub-shape
2018 - **sub-shape #3** - invalid sub-shape ID
2019 - **#3** - error in this function
2022 subShapeID: a unique ID of a sub-shape
2025 a string describing the sub-shape
2029 if not self.mesh.HasShapeToMesh():
2033 mainIOR = salome.orb.object_to_string( self.GetShape() )
2035 mainSO = s.FindObjectIOR(mainIOR)
2038 shapeText = '"%s"' % mainSO.GetName()
2039 subIt = s.NewChildIterator(mainSO)
2041 subSO = subIt.Value()
2043 obj = subSO.GetObject()
2044 if not obj: continue
2045 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2048 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2051 if ids == subShapeID:
2052 shapeText = '"%s"' % subSO.GetName()
2055 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2057 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2059 shapeText = 'sub-shape #%s' % (subShapeID)
2061 shapeText = "#%s" % (subShapeID)
2064 def GetFailedShapes(self, publish=False):
2066 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2067 error of an algorithm
2070 publish: if *True*, the returned groups will be published in the study
2073 a list of GEOM groups each named after a failed algorithm
2078 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2079 for err in computeErrors:
2080 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2081 if not shape: continue
2082 if err.algoName in algo2shapes:
2083 algo2shapes[ err.algoName ].append( shape )
2085 algo2shapes[ err.algoName ] = [ shape ]
2089 for algoName, shapes in list(algo2shapes.items()):
2091 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2092 otherTypeShapes = []
2094 group = self.geompyD.CreateGroup( self.geom, groupType )
2095 for shape in shapes:
2096 if shape.GetShapeType() == shapes[0].GetShapeType():
2097 sameTypeShapes.append( shape )
2099 otherTypeShapes.append( shape )
2100 self.geompyD.UnionList( group, sameTypeShapes )
2102 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2104 group.SetName( algoName )
2105 groups.append( group )
2106 shapes = otherTypeShapes
2109 for group in groups:
2110 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2113 def GetMeshOrder(self):
2115 Return sub-mesh objects list in meshing order
2118 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2121 return self.mesh.GetMeshOrder()
2123 def SetMeshOrder(self, submeshes):
2125 Set priority of sub-meshes. It works in two ways:
2127 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2128 *several dimensions*, it sets the order in which the sub-meshes are computed.
2129 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2130 when looking for meshing parameters to apply to a sub-shape. To impose the
2131 order in which sub-meshes with uni-dimensional algorithms are computed,
2132 call **submesh.Compute()** in a desired order.
2135 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2137 Warning: the method is for setting the order for all sub-meshes at once:
2138 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2141 return self.mesh.SetMeshOrder(submeshes)
2143 def Clear(self, refresh=False):
2145 Remove all nodes and elements generated on geometry. Imported elements remain.
2148 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2152 if ( salome.sg.hasDesktop() ):
2153 if refresh: salome.sg.updateObjBrowser()
2155 def ClearSubMesh(self, geomId, refresh=False):
2157 Remove all nodes and elements of indicated shape
2160 geomId: the ID of a sub-shape to remove elements on
2161 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2164 self.mesh.ClearSubMesh(geomId)
2165 if salome.sg.hasDesktop():
2166 if refresh: salome.sg.updateObjBrowser()
2168 def AutomaticTetrahedralization(self, fineness=0):
2170 Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron
2173 fineness: [0.0,1.0] defines mesh fineness
2179 dim = self.MeshDimension()
2181 self.RemoveGlobalHypotheses()
2182 self.Segment().AutomaticLength(fineness)
2184 self.Triangle().LengthFromEdges()
2189 return self.Compute()
2191 def AutomaticHexahedralization(self, fineness=0):
2193 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2196 fineness: [0.0, 1.0] defines mesh fineness
2202 dim = self.MeshDimension()
2203 # assign the hypotheses
2204 self.RemoveGlobalHypotheses()
2205 self.Segment().AutomaticLength(fineness)
2212 return self.Compute()
2214 def AddHypothesis(self, hyp, geom=0):
2219 hyp: a hypothesis to assign
2220 geom: a subhape of mesh geometry
2223 :class:`SMESH.Hypothesis_Status`
2226 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2227 hyp, geom = geom, hyp
2228 if isinstance( hyp, Mesh_Algorithm ):
2229 hyp = hyp.GetAlgorithm()
2234 geom = self.mesh.GetShapeToMesh()
2237 if self.mesh.HasShapeToMesh():
2238 hyp_type = hyp.GetName()
2239 lib_name = hyp.GetLibName()
2240 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2241 # if checkAll and geom:
2242 # checkAll = geom.GetType() == 37
2244 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2246 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2247 status = self.mesh.AddHypothesis(geom, hyp)
2249 status = HYP_BAD_GEOMETRY, ""
2250 hyp_name = GetName( hyp )
2253 geom_name = geom.GetName()
2254 isAlgo = hyp._narrow( SMESH_Algo )
2255 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2258 def IsUsedHypothesis(self, hyp, geom):
2260 Return True if an algorithm or hypothesis is assigned to a given shape
2263 hyp: an algorithm or hypothesis to check
2264 geom: a subhape of mesh geometry
2270 if not hyp: # or not geom
2272 if isinstance( hyp, Mesh_Algorithm ):
2273 hyp = hyp.GetAlgorithm()
2275 hyps = self.GetHypothesisList(geom)
2277 if h.GetId() == hyp.GetId():
2281 def RemoveHypothesis(self, hyp, geom=0):
2283 Unassign a hypothesis
2286 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2287 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2290 :class:`SMESH.Hypothesis_Status`
2295 if isinstance( hyp, Mesh_Algorithm ):
2296 hyp = hyp.GetAlgorithm()
2302 if self.IsUsedHypothesis( hyp, shape ):
2303 return self.mesh.RemoveHypothesis( shape, hyp )
2304 hypName = GetName( hyp )
2305 geoName = GetName( shape )
2306 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2309 def GetHypothesisList(self, geom):
2311 Get the list of hypotheses added on a geometry
2314 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2317 the sequence of :class:`SMESH.SMESH_Hypothesis`
2320 return self.mesh.GetHypothesisList( geom )
2322 def RemoveGlobalHypotheses(self):
2324 Remove all global hypotheses
2327 current_hyps = self.mesh.GetHypothesisList( self.geom )
2328 for hyp in current_hyps:
2329 self.mesh.RemoveHypothesis( self.geom, hyp )
2333 def ExportMEDCoupling(self, *args, **kwargs):
2335 Export the mesh in a memory representation.
2338 auto_groups (boolean): parameter for creating/not creating
2339 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2340 the typical use is auto_groups=False.
2341 overwrite (boolean): parameter for overwriting/not overwriting the file
2342 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2343 to export instead of the mesh
2344 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2346 - 1D if all mesh nodes lie on OX coordinate axis, or
2347 - 2D if all mesh nodes lie on XOY coordinate plane, or
2348 - 3D in the rest cases.
2350 If *autoDimension* is *False*, the space dimension is always 3.
2351 fields: list of GEOM fields defined on the shape to mesh.
2352 geomAssocFields: each character of this string means a need to export a
2353 corresponding field; correspondence between fields and characters
2356 - 'v' stands for "_vertices_" field;
2357 - 'e' stands for "_edges_" field;
2358 - 'f' stands for "_faces_" field;
2359 - 's' stands for "_solids_" field.
2361 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2362 close to zero within a given tolerance, the coordinate is set to zero.
2363 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2364 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2366 auto_groups = args[0] if len(args) > 0 else False
2367 meshPart = args[1] if len(args) > 1 else None
2368 autoDimension = args[2] if len(args) > 2 else True
2369 fields = args[3] if len(args) > 3 else []
2370 geomAssocFields = args[4] if len(args) > 4 else ''
2371 z_tolerance = args[5] if len(args) > 5 else -1.
2372 saveNumbers = args[6] if len(args) > 6 else True
2373 # process keywords arguments
2374 auto_groups = kwargs.get("auto_groups", auto_groups)
2375 meshPart = kwargs.get("meshPart", meshPart)
2376 autoDimension = kwargs.get("autoDimension", autoDimension)
2377 fields = kwargs.get("fields", fields)
2378 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2379 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2380 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2382 # invoke engine's function
2383 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2384 unRegister = genObjUnRegister()
2385 if isinstance( meshPart, list ):
2386 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2387 unRegister.set( meshPart )
2389 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2390 self.mesh.SetParameters(Parameters)
2392 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2393 fields, geomAssocFields, z_tolerance,
2396 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2397 return medcoupling.MEDFileData.New(dab)
2399 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2401 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2402 return medcoupling.MEDFileMesh.New(dab)
2404 def ExportMED(self, *args, **kwargs):
2406 Export the mesh in a file in MED format
2407 allowing to overwrite the file if it exists or add the exported data to its contents
2410 fileName: is the file name
2411 auto_groups (boolean): parameter for creating/not creating
2412 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2413 the typical use is auto_groups=False.
2414 version (int): define the version (xy, where version is x.y.z) of MED file format.
2415 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2416 The rules of compatibility to write a mesh in an older version than
2417 the current version depend on the current version. For instance,
2418 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2419 or 3.2.1 or 3.3.1 formats.
2420 If the version is equal to -1, the version is not changed (default).
2421 overwrite (boolean): parameter for overwriting/not overwriting the file
2422 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2423 to export instead of the mesh
2424 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2426 - 1D if all mesh nodes lie on OX coordinate axis, or
2427 - 2D if all mesh nodes lie on XOY coordinate plane, or
2428 - 3D in the rest cases.
2430 If *autoDimension* is *False*, the space dimension is always 3.
2431 fields: list of GEOM fields defined on the shape to mesh.
2432 geomAssocFields: each character of this string means a need to export a
2433 corresponding field; correspondence between fields and characters
2436 - 'v' stands for "_vertices_" field;
2437 - 'e' stands for "_edges_" field;
2438 - 'f' stands for "_faces_" field;
2439 - 's' stands for "_solids_" field.
2441 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2442 close to zero within a given tolerance, the coordinate is set to zero.
2443 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2444 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2446 # process positional arguments
2447 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2449 auto_groups = args[1] if len(args) > 1 else False
2450 version = args[2] if len(args) > 2 else -1
2451 overwrite = args[3] if len(args) > 3 else True
2452 meshPart = args[4] if len(args) > 4 else None
2453 autoDimension = args[5] if len(args) > 5 else True
2454 fields = args[6] if len(args) > 6 else []
2455 geomAssocFields = args[7] if len(args) > 7 else ''
2456 z_tolerance = args[8] if len(args) > 8 else -1.
2457 saveNumbers = args[9] if len(args) > 9 else True
2458 # process keywords arguments
2459 auto_groups = kwargs.get("auto_groups", auto_groups)
2460 version = kwargs.get("version", version)
2461 version = kwargs.get("minor", version)
2462 overwrite = kwargs.get("overwrite", overwrite)
2463 meshPart = kwargs.get("meshPart", meshPart)
2464 autoDimension = kwargs.get("autoDimension", autoDimension)
2465 fields = kwargs.get("fields", fields)
2466 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2467 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2468 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2470 if isinstance( meshPart, Mesh):
2471 meshPart = meshPart.GetMesh()
2473 # invoke engine's function
2474 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2475 unRegister = genObjUnRegister()
2476 if isinstance( meshPart, list ):
2477 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2478 unRegister.set( meshPart )
2480 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2481 self.mesh.SetParameters(Parameters)
2483 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2484 version, overwrite, autoDimension,
2485 fields, geomAssocFields, z_tolerance, saveNumbers )
2487 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2489 def ExportDAT(self, f, meshPart=None, renumber=True):
2491 Export the mesh in a file in DAT format
2495 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2496 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2499 if meshPart or not renumber:
2500 unRegister = genObjUnRegister()
2501 if isinstance( meshPart, list ):
2502 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2503 unRegister.set( meshPart )
2504 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2506 self.mesh.ExportDAT( f, renumber )
2508 def ExportUNV(self, f, meshPart=None, renumber=True):
2510 Export the mesh in a file in UNV format
2514 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2515 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2518 if meshPart or not renumber:
2519 unRegister = genObjUnRegister()
2520 if isinstance( meshPart, list ):
2521 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2522 unRegister.set( meshPart )
2523 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2525 self.mesh.ExportUNV( f, renumber )
2527 def ExportSTL(self, f, ascii=1, meshPart=None):
2529 Export the mesh in a file in STL format
2533 ascii: defines the file encoding
2534 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2538 unRegister = genObjUnRegister()
2539 if isinstance( meshPart, list ):
2540 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2541 unRegister.set( meshPart )
2542 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2544 self.mesh.ExportSTL(f, ascii)
2546 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2548 Export the mesh in a file in CGNS format
2552 overwrite: boolean parameter for overwriting/not overwriting the file
2553 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2554 groupElemsByType: if True all elements of same entity type are exported at ones,
2555 else elements are exported in order of their IDs which can cause creation
2556 of multiple cgns sections
2559 unRegister = genObjUnRegister()
2560 if isinstance( meshPart, list ):
2561 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2562 unRegister.set( meshPart )
2563 if isinstance( meshPart, Mesh ):
2564 meshPart = meshPart.mesh
2566 meshPart = self.mesh
2567 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2569 def ExportGMF(self, f, meshPart=None):
2571 Export the mesh in a file in GMF format.
2572 GMF files must have .mesh extension for the ASCII format and .meshb for
2573 the bynary format. Other extensions are not allowed.
2577 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2580 unRegister = genObjUnRegister()
2581 if isinstance( meshPart, list ):
2582 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2583 unRegister.set( meshPart )
2584 if isinstance( meshPart, Mesh ):
2585 meshPart = meshPart.mesh
2587 meshPart = self.mesh
2588 self.mesh.ExportGMF(meshPart, f, True)
2590 def ExportToMED(self, *args, **kwargs):
2592 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2593 Export the mesh in a file in MED format
2594 allowing to overwrite the file if it exists or add the exported data to its contents
2597 fileName: the file name
2598 opt (boolean): parameter for creating/not creating
2599 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2600 overwrite: boolean parameter for overwriting/not overwriting the file
2601 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2603 - 1D if all mesh nodes lie on OX coordinate axis, or
2604 - 2D if all mesh nodes lie on XOY coordinate plane, or
2605 - 3D in the rest cases.
2607 If **autoDimension** is *False*, the space dimension is always 3.
2610 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2611 # process positional arguments
2612 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2614 auto_groups = args[1] if len(args) > 1 else False
2615 overwrite = args[2] if len(args) > 2 else True
2616 autoDimension = args[3] if len(args) > 3 else True
2617 # process keywords arguments
2618 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2619 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2620 overwrite = kwargs.get("overwrite", overwrite)
2621 autoDimension = kwargs.get("autoDimension", autoDimension)
2623 # invoke engine's function
2624 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2626 def ExportToMEDX(self, *args, **kwargs):
2628 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2629 Export the mesh in a file in MED format
2632 fileName: the file name
2633 opt (boolean): parameter for creating/not creating
2634 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2635 overwrite: boolean parameter for overwriting/not overwriting the file
2636 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2638 - 1D if all mesh nodes lie on OX coordinate axis, or
2639 - 2D if all mesh nodes lie on XOY coordinate plane, or
2640 - 3D in the rest cases.
2642 If **autoDimension** is *False*, the space dimension is always 3.
2645 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2646 # process positional arguments
2647 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2649 auto_groups = args[1] if len(args) > 1 else False
2650 overwrite = args[2] if len(args) > 2 else True
2651 autoDimension = args[3] if len(args) > 3 else True
2652 # process keywords arguments
2653 auto_groups = kwargs.get("auto_groups", auto_groups)
2654 overwrite = kwargs.get("overwrite", overwrite)
2655 autoDimension = kwargs.get("autoDimension", autoDimension)
2657 # invoke engine's function
2658 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2662 def Append(self, meshes, uniteIdenticalGroups = True,
2663 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2665 Append given meshes into this mesh.
2666 All groups of input meshes will be created in this mesh.
2669 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2670 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2671 mergeNodesAndElements: if True, equal nodes and elements are merged
2672 mergeTolerance: tolerance for merging nodes
2673 allGroups: forces creation of groups corresponding to every input mesh
2675 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2676 mergeNodesAndElements, mergeTolerance, allGroups,
2677 meshToAppendTo = self.GetMesh() )
2679 # Operations with groups:
2680 # ----------------------
2681 def CreateEmptyGroup(self, elementType, name):
2683 Create an empty standalone mesh group
2686 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2687 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2688 name: the name of the mesh group
2691 :class:`SMESH.SMESH_Group`
2694 return self.mesh.CreateGroup(elementType, name)
2696 def Group(self, grp, name=""):
2698 Create a mesh group based on the geometric object *grp*
2699 and give it a *name*.
2700 If *name* is not defined the name of the geometric group is used
2703 Works like :meth:`GroupOnGeom`.
2706 grp: a geometric group, a vertex, an edge, a face or a solid
2707 name: the name of the mesh group
2710 :class:`SMESH.SMESH_GroupOnGeom`
2713 return self.GroupOnGeom(grp, name)
2715 def GroupOnGeom(self, grp, name="", typ=None):
2717 Create a mesh group based on the geometrical object *grp*
2718 and give it a *name*.
2719 if *name* is not defined the name of the geometric group is used
2722 grp: a geometrical group, a vertex, an edge, a face or a solid
2723 name: the name of the mesh group
2724 typ: the type of elements in the group; either of
2725 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2726 automatically detected by the type of the geometry
2729 :class:`SMESH.SMESH_GroupOnGeom`
2732 AssureGeomPublished( self, grp, name )
2734 name = grp.GetName()
2736 typ = self._groupTypeFromShape( grp )
2737 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2739 def _groupTypeFromShape( self, shape ):
2741 Pivate method to get a type of group on geometry
2743 tgeo = str(shape.GetShapeType())
2744 if tgeo == "VERTEX":
2746 elif tgeo == "EDGE" or tgeo == "WIRE":
2748 elif tgeo == "FACE" or tgeo == "SHELL":
2750 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2752 elif tgeo == "COMPOUND":
2754 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2756 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2757 # simplification of access in geomBuilder: omniORB.registerObjref
2758 from SHAPERSTUDY_utils import getEngine
2761 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2763 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2764 return self._groupTypeFromShape( sub[0] )
2766 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2769 def GroupOnFilter(self, typ, name, filter):
2771 Create a mesh group with given *name* based on the *filter*.
2772 It is a special type of group dynamically updating it's contents during
2776 typ: the type of elements in the group; either of
2777 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2778 name: the name of the mesh group
2779 filter (SMESH.Filter): the filter defining group contents
2782 :class:`SMESH.SMESH_GroupOnFilter`
2785 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2787 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2789 Create a mesh group by the given ids of elements
2792 groupName: the name of the mesh group
2793 elementType: the type of elements in the group; either of
2794 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2795 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2798 :class:`SMESH.SMESH_Group`
2801 group = self.mesh.CreateGroup(elementType, groupName)
2802 if isinstance( elemIDs, Mesh ):
2803 elemIDs = elemIDs.GetMesh()
2804 if hasattr( elemIDs, "GetIDs" ):
2805 if hasattr( elemIDs, "SetMesh" ):
2806 elemIDs.SetMesh( self.GetMesh() )
2807 group.AddFrom( elemIDs )
2815 CritType=FT_Undefined,
2818 UnaryOp=FT_Undefined,
2821 Create a mesh group by the given conditions
2824 groupName: the name of the mesh group
2825 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2826 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2827 Note that the items starting from FT_LessThan are not suitable for CritType.
2828 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2829 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2830 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2831 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2832 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2835 :class:`SMESH.SMESH_GroupOnFilter`
2838 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2839 group = self.MakeGroupByCriterion(groupName, aCriterion)
2842 def MakeGroupByCriterion(self, groupName, Criterion):
2844 Create a mesh group by the given criterion
2847 groupName: the name of the mesh group
2848 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2851 :class:`SMESH.SMESH_GroupOnFilter`
2854 :meth:`smeshBuilder.GetCriterion`
2857 return self.MakeGroupByCriteria( groupName, [Criterion] )
2859 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2861 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2864 groupName: the name of the mesh group
2865 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2866 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2869 :class:`SMESH.SMESH_GroupOnFilter`
2872 :meth:`smeshBuilder.GetCriterion`
2875 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2876 group = self.MakeGroupByFilter(groupName, aFilter)
2879 def MakeGroupByFilter(self, groupName, theFilter):
2881 Create a mesh group by the given filter
2884 groupName (string): the name of the mesh group
2885 theFilter (SMESH.Filter): the filter
2888 :class:`SMESH.SMESH_GroupOnFilter`
2891 :meth:`smeshBuilder.GetFilter`
2894 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2895 #theFilter.SetMesh( self.mesh )
2896 #group.AddFrom( theFilter )
2897 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2900 def RemoveGroup(self, group):
2905 group (SMESH.SMESH_GroupBase): group to remove
2908 self.mesh.RemoveGroup(group)
2910 def RemoveGroupWithContents(self, group):
2912 Remove a group with its contents
2915 group (SMESH.SMESH_GroupBase): group to remove
2918 This operation can create gaps in numeration of nodes or elements.
2919 Call :meth:`RenumberElements` to remove the gaps.
2922 self.mesh.RemoveGroupWithContents(group)
2924 def GetGroups(self, elemType = SMESH.ALL):
2926 Get the list of groups existing in the mesh in the order of creation
2927 (starting from the oldest one)
2930 elemType (SMESH.ElementType): type of elements the groups contain;
2931 by default groups of elements of all types are returned
2934 a list of :class:`SMESH.SMESH_GroupBase`
2937 groups = self.mesh.GetGroups()
2938 if elemType == SMESH.ALL:
2942 if g.GetType() == elemType:
2943 typedGroups.append( g )
2950 Get the number of groups existing in the mesh
2953 the quantity of groups as an integer value
2956 return self.mesh.NbGroups()
2958 def GetGroupNames(self):
2960 Get the list of names of groups existing in the mesh
2966 groups = self.GetGroups()
2968 for group in groups:
2969 names.append(group.GetName())
2972 def GetGroupByName(self, name, elemType = None):
2974 Find groups by name and type
2977 name (string): name of the group of interest
2978 elemType (SMESH.ElementType): type of elements the groups contain;
2979 by default one group of any type is returned;
2980 if elemType == SMESH.ALL then all groups of any type are returned
2983 a list of :class:`SMESH.SMESH_GroupBase`
2987 for group in self.GetGroups():
2988 if group.GetName() == name:
2989 if elemType is None:
2991 if ( elemType == SMESH.ALL or
2992 group.GetType() == elemType ):
2993 groups.append( group )
2996 def UnionGroups(self, group1, group2, name):
2998 Produce a union of two groups.
2999 A new group is created. All mesh elements that are
3000 present in the initial groups are added to the new one
3003 group1 (SMESH.SMESH_GroupBase): a group
3004 group2 (SMESH.SMESH_GroupBase): another group
3007 instance of :class:`SMESH.SMESH_Group`
3010 return self.mesh.UnionGroups(group1, group2, name)
3012 def UnionListOfGroups(self, groups, name):
3014 Produce a union list of groups.
3015 New group is created. All mesh elements that are present in
3016 initial groups are added to the new one
3019 groups: list of :class:`SMESH.SMESH_GroupBase`
3022 instance of :class:`SMESH.SMESH_Group`
3024 return self.mesh.UnionListOfGroups(groups, name)
3026 def IntersectGroups(self, group1, group2, name):
3028 Prodice an intersection of two groups.
3029 A new group is created. All mesh elements that are common
3030 for the two initial groups are added to the new one.
3033 group1 (SMESH.SMESH_GroupBase): a group
3034 group2 (SMESH.SMESH_GroupBase): another group
3037 instance of :class:`SMESH.SMESH_Group`
3040 return self.mesh.IntersectGroups(group1, group2, name)
3042 def IntersectListOfGroups(self, groups, name):
3044 Produce an intersection of groups.
3045 New group is created. All mesh elements that are present in all
3046 initial groups simultaneously are added to the new one
3049 groups: a list of :class:`SMESH.SMESH_GroupBase`
3052 instance of :class:`SMESH.SMESH_Group`
3054 return self.mesh.IntersectListOfGroups(groups, name)
3056 def CutGroups(self, main_group, tool_group, name):
3058 Produce a cut of two groups.
3059 A new group is created. All mesh elements that are present in
3060 the main group but are not present in the tool group are added to the new one
3063 main_group (SMESH.SMESH_GroupBase): a group to cut from
3064 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3067 an instance of :class:`SMESH.SMESH_Group`
3070 return self.mesh.CutGroups(main_group, tool_group, name)
3072 def CutListOfGroups(self, main_groups, tool_groups, name):
3074 Produce a cut of groups.
3075 A new group is created. All mesh elements that are present in main groups
3076 but do not present in tool groups are added to the new one
3079 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3080 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3083 an instance of :class:`SMESH.SMESH_Group`
3086 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3088 def CreateDimGroup(self, groups, elemType, name,
3089 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3091 Create a standalone group of entities basing on nodes of other groups.
3094 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3095 elemType: a type of elements to include to the new group; either of
3096 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3097 name: a name of the new group.
3098 nbCommonNodes: a criterion of inclusion of an element to the new group
3099 basing on number of element nodes common with reference *groups*.
3100 Meaning of possible values are:
3102 - SMESH.ALL_NODES - include if all nodes are common,
3103 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3104 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3105 - SMEHS.MAJORITY - include if half of nodes or more are common.
3106 underlyingOnly: if *True* (default), an element is included to the
3107 new group provided that it is based on nodes of an element of *groups*;
3108 in this case the reference *groups* are supposed to be of higher dimension
3109 than *elemType*, which can be useful for example to get all faces lying on
3110 volumes of the reference *groups*.
3113 an instance of :class:`SMESH.SMESH_Group`
3116 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3118 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3120 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3122 Distribute all faces of the mesh among groups using sharp edges and optionally
3123 existing 1D elements as group boundaries.
3126 sharpAngle: edge is considered sharp if an angle between normals of
3127 adjacent faces is more than \a sharpAngle in degrees.
3128 createEdges (boolean): to create 1D elements for detected sharp edges.
3129 useExistingEdges (boolean): to use existing edges as group boundaries
3131 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3133 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3134 self.mesh.SetParameters(Parameters)
3135 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3137 def ConvertToStandalone(self, group):
3139 Convert group on geom into standalone group
3142 return self.mesh.ConvertToStandalone(group)
3144 # Get some info about mesh:
3145 # ------------------------
3147 def GetLog(self, clearAfterGet):
3149 Return the log of nodes and elements added or removed
3150 since the previous clear of the log.
3153 clearAfterGet: log is emptied after Get (safe if concurrents access)
3156 list of SMESH.log_block structures { commandType, number, coords, indexes }
3159 return self.mesh.GetLog(clearAfterGet)
3163 Clear the log of nodes and elements added or removed since the previous
3164 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3167 self.mesh.ClearLog()
3169 def SetAutoColor(self, theAutoColor):
3171 Toggle auto color mode on the object.
3172 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3175 theAutoColor (boolean): the flag which toggles auto color mode.
3178 self.mesh.SetAutoColor(theAutoColor)
3180 def GetAutoColor(self):
3182 Get flag of object auto color mode.
3188 return self.mesh.GetAutoColor()
3195 integer value, which is the internal Id of the mesh
3198 return self.mesh.GetId()
3200 def HasDuplicatedGroupNamesMED(self):
3202 Check the group names for duplications.
3203 Consider the maximum group name length stored in MED file.
3209 return self.mesh.HasDuplicatedGroupNamesMED()
3211 def GetMeshEditor(self):
3213 Obtain the mesh editor tool
3216 an instance of :class:`SMESH.SMESH_MeshEditor`
3221 def GetIDSource(self, ids, elemType = SMESH.ALL):
3223 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3224 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3228 elemType: type of elements; this parameter is used to distinguish
3229 IDs of nodes from IDs of elements; by default ids are treated as
3230 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3233 an instance of :class:`SMESH.SMESH_IDSource`
3236 call UnRegister() for the returned object as soon as it is no more useful::
3238 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3239 mesh.DoSomething( idSrc )
3243 if isinstance( ids, int ):
3245 return self.editor.MakeIDSource(ids, elemType)
3248 # Get information about mesh contents:
3249 # ------------------------------------
3251 def GetMeshInfo(self, obj = None):
3253 Get the mesh statistic.
3256 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3259 if not obj: obj = self.mesh
3260 return self.smeshpyD.GetMeshInfo(obj)
3264 Return the number of nodes in the mesh
3270 return self.mesh.NbNodes()
3272 def NbElements(self):
3274 Return the number of elements in the mesh
3280 return self.mesh.NbElements()
3282 def Nb0DElements(self):
3284 Return the number of 0d elements in the mesh
3290 return self.mesh.Nb0DElements()
3294 Return the number of ball discrete elements in the mesh
3300 return self.mesh.NbBalls()
3304 Return the number of edges in the mesh
3310 return self.mesh.NbEdges()
3312 def NbEdgesOfOrder(self, elementOrder):
3314 Return the number of edges with the given order in the mesh
3317 elementOrder: the order of elements
3318 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3324 return self.mesh.NbEdgesOfOrder(elementOrder)
3328 Return the number of faces in the mesh
3334 return self.mesh.NbFaces()
3336 def NbFacesOfOrder(self, elementOrder):
3338 Return the number of faces with the given order in the mesh
3341 elementOrder: the order of elements
3342 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3348 return self.mesh.NbFacesOfOrder(elementOrder)
3350 def NbTriangles(self):
3352 Return the number of triangles in the mesh
3358 return self.mesh.NbTriangles()
3360 def NbTrianglesOfOrder(self, elementOrder):
3362 Return the number of triangles with the given order in the mesh
3365 elementOrder: is the order of elements
3366 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3372 return self.mesh.NbTrianglesOfOrder(elementOrder)
3374 def NbBiQuadTriangles(self):
3376 Return the number of biquadratic triangles in the mesh
3382 return self.mesh.NbBiQuadTriangles()
3384 def NbQuadrangles(self):
3386 Return the number of quadrangles in the mesh
3392 return self.mesh.NbQuadrangles()
3394 def NbQuadranglesOfOrder(self, elementOrder):
3396 Return the number of quadrangles with the given order in the mesh
3399 elementOrder: the order of elements
3400 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3406 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3408 def NbBiQuadQuadrangles(self):
3410 Return the number of biquadratic quadrangles in the mesh
3416 return self.mesh.NbBiQuadQuadrangles()
3418 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3420 Return the number of polygons of given order in the mesh
3423 elementOrder: the order of elements
3424 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3430 return self.mesh.NbPolygonsOfOrder(elementOrder)
3432 def NbVolumes(self):
3434 Return the number of volumes in the mesh
3440 return self.mesh.NbVolumes()
3443 def NbVolumesOfOrder(self, elementOrder):
3445 Return the number of volumes with the given order in the mesh
3448 elementOrder: the order of elements
3449 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3455 return self.mesh.NbVolumesOfOrder(elementOrder)
3459 Return the number of tetrahedrons in the mesh
3465 return self.mesh.NbTetras()
3467 def NbTetrasOfOrder(self, elementOrder):
3469 Return the number of tetrahedrons with the given order in the mesh
3472 elementOrder: the order of elements
3473 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3479 return self.mesh.NbTetrasOfOrder(elementOrder)
3483 Return the number of hexahedrons in the mesh
3489 return self.mesh.NbHexas()
3491 def NbHexasOfOrder(self, elementOrder):
3493 Return the number of hexahedrons with the given order in the mesh
3496 elementOrder: the order of elements
3497 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3503 return self.mesh.NbHexasOfOrder(elementOrder)
3505 def NbTriQuadraticHexas(self):
3507 Return the number of triquadratic hexahedrons in the mesh
3513 return self.mesh.NbTriQuadraticHexas()
3515 def NbPyramids(self):
3517 Return the number of pyramids in the mesh
3523 return self.mesh.NbPyramids()
3525 def NbPyramidsOfOrder(self, elementOrder):
3527 Return the number of pyramids with the given order in the mesh
3530 elementOrder: the order of elements
3531 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3537 return self.mesh.NbPyramidsOfOrder(elementOrder)
3541 Return the number of prisms in the mesh
3547 return self.mesh.NbPrisms()
3549 def NbPrismsOfOrder(self, elementOrder):
3551 Return the number of prisms with the given order in the mesh
3554 elementOrder: the order of elements
3555 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3561 return self.mesh.NbPrismsOfOrder(elementOrder)
3563 def NbHexagonalPrisms(self):
3565 Return the number of hexagonal prisms in the mesh
3571 return self.mesh.NbHexagonalPrisms()
3573 def NbPolyhedrons(self):
3575 Return the number of polyhedrons in the mesh
3581 return self.mesh.NbPolyhedrons()
3583 def NbSubMesh(self):
3585 Return the number of submeshes in the mesh
3591 return self.mesh.NbSubMesh()
3593 def GetElementsId(self):
3595 Return the list of all mesh elements IDs
3598 the list of integer values
3601 :meth:`GetElementsByType`
3604 return self.mesh.GetElementsId()
3606 def GetElementsByType(self, elementType):
3608 Return the list of IDs of mesh elements with the given type
3611 elementType (SMESH.ElementType): the required type of elements
3614 list of integer values
3617 return self.mesh.GetElementsByType(elementType)
3619 def GetNodesId(self):
3621 Return the list of mesh nodes IDs
3624 the list of integer values
3627 return self.mesh.GetNodesId()
3629 # Get the information about mesh elements:
3630 # ------------------------------------
3632 def GetElementType(self, id, iselem=True):
3634 Return the type of mesh element or node
3637 the value from :class:`SMESH.ElementType` enumeration.
3638 Return SMESH.ALL if element or node with the given ID does not exist
3641 return self.mesh.GetElementType(id, iselem)
3643 def GetElementGeomType(self, id):
3645 Return the geometric type of mesh element
3648 the value from :class:`SMESH.EntityType` enumeration.
3651 return self.mesh.GetElementGeomType(id)
3653 def GetElementShape(self, id):
3655 Return the shape type of mesh element
3658 the value from :class:`SMESH.GeometryType` enumeration.
3661 return self.mesh.GetElementShape(id)
3663 def GetSubMeshElementsId(self, Shape):
3665 Return the list of sub-mesh elements IDs
3668 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3669 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3672 list of integer values
3675 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3676 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3679 return self.mesh.GetSubMeshElementsId(ShapeID)
3681 def GetSubMeshNodesId(self, Shape, all):
3683 Return the list of sub-mesh nodes IDs
3686 Shape: a geom object (sub-shape).
3687 *Shape* must be the sub-shape of a :meth:`GetShape`
3688 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3691 list of integer values
3694 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3695 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3698 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3700 def GetSubMeshElementType(self, Shape):
3702 Return type of elements on given shape
3705 Shape: a geom object (sub-shape).
3706 *Shape* must be a sub-shape of a ShapeToMesh()
3709 :class:`SMESH.ElementType`
3712 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3713 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3716 return self.mesh.GetSubMeshElementType(ShapeID)
3720 Get the mesh description
3726 return self.mesh.Dump()
3729 # Get the information about nodes and elements of a mesh by its IDs:
3730 # -----------------------------------------------------------
3732 def GetNodeXYZ(self, id):
3734 Get XYZ coordinates of a node.
3735 If there is no node for the given ID - return an empty list
3738 list of float values
3741 return self.mesh.GetNodeXYZ(id)
3743 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3745 Return list of IDs of inverse elements for the given node.
3746 If there is no node for the given ID - return an empty list
3750 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3753 list of integer values
3756 return self.mesh.GetNodeInverseElements(id,elemType)
3758 def GetNodePosition(self,NodeID):
3760 Return the position of a node on the shape
3763 :class:`SMESH.NodePosition`
3766 return self.mesh.GetNodePosition(NodeID)
3768 def GetElementPosition(self,ElemID):
3770 Return the position of an element on the shape
3773 :class:`SMESH.ElementPosition`
3776 return self.mesh.GetElementPosition(ElemID)
3778 def GetShapeID(self, id):
3780 Return the ID of the shape, on which the given node was generated.
3783 an integer value > 0 or -1 if there is no node for the given
3784 ID or the node is not assigned to any geometry
3787 return self.mesh.GetShapeID(id)
3789 def GetShapeIDForElem(self,id):
3791 Return the ID of the shape, on which the given element was generated.
3794 an integer value > 0 or -1 if there is no element for the given
3795 ID or the element is not assigned to any geometry
3798 return self.mesh.GetShapeIDForElem(id)
3800 def GetElemNbNodes(self, id):
3802 Return the number of nodes of the given element
3805 an integer value > 0 or -1 if there is no element for the given ID
3808 return self.mesh.GetElemNbNodes(id)
3810 def GetElemNode(self, id, index):
3812 Return the node ID the given (zero based) index for the given element.
3814 * If there is no element for the given ID - return -1.
3815 * If there is no node for the given index - return -2.
3818 id (int): element ID
3819 index (int): node index within the element
3822 an integer value (ID)
3825 :meth:`GetElemNodes`
3828 return self.mesh.GetElemNode(id, index)
3830 def GetElemNodes(self, id):
3832 Return the IDs of nodes of the given element
3835 a list of integer values
3838 return self.mesh.GetElemNodes(id)
3840 def IsMediumNode(self, elementID, nodeID):
3842 Return true if the given node is the medium node in the given quadratic element
3845 return self.mesh.IsMediumNode(elementID, nodeID)
3847 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3849 Return true if the given node is the medium node in one of quadratic elements
3852 nodeID: ID of the node
3853 elementType: the type of elements to check a state of the node, either of
3854 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3857 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3859 def ElemNbEdges(self, id):
3861 Return the number of edges for the given element
3864 return self.mesh.ElemNbEdges(id)
3866 def ElemNbFaces(self, id):
3868 Return the number of faces for the given element
3871 return self.mesh.ElemNbFaces(id)
3873 def GetElemFaceNodes(self,elemId, faceIndex):
3875 Return nodes of given face (counted from zero) for given volumic element.
3878 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3880 def GetFaceNormal(self, faceId, normalized=False):
3882 Return three components of normal of given mesh face
3883 (or an empty array in KO case)
3886 return self.mesh.GetFaceNormal(faceId,normalized)
3888 def FindElementByNodes(self, nodes):
3890 Return an element based on all given nodes.
3893 return self.mesh.FindElementByNodes(nodes)
3895 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3897 Return elements including all given nodes.
3900 return self.mesh.GetElementsByNodes( nodes, elemType )
3902 def IsPoly(self, id):
3904 Return true if the given element is a polygon
3907 return self.mesh.IsPoly(id)
3909 def IsQuadratic(self, id):
3911 Return true if the given element is quadratic
3914 return self.mesh.IsQuadratic(id)
3916 def GetBallDiameter(self, id):
3918 Return diameter of a ball discrete element or zero in case of an invalid *id*
3921 return self.mesh.GetBallDiameter(id)
3923 def BaryCenter(self, id):
3925 Return XYZ coordinates of the barycenter of the given element.
3926 If there is no element for the given ID - return an empty list
3929 a list of three double values
3932 :meth:`smeshBuilder.GetGravityCenter`
3935 return self.mesh.BaryCenter(id)
3937 def GetIdsFromFilter(self, filter, meshParts=[] ):
3939 Pass mesh elements through the given filter and return IDs of fitting elements
3942 filter: :class:`SMESH.Filter`
3943 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3949 :meth:`SMESH.Filter.GetIDs`
3950 :meth:`SMESH.Filter.GetElementsIdFromParts`
3953 filter.SetMesh( self.mesh )
3956 if isinstance( meshParts, Mesh ):
3957 filter.SetMesh( meshParts.GetMesh() )
3958 return theFilter.GetIDs()
3959 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3960 meshParts = [ meshParts ]
3961 return filter.GetElementsIdFromParts( meshParts )
3963 return filter.GetIDs()
3965 # Get mesh measurements information:
3966 # ------------------------------------
3968 def GetFreeBorders(self):
3970 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3971 Return a list of special structures (borders).
3974 a list of :class:`SMESH.FreeEdges.Border`
3977 aFilterMgr = self.smeshpyD.CreateFilterManager()
3978 aPredicate = aFilterMgr.CreateFreeEdges()
3979 aPredicate.SetMesh(self.mesh)
3980 aBorders = aPredicate.GetBorders()
3981 aFilterMgr.UnRegister()
3984 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3986 Get minimum distance between two nodes, elements or distance to the origin
3989 id1: first node/element id
3990 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3991 isElem1: *True* if *id1* is element id, *False* if it is node id
3992 isElem2: *True* if *id2* is element id, *False* if it is node id
3995 minimum distance value
3997 :meth:`GetMinDistance`
4000 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
4001 return aMeasure.value
4003 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
4005 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
4008 id1: first node/element id
4009 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
4010 isElem1: *True* if *id1* is element id, *False* if it is node id
4011 isElem2: *True* if *id2* is element id, *False* if it is node id
4014 :class:`SMESH.Measure` structure
4020 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
4022 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
4025 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
4027 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4032 aMeasurements = self.smeshpyD.CreateMeasurements()
4033 aMeasure = aMeasurements.MinDistance(id1, id2)
4034 genObjUnRegister([aMeasurements,id1, id2])
4037 def BoundingBox(self, objects=None, isElem=False):
4039 Get bounding box of the specified object(s)
4042 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4043 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4044 *False* specifies that *objects* are nodes
4047 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4050 :meth:`GetBoundingBox()`
4053 result = self.GetBoundingBox(objects, isElem)
4057 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4060 def GetBoundingBox(self, objects=None, isElem=False):
4062 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4065 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4066 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4067 False means that *objects* are nodes
4070 :class:`SMESH.Measure` structure
4073 :meth:`BoundingBox()`
4077 objects = [self.mesh]
4078 elif isinstance(objects, tuple):
4079 objects = list(objects)
4080 if not isinstance(objects, list):
4082 if len(objects) > 0 and isinstance(objects[0], int):
4085 unRegister = genObjUnRegister()
4087 if isinstance(o, Mesh):
4088 srclist.append(o.mesh)
4089 elif hasattr(o, "_narrow"):
4090 src = o._narrow(SMESH.SMESH_IDSource)
4091 if src: srclist.append(src)
4093 elif isinstance(o, list):
4095 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4097 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4098 unRegister.set( srclist[-1] )
4101 aMeasurements = self.smeshpyD.CreateMeasurements()
4102 unRegister.set( aMeasurements )
4103 aMeasure = aMeasurements.BoundingBox(srclist)
4106 # Mesh edition (SMESH_MeshEditor functionality):
4107 # ---------------------------------------------
4109 def RemoveElements(self, IDsOfElements):
4111 Remove the elements from the mesh by ids
4114 IDsOfElements: is a list of ids of elements to remove
4120 This operation can create gaps in numeration of elements.
4121 Call :meth:`RenumberElements` to remove the gaps.
4124 return self.editor.RemoveElements(IDsOfElements)
4126 def RemoveNodes(self, IDsOfNodes):
4128 Remove nodes from mesh by ids
4131 IDsOfNodes: is a list of ids of nodes to remove
4137 This operation can create gaps in numeration of nodes.
4138 Call :meth:`RenumberElements` to remove the gaps.
4141 return self.editor.RemoveNodes(IDsOfNodes)
4143 def RemoveNodeWithReconnection(self, nodeID ):
4145 Remove a node along with changing surrounding faces to cover a hole.
4148 nodeID: ID of node to remove
4151 return self.editor.RemoveNodeWithReconnection( nodeID )
4153 def RemoveOrphanNodes(self):
4155 Remove all orphan (free) nodes from mesh
4158 number of the removed nodes
4161 This operation can create gaps in numeration of nodes.
4162 Call :meth:`RenumberElements` to remove the gaps.
4165 return self.editor.RemoveOrphanNodes()
4167 def AddNode(self, x, y, z):
4169 Add a node to the mesh by coordinates
4175 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4176 if hasVars: self.mesh.SetParameters(Parameters)
4177 return self.editor.AddNode( x, y, z)
4179 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4181 Create a 0D element on a node with given number.
4184 IDOfNode: the ID of node for creation of the element.
4185 DuplicateElements: to add one more 0D element to a node or not
4188 ID of the new 0D element
4191 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4193 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4195 Create 0D elements on all nodes of the given elements except those
4196 nodes on which a 0D element already exists.
4199 theObject: an object on whose nodes 0D elements will be created.
4200 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4201 theGroupName: optional name of a group to add 0D elements created
4202 and/or found on nodes of *theObject*.
4203 DuplicateElements: to add one more 0D element to a node or not
4206 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4207 IDs of new and/or found 0D elements. IDs of 0D elements
4208 can be retrieved from the returned object by
4209 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4212 unRegister = genObjUnRegister()
4213 if isinstance( theObject, Mesh ):
4214 theObject = theObject.GetMesh()
4215 elif isinstance( theObject, list ):
4216 theObject = self.GetIDSource( theObject, SMESH.ALL )
4217 unRegister.set( theObject )
4218 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4220 def AddBall(self, IDOfNode, diameter):
4222 Create a ball element on a node with given ID.
4225 IDOfNode: the ID of node for creation of the element.
4226 diameter: the bal diameter.
4229 ID of the new ball element
4232 return self.editor.AddBall( IDOfNode, diameter )
4234 def AddEdge(self, IDsOfNodes):
4236 Create a linear or quadratic edge (this is determined
4237 by the number of given nodes).
4240 IDsOfNodes: list of node IDs for creation of the element.
4241 The order of nodes in this list should correspond to
4242 the :ref:`connectivity convention <connectivity_page>`.
4248 return self.editor.AddEdge(IDsOfNodes)
4250 def AddFace(self, IDsOfNodes):
4252 Create a linear or quadratic face (this is determined
4253 by the number of given nodes).
4256 IDsOfNodes: list of node IDs for creation of the element.
4257 The order of nodes in this list should correspond to
4258 the :ref:`connectivity convention <connectivity_page>`.
4264 return self.editor.AddFace(IDsOfNodes)
4266 def AddPolygonalFace(self, IdsOfNodes):
4268 Add a polygonal face defined by a list of node IDs
4271 IdsOfNodes: the list of node IDs for creation of the element.
4277 return self.editor.AddPolygonalFace(IdsOfNodes)
4279 def AddQuadPolygonalFace(self, IdsOfNodes):
4281 Add a quadratic polygonal face defined by a list of node IDs
4284 IdsOfNodes: the list of node IDs for creation of the element;
4285 corner nodes follow first.
4291 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4293 def AddVolume(self, IDsOfNodes):
4295 Create both simple and quadratic volume (this is determined
4296 by the number of given nodes).
4299 IDsOfNodes: list of node IDs for creation of the element.
4300 The order of nodes in this list should correspond to
4301 the :ref:`connectivity convention <connectivity_page>`.
4304 ID of the new volumic element
4307 return self.editor.AddVolume(IDsOfNodes)
4309 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4311 Create a volume of many faces, giving nodes for each face.
4314 IdsOfNodes: list of node IDs for volume creation, face by face.
4315 Quantities: list of integer values, Quantities[i]
4316 gives the quantity of nodes in face number i.
4319 ID of the new volumic element
4322 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4324 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4326 Create a volume of many faces, giving the IDs of the existing faces.
4329 The created volume will refer only to the nodes
4330 of the given faces, not to the faces themselves.
4333 IdsOfFaces: the list of face IDs for volume creation.
4336 ID of the new volumic element
4339 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4342 def SetNodeOnVertex(self, NodeID, Vertex):
4344 Bind a node to a vertex
4348 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4351 True if succeed else raises an exception
4354 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4355 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4359 self.editor.SetNodeOnVertex(NodeID, VertexID)
4360 except SALOME.SALOME_Exception as inst:
4361 raise ValueError(inst.details.text)
4365 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4367 Store the node position on an edge
4371 Edge: an edge (GEOM.GEOM_Object) or edge ID
4372 paramOnEdge: a parameter on the edge where the node is located
4375 True if succeed else raises an exception
4378 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4379 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4383 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4384 except SALOME.SALOME_Exception as inst:
4385 raise ValueError(inst.details.text)
4388 def SetNodeOnFace(self, NodeID, Face, u, v):
4390 Store node position on a face
4394 Face: a face (GEOM.GEOM_Object) or face ID
4395 u: U parameter on the face where the node is located
4396 v: V parameter on the face where the node is located
4399 True if succeed else raises an exception
4402 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4403 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4407 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4408 except SALOME.SALOME_Exception as inst:
4409 raise ValueError(inst.details.text)
4412 def SetNodeInVolume(self, NodeID, Solid):
4414 Bind a node to a solid
4418 Solid: a solid (GEOM.GEOM_Object) or solid ID
4421 True if succeed else raises an exception
4424 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4425 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4429 self.editor.SetNodeInVolume(NodeID, SolidID)
4430 except SALOME.SALOME_Exception as inst:
4431 raise ValueError(inst.details.text)
4434 def SetMeshElementOnShape(self, ElementID, Shape):
4436 Bind an element to a shape
4439 ElementID: an element ID
4440 Shape: a shape (GEOM.GEOM_Object) or shape ID
4443 True if succeed else raises an exception
4446 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4447 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4451 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4452 except SALOME.SALOME_Exception as inst:
4453 raise ValueError(inst.details.text)
4457 def MoveNode(self, NodeID, x, y, z):
4459 Move the node with the given id
4462 NodeID: the id of the node
4463 x: a new X coordinate
4464 y: a new Y coordinate
4465 z: a new Z coordinate
4468 True if succeed else False
4471 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4472 if hasVars: self.mesh.SetParameters(Parameters)
4473 return self.editor.MoveNode(NodeID, x, y, z)
4475 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4477 Find the node closest to a point and moves it to a point location
4480 x: the X coordinate of a point
4481 y: the Y coordinate of a point
4482 z: the Z coordinate of a point
4483 NodeID: if specified (>0), the node with this ID is moved,
4484 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4487 the ID of a moved node
4490 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4491 if hasVars: self.mesh.SetParameters(Parameters)
4492 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4494 def FindNodeClosestTo(self, x, y, z):
4496 Find the node closest to a point
4499 x: the X coordinate of a point
4500 y: the Y coordinate of a point
4501 z: the Z coordinate of a point
4507 return self.editor.FindNodeClosestTo(x, y, z)
4509 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4511 Find the elements where a point lays IN or ON
4514 x,y,z (float): coordinates of the point
4515 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4516 means elements of any type excluding nodes, discrete and 0D elements.
4517 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4520 list of IDs of found elements
4523 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4525 return self.editor.FindElementsByPoint(x, y, z, elementType)
4527 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4529 Project a point to a mesh object.
4530 Return ID of an element of given type where the given point is projected
4531 and coordinates of the projection point.
4532 In the case if nothing found, return -1 and []
4534 if isinstance( meshObject, Mesh ):
4535 meshObject = meshObject.GetMesh()
4537 meshObject = self.GetMesh()
4538 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4540 def GetPointState(self, x, y, z):
4542 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4543 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4544 UNKNOWN state means that either mesh is wrong or the analysis fails.
4547 return self.editor.GetPointState(x, y, z)
4549 def IsManifold(self):
4551 Check if a 2D mesh is manifold
4554 return self.editor.IsManifold()
4556 def IsCoherentOrientation2D(self):
4558 Check if orientation of 2D elements is coherent
4561 return self.editor.IsCoherentOrientation2D()
4563 def Get1DBranches( self, edges, startNode = 0 ):
4565 Partition given 1D elements into groups of contiguous edges.
4566 A node where number of meeting edges != 2 is a group end.
4567 An optional startNode is used to orient groups it belongs to.
4570 A list of edge groups and a list of corresponding node groups,
4571 where the group is a list of IDs of edges or nodes, like follows
4572 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4573 If a group is closed, the first and last nodes of the group are same.
4575 if isinstance( edges, Mesh ):
4576 edges = edges.GetMesh()
4577 unRegister = genObjUnRegister()
4578 if isinstance( edges, list ):
4579 edges = self.GetIDSource( edges, SMESH.EDGE )
4580 unRegister.set( edges )
4581 return self.editor.Get1DBranches( edges, startNode )
4583 def FindSharpEdges( self, angle, addExisting=False ):
4585 Return sharp edges of faces and non-manifold ones.
4586 Optionally add existing edges.
4589 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4590 addExisting: to return existing edges (1D elements) as well
4593 list of FaceEdge structures
4595 angle = ParseParameters( angle )[0]
4596 return self.editor.FindSharpEdges( angle, addExisting )
4598 def MeshToPassThroughAPoint(self, x, y, z):
4600 Find the node closest to a point and moves it to a point location
4603 x: the X coordinate of a point
4604 y: the Y coordinate of a point
4605 z: the Z coordinate of a point
4608 the ID of a moved node
4611 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4613 def InverseDiag(self, NodeID1, NodeID2):
4615 Replace two neighbour triangles sharing Node1-Node2 link
4616 with the triangles built on the same 4 nodes but having other common link.
4619 NodeID1: the ID of the first node
4620 NodeID2: the ID of the second node
4623 False if proper faces were not found
4625 return self.editor.InverseDiag(NodeID1, NodeID2)
4627 def DeleteDiag(self, NodeID1, NodeID2):
4629 Replace two neighbour triangles sharing *Node1-Node2* link
4630 with a quadrangle built on the same 4 nodes.
4633 NodeID1: ID of the first node
4634 NodeID2: ID of the second node
4637 False if proper faces were not found
4640 This operation can create gaps in numeration of elements.
4641 Call :meth:`RenumberElements` to remove the gaps.
4644 return self.editor.DeleteDiag(NodeID1, NodeID2)
4646 def AddNodeOnSegment(self, Node1, Node2, position = 0.5):
4648 Replace each triangle bound by Node1-Node2 segment with
4649 two triangles by connecting a node made on the link with a node
4650 opposite to the link.
4653 Node1: ID of the first node
4654 Node2: ID of the second node
4655 position: location [0,1] of the new node on the segment
4657 return self.editor.AddNodeOnSegment(Node1, Node2, position)
4659 def AddNodeOnFace(self, face, x, y, z):
4661 Split a face into triangles by adding a new node onto the face
4662 and connecting the new node with face nodes
4665 face: ID of the face
4666 x,y,z: coordinates of the new node
4668 return self.editor.AddNodeOnFace(face, x, y, z)
4670 def Reorient(self, IDsOfElements=None):
4672 Reorient elements by ids
4675 IDsOfElements: if undefined reorients all mesh elements
4678 True if succeed else False
4681 if IDsOfElements == None:
4682 IDsOfElements = self.GetElementsId()
4683 return self.editor.Reorient(IDsOfElements)
4685 def ReorientObject(self, theObject):
4687 Reorient all elements of the object
4690 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4693 True if succeed else False
4696 if ( isinstance( theObject, Mesh )):
4697 theObject = theObject.GetMesh()
4698 return self.editor.ReorientObject(theObject)
4700 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4702 Reorient faces contained in *the2DObject*.
4705 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4706 theDirection: a desired direction of normal of *theFace*.
4707 It can be either a GEOM vector or a list of coordinates [x,y,z].
4708 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4709 compared with theDirection. It can be either ID of face or a point
4710 by which the face will be found. The point can be given as either
4711 a GEOM vertex or a list of point coordinates.
4714 number of reoriented faces
4717 unRegister = genObjUnRegister()
4719 if isinstance( the2DObject, Mesh ):
4720 the2DObject = the2DObject.GetMesh()
4721 if isinstance( the2DObject, list ):
4722 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4723 unRegister.set( the2DObject )
4724 # check theDirection
4725 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4726 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4727 if isinstance( theDirection, list ):
4728 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4729 # prepare theFace and thePoint
4730 theFace = theFaceOrPoint
4731 thePoint = PointStruct(0,0,0)
4732 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4733 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4735 if isinstance( theFaceOrPoint, list ):
4736 thePoint = PointStruct( *theFaceOrPoint )
4738 if isinstance( theFaceOrPoint, PointStruct ):
4739 thePoint = theFaceOrPoint
4741 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4743 def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4745 Reorient faces contained in a list of *objectFaces*
4746 equally to faces contained in a list of *referenceFaces*.
4749 objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4750 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.
4753 number of reoriented faces.
4755 if not isinstance( objectFaces, list ):
4756 objectFaces = [ objectFaces ]
4757 for i,obj2D in enumerate( objectFaces ):
4758 if isinstance( obj2D, Mesh ):
4759 objectFaces[i] = obj2D.GetMesh()
4760 if not isinstance( referenceFaces, list ):
4761 referenceFaces = [ referenceFaces ]
4763 return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4766 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4768 Reorient faces according to adjacent volumes.
4771 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4772 either IDs of faces or face groups.
4773 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4774 theOutsideNormal: to orient faces to have their normals
4775 pointing either *outside* or *inside* the adjacent volumes.
4778 number of reoriented faces.
4781 unRegister = genObjUnRegister()
4783 if not isinstance( the2DObject, list ):
4784 the2DObject = [ the2DObject ]
4785 elif the2DObject and isinstance( the2DObject[0], int ):
4786 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4787 unRegister.set( the2DObject )
4788 the2DObject = [ the2DObject ]
4789 for i,obj2D in enumerate( the2DObject ):
4790 if isinstance( obj2D, Mesh ):
4791 the2DObject[i] = obj2D.GetMesh()
4792 if isinstance( obj2D, list ):
4793 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4794 unRegister.set( the2DObject[i] )
4796 if isinstance( the3DObject, Mesh ):
4797 the3DObject = the3DObject.GetMesh()
4798 if isinstance( the3DObject, list ):
4799 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4800 unRegister.set( the3DObject )
4801 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4803 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4805 Fuse the neighbouring triangles into quadrangles.
4808 IDsOfElements: The triangles to be fused.
4809 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4810 applied to possible quadrangles to choose a neighbour to fuse with.
4811 Note that not all items of :class:`SMESH.FunctorType` corresponds
4812 to numerical functors.
4813 MaxAngle: is the maximum angle between element normals at which the fusion
4814 is still performed; theMaxAngle is measured in radians.
4815 Also it could be a name of variable which defines angle in degrees.
4818 True in case of success, False otherwise.
4821 This operation can create gaps in numeration of elements.
4822 Call :meth:`RenumberElements` to remove the gaps.
4825 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4826 self.mesh.SetParameters(Parameters)
4827 if not IDsOfElements:
4828 IDsOfElements = self.GetElementsId()
4829 Functor = self.smeshpyD.GetFunctor(theCriterion)
4830 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4832 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4834 Fuse the neighbouring triangles of the object into quadrangles
4837 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4838 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4839 applied to possible quadrangles to choose a neighbour to fuse with.
4840 Note that not all items of :class:`SMESH.FunctorType` corresponds
4841 to numerical functors.
4842 MaxAngle: a max angle between element normals at which the fusion
4843 is still performed; theMaxAngle is measured in radians.
4846 True in case of success, False otherwise.
4849 This operation can create gaps in numeration of elements.
4850 Call :meth:`RenumberElements` to remove the gaps.
4853 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4854 self.mesh.SetParameters(Parameters)
4855 if isinstance( theObject, Mesh ):
4856 theObject = theObject.GetMesh()
4857 Functor = self.smeshpyD.GetFunctor(theCriterion)
4858 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4860 def QuadToTri (self, IDsOfElements, theCriterion = None):
4862 Split quadrangles into triangles.
4865 IDsOfElements: the faces to be splitted.
4866 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4867 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4868 value, then quadrangles will be split by the smallest diagonal.
4869 Note that not all items of :class:`SMESH.FunctorType` corresponds
4870 to numerical functors.
4873 True in case of success, False otherwise.
4876 This operation can create gaps in numeration of elements.
4877 Call :meth:`RenumberElements` to remove the gaps.
4879 if IDsOfElements == []:
4880 IDsOfElements = self.GetElementsId()
4881 if theCriterion is None:
4882 theCriterion = FT_MaxElementLength2D
4883 Functor = self.smeshpyD.GetFunctor(theCriterion)
4884 return self.editor.QuadToTri(IDsOfElements, Functor)
4886 def QuadToTriObject (self, theObject, theCriterion = None):
4888 Split quadrangles into triangles.
4891 theObject: the object from which the list of elements is taken,
4892 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4893 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4894 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4895 value, then quadrangles will be split by the smallest diagonal.
4896 Note that not all items of :class:`SMESH.FunctorType` corresponds
4897 to numerical functors.
4900 True in case of success, False otherwise.
4903 This operation can create gaps in numeration of elements.
4904 Call :meth:`RenumberElements` to remove the gaps.
4906 if ( isinstance( theObject, Mesh )):
4907 theObject = theObject.GetMesh()
4908 if theCriterion is None:
4909 theCriterion = FT_MaxElementLength2D
4910 Functor = self.smeshpyD.GetFunctor(theCriterion)
4911 return self.editor.QuadToTriObject(theObject, Functor)
4913 def QuadTo4Tri (self, theElements=[]):
4915 Split each of given quadrangles into 4 triangles. A node is added at the center of
4919 theElements: the faces to be splitted. This can be either
4920 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4921 or a list of face IDs. By default all quadrangles are split
4924 This operation can create gaps in numeration of elements.
4925 Call :meth:`RenumberElements` to remove the gaps.
4927 unRegister = genObjUnRegister()
4928 if isinstance( theElements, Mesh ):
4929 theElements = theElements.mesh
4930 elif not theElements:
4931 theElements = self.mesh
4932 elif isinstance( theElements, list ):
4933 theElements = self.GetIDSource( theElements, SMESH.FACE )
4934 unRegister.set( theElements )
4935 return self.editor.QuadTo4Tri( theElements )
4937 def SplitQuad (self, IDsOfElements, Diag13):
4939 Split quadrangles into triangles.
4942 IDsOfElements: the faces to be splitted
4943 Diag13 (boolean): is used to choose a diagonal for splitting.
4946 True in case of success, False otherwise.
4949 This operation can create gaps in numeration of elements.
4950 Call :meth:`RenumberElements` to remove the gaps.
4952 if IDsOfElements == []:
4953 IDsOfElements = self.GetElementsId()
4954 return self.editor.SplitQuad(IDsOfElements, Diag13)
4956 def SplitQuadObject (self, theObject, Diag13):
4958 Split quadrangles into triangles.
4961 theObject: the object from which the list of elements is taken,
4962 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4963 Diag13 (boolean): is used to choose a diagonal for splitting.
4966 True in case of success, False otherwise.
4969 This operation can create gaps in numeration of elements.
4970 Call :meth:`RenumberElements` to remove the gaps.
4972 if ( isinstance( theObject, Mesh )):
4973 theObject = theObject.GetMesh()
4974 return self.editor.SplitQuadObject(theObject, Diag13)
4976 def BestSplit (self, IDOfQuad, theCriterion):
4978 Find a better splitting of the given quadrangle.
4981 IDOfQuad: the ID of the quadrangle to be splitted.
4982 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4983 choose a diagonal for splitting.
4984 Note that not all items of :class:`SMESH.FunctorType` corresponds
4985 to numerical functors.
4988 * 1 if 1-3 diagonal is better,
4989 * 2 if 2-4 diagonal is better,
4990 * 0 if error occurs.
4993 This operation can create gaps in numeration of elements.
4994 Call :meth:`RenumberElements` to remove the gaps.
4996 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4998 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
5000 Split volumic elements into tetrahedrons
5003 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5004 method: flags passing splitting method:
5005 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
5006 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
5009 This operation can create gaps in numeration of elements.
5010 Call :meth:`RenumberElements` to remove the gaps.
5012 unRegister = genObjUnRegister()
5013 if isinstance( elems, Mesh ):
5014 elems = elems.GetMesh()
5015 if ( isinstance( elems, list )):
5016 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5017 unRegister.set( elems )
5018 self.editor.SplitVolumesIntoTetra(elems, method)
5021 def SplitBiQuadraticIntoLinear(self, elems=None):
5023 Split bi-quadratic elements into linear ones without creation of additional nodes:
5025 - bi-quadratic triangle will be split into 3 linear quadrangles;
5026 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
5027 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
5029 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
5030 will be split in order to keep the mesh conformal.
5033 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
5034 if None (default), all bi-quadratic elements will be split
5037 This operation can create gaps in numeration of elements.
5038 Call :meth:`RenumberElements` to remove the gaps.
5040 unRegister = genObjUnRegister()
5041 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
5042 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
5043 unRegister.set( elems )
5045 elems = [ self.GetMesh() ]
5046 if isinstance( elems, Mesh ):
5047 elems = [ elems.GetMesh() ]
5048 if not isinstance( elems, list ):
5050 self.editor.SplitBiQuadraticIntoLinear( elems )
5052 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
5053 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
5055 Split hexahedra into prisms
5058 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5059 startHexPoint: a point used to find a hexahedron for which *facetNormal*
5060 gives a normal vector defining facets to split into triangles.
5061 *startHexPoint* can be either a triple of coordinates or a vertex.
5062 facetNormal: a normal to a facet to split into triangles of a
5063 hexahedron found by *startHexPoint*.
5064 *facetNormal* can be either a triple of coordinates or an edge.
5065 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
5066 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
5067 allDomains: if :code:`False`, only hexahedra adjacent to one closest
5068 to *startHexPoint* are split, else *startHexPoint*
5069 is used to find the facet to split in all domains present in *elems*.
5072 This operation can create gaps in numeration of elements.
5073 Call :meth:`RenumberElements` to remove the gaps.
5076 unRegister = genObjUnRegister()
5077 if isinstance( elems, Mesh ):
5078 elems = elems.GetMesh()
5079 if ( isinstance( elems, list )):
5080 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5081 unRegister.set( elems )
5084 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5085 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5086 elif isinstance( startHexPoint, list ):
5087 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5090 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5091 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5092 elif isinstance( facetNormal, list ):
5093 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5096 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5098 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5100 def SplitQuadsNearTriangularFacets(self):
5102 Split quadrangle faces near triangular facets of volumes
5105 This operation can create gaps in numeration of elements.
5106 Call :meth:`RenumberElements` to remove the gaps.
5108 faces_array = self.GetElementsByType(SMESH.FACE)
5109 for face_id in faces_array:
5110 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5111 quad_nodes = self.mesh.GetElemNodes(face_id)
5112 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5113 isVolumeFound = False
5114 for node1_elem in node1_elems:
5115 if not isVolumeFound:
5116 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5117 nb_nodes = self.GetElemNbNodes(node1_elem)
5118 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5119 volume_elem = node1_elem
5120 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5121 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5122 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5123 isVolumeFound = True
5124 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5125 self.SplitQuad([face_id], False) # diagonal 2-4
5126 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5127 isVolumeFound = True
5128 self.SplitQuad([face_id], True) # diagonal 1-3
5129 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5130 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5131 isVolumeFound = True
5132 self.SplitQuad([face_id], True) # diagonal 1-3
5134 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5136 Split hexahedrons into tetrahedrons.
5138 This operation uses :doc:`pattern_mapping` functionality for splitting.
5141 theObject: the object from which the list of hexahedrons is taken;
5142 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5143 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5144 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5145 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5146 key-point will be mapped into *theNode001*-th node of each volume.
5147 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5150 True in case of success, False otherwise.
5153 This operation can create gaps in numeration of elements.
5154 Call :meth:`RenumberElements` to remove the gaps.
5162 # (0,0,1) 4.---------.7 * |
5169 # (0,0,0) 0.---------.3
5170 pattern_tetra = "!!! Nb of points: \n 8 \n\
5180 !!! Indices of points of 6 tetras: \n\
5188 pattern = self.smeshpyD.GetPattern()
5189 isDone = pattern.LoadFromFile(pattern_tetra)
5191 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5194 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5195 isDone = pattern.MakeMesh(self.mesh, False, False)
5196 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5198 # split quafrangle faces near triangular facets of volumes
5199 self.SplitQuadsNearTriangularFacets()
5203 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5205 Split hexahedrons into prisms.
5207 Uses the :doc:`pattern_mapping` functionality for splitting.
5210 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5211 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5212 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5213 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5214 will be mapped into the *theNode001* -th node of each volume.
5215 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5218 True in case of success, False otherwise.
5221 This operation can create gaps in numeration of elements.
5222 Call :meth:`RenumberElements` to remove the gaps.
5224 # Pattern: 5.---------.6
5229 # (0,0,1) 4.---------.7 |
5236 # (0,0,0) 0.---------.3
5237 pattern_prism = "!!! Nb of points: \n 8 \n\
5247 !!! Indices of points of 2 prisms: \n\
5251 pattern = self.smeshpyD.GetPattern()
5252 isDone = pattern.LoadFromFile(pattern_prism)
5254 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5257 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5258 isDone = pattern.MakeMesh(self.mesh, False, False)
5259 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5261 # Split quafrangle faces near triangular facets of volumes
5262 self.SplitQuadsNearTriangularFacets()
5266 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5267 MaxNbOfIterations, MaxAspectRatio, Method):
5272 IDsOfElements: the list if ids of elements to smooth
5273 IDsOfFixedNodes: the list of ids of fixed nodes.
5274 Note that nodes built on edges and boundary nodes are always fixed.
5275 MaxNbOfIterations: the maximum number of iterations
5276 MaxAspectRatio: varies in range [1.0, inf]
5277 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5278 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5281 True in case of success, False otherwise.
5284 if IDsOfElements == []:
5285 IDsOfElements = self.GetElementsId()
5286 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5287 self.mesh.SetParameters(Parameters)
5288 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5289 MaxNbOfIterations, MaxAspectRatio, Method)
5291 def SmoothObject(self, theObject, IDsOfFixedNodes,
5292 MaxNbOfIterations, MaxAspectRatio, Method):
5294 Smooth elements which belong to the given object
5297 theObject: the object to smooth
5298 IDsOfFixedNodes: the list of ids of fixed nodes.
5299 Note that nodes built on edges and boundary nodes are always fixed.
5300 MaxNbOfIterations: the maximum number of iterations
5301 MaxAspectRatio: varies in range [1.0, inf]
5302 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5303 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5306 True in case of success, False otherwise.
5309 if ( isinstance( theObject, Mesh )):
5310 theObject = theObject.GetMesh()
5311 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5312 MaxNbOfIterations, MaxAspectRatio, Method)
5314 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5315 MaxNbOfIterations, MaxAspectRatio, Method):
5317 Parametrically smooth the given elements
5320 IDsOfElements: the list if ids of elements to smooth
5321 IDsOfFixedNodes: the list of ids of fixed nodes.
5322 Note that nodes built on edges and boundary nodes are always fixed.
5323 MaxNbOfIterations: the maximum number of iterations
5324 MaxAspectRatio: varies in range [1.0, inf]
5325 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5326 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5329 True in case of success, False otherwise.
5332 if IDsOfElements == []:
5333 IDsOfElements = self.GetElementsId()
5334 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5335 self.mesh.SetParameters(Parameters)
5336 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5337 MaxNbOfIterations, MaxAspectRatio, Method)
5339 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5340 MaxNbOfIterations, MaxAspectRatio, Method):
5342 Parametrically smooth the elements which belong to the given object
5345 theObject: the object to smooth
5346 IDsOfFixedNodes: the list of ids of fixed nodes.
5347 Note that nodes built on edges and boundary nodes are always fixed.
5348 MaxNbOfIterations: the maximum number of iterations
5349 MaxAspectRatio: varies in range [1.0, inf]
5350 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5351 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5354 True in case of success, False otherwise.
5357 if ( isinstance( theObject, Mesh )):
5358 theObject = theObject.GetMesh()
5359 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5360 MaxNbOfIterations, MaxAspectRatio, Method)
5362 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5364 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5365 them with quadratic with the same id.
5368 theForce3d: method of new node creation:
5370 * False - the medium node lies at the geometrical entity from which the mesh element is built
5371 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5372 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5373 theToBiQuad: If True, converts the mesh to bi-quadratic
5376 :class:`SMESH.ComputeError` which can hold a warning
5379 If *theSubMesh* is provided, the mesh can become non-conformal
5382 This operation can create gaps in numeration of nodes or elements.
5383 Call :meth:`RenumberElements` to remove the gaps.
5386 if isinstance( theSubMesh, Mesh ):
5387 theSubMesh = theSubMesh.mesh
5389 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5392 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5394 self.editor.ConvertToQuadratic(theForce3d)
5395 error = self.editor.GetLastError()
5396 if error and error.comment:
5397 print(error.comment)
5400 def ConvertFromQuadratic(self, theSubMesh=None):
5402 Convert the mesh from quadratic to ordinary,
5403 deletes old quadratic elements,
5404 replacing them with ordinary mesh elements with the same id.
5407 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5410 If *theSubMesh* is provided, the mesh can become non-conformal
5413 This operation can create gaps in numeration of nodes or elements.
5414 Call :meth:`RenumberElements` to remove the gaps.
5418 self.editor.ConvertFromQuadraticObject(theSubMesh)
5420 return self.editor.ConvertFromQuadratic()
5422 def Make2DMeshFrom3D(self):
5424 Create 2D mesh as skin on boundary faces of a 3D mesh
5427 True if operation has been completed successfully, False otherwise
5430 return self.editor.Make2DMeshFrom3D()
5432 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5433 toCopyElements=False, toCopyExistingBondary=False):
5435 Create missing boundary elements
5438 elements: elements whose boundary is to be checked:
5439 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5440 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5441 dimension: defines type of boundary elements to create, either of
5442 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5443 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5444 groupName: a name of group to store created boundary elements in,
5445 "" means not to create the group
5446 meshName: a name of new mesh to store created boundary elements in,
5447 "" means not to create the new mesh
5448 toCopyElements: if True, the checked elements will be copied into
5449 the new mesh else only boundary elements will be copied into the new mesh
5450 toCopyExistingBondary: if True, not only new but also pre-existing
5451 boundary elements will be copied into the new mesh
5454 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5457 unRegister = genObjUnRegister()
5458 if isinstance( elements, Mesh ):
5459 elements = elements.GetMesh()
5460 if ( isinstance( elements, list )):
5461 elemType = SMESH.ALL
5462 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5463 elements = self.editor.MakeIDSource(elements, elemType)
5464 unRegister.set( elements )
5465 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5466 toCopyElements,toCopyExistingBondary)
5467 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5470 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5471 toCopyAll=False, groups=[]):
5473 Create missing boundary elements around either the whole mesh or
5477 dimension: defines type of boundary elements to create, either of
5478 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5479 groupName: a name of group to store all boundary elements in,
5480 "" means not to create the group
5481 meshName: a name of a new mesh, which is a copy of the initial
5482 mesh + created boundary elements; "" means not to create the new mesh
5483 toCopyAll: if True, the whole initial mesh will be copied into
5484 the new mesh else only boundary elements will be copied into the new mesh
5485 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5488 tuple( long, mesh, group )
5489 - long - number of added boundary elements
5490 - mesh - the :class:`Mesh` where elements were added to
5491 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5494 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5496 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5497 return nb, mesh, group
5499 def RenumberNodes(self):
5501 Renumber mesh nodes to remove unused node IDs
5503 self.editor.RenumberNodes()
5505 def RenumberElements(self):
5507 Renumber mesh elements to remove unused element IDs
5509 self.editor.RenumberElements()
5511 def _getIdSourceList(self, arg, idType, unRegister):
5513 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5515 if arg and isinstance( arg, list ):
5516 if isinstance( arg[0], int ):
5517 arg = self.GetIDSource( arg, idType )
5518 unRegister.set( arg )
5519 elif isinstance( arg[0], Mesh ):
5520 arg[0] = arg[0].GetMesh()
5521 elif isinstance( arg, Mesh ):
5523 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5527 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5528 MakeGroups=False, TotalAngle=False):
5530 Generate new elements by rotation of the given elements and nodes around the axis
5533 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5534 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5535 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5536 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5537 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5538 which defines angle in degrees
5539 NbOfSteps: the number of steps
5540 Tolerance: tolerance
5541 MakeGroups: forces the generation of new groups from existing ones
5542 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5543 of all steps, else - size of each step
5546 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5549 unRegister = genObjUnRegister()
5550 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5551 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5552 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5554 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5555 Axis = self.smeshpyD.GetAxisStruct( Axis )
5556 if isinstance( Axis, list ):
5557 Axis = SMESH.AxisStruct( *Axis )
5559 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5560 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5561 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5562 self.mesh.SetParameters(Parameters)
5563 if TotalAngle and NbOfSteps:
5564 AngleInRadians /= NbOfSteps
5565 return self.editor.RotationSweepObjects( nodes, edges, faces,
5566 Axis, AngleInRadians,
5567 NbOfSteps, Tolerance, MakeGroups)
5569 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5570 MakeGroups=False, TotalAngle=False):
5572 Generate new elements by rotation of the elements around the axis
5575 IDsOfElements: the list of ids of elements to sweep
5576 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5577 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5578 NbOfSteps: the number of steps
5579 Tolerance: tolerance
5580 MakeGroups: forces the generation of new groups from existing ones
5581 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5582 of all steps, else - size of each step
5585 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5588 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5589 AngleInRadians, NbOfSteps, Tolerance,
5590 MakeGroups, TotalAngle)
5592 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5593 MakeGroups=False, TotalAngle=False):
5595 Generate new elements by rotation of the elements of object around the axis
5596 theObject object which elements should be sweeped.
5597 It can be a mesh, a sub mesh or a group.
5600 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5601 AngleInRadians: the angle of Rotation
5602 NbOfSteps: number of steps
5603 Tolerance: tolerance
5604 MakeGroups: forces the generation of new groups from existing ones
5605 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5606 of all steps, else - size of each step
5609 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5612 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5613 AngleInRadians, NbOfSteps, Tolerance,
5614 MakeGroups, TotalAngle )
5616 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5617 MakeGroups=False, TotalAngle=False):
5619 Generate new elements by rotation of the elements of object around the axis
5620 theObject object which elements should be sweeped.
5621 It can be a mesh, a sub mesh or a group.
5624 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5625 AngleInRadians: the angle of Rotation
5626 NbOfSteps: number of steps
5627 Tolerance: tolerance
5628 MakeGroups: forces the generation of new groups from existing ones
5629 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5630 of all steps, else - size of each step
5633 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5634 empty list otherwise
5637 return self.RotationSweepObjects([],theObject,[], Axis,
5638 AngleInRadians, NbOfSteps, Tolerance,
5639 MakeGroups, TotalAngle)
5641 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5642 MakeGroups=False, TotalAngle=False):
5644 Generate new elements by rotation of the elements of object around the axis
5645 theObject object which elements should be sweeped.
5646 It can be a mesh, a sub mesh or a group.
5649 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5650 AngleInRadians: the angle of Rotation
5651 NbOfSteps: number of steps
5652 Tolerance: tolerance
5653 MakeGroups: forces the generation of new groups from existing ones
5654 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5655 of all steps, else - size of each step
5658 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5661 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5662 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5664 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5665 scaleFactors=[], linearVariation=False, basePoint=[],
5666 angles=[], anglesVariation=False):
5668 Generate new elements by extrusion of the given elements and nodes
5671 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5672 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5673 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5674 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5675 the direction and value of extrusion for one step (the total extrusion
5676 length will be NbOfSteps * ||StepVector||)
5677 NbOfSteps: the number of steps
5678 MakeGroups: forces the generation of new groups from existing ones
5679 scaleFactors: optional scale factors to apply during extrusion
5680 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5681 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5682 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5683 nodes and elements being extruded is used as the scaling center.
5686 - a list of tree components of the point or
5689 angles: list of angles in radians. Nodes at each extrusion step are rotated
5690 around *basePoint*, additionally to previous steps.
5691 anglesVariation: forces the computation of rotation angles as linear
5692 variation of the given *angles* along path steps
5694 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5696 Example: :ref:`tui_extrusion`
5698 unRegister = genObjUnRegister()
5699 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5700 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5701 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5703 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5704 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5705 if isinstance( StepVector, list ):
5706 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5708 if isinstance( basePoint, int):
5709 xyz = self.GetNodeXYZ( basePoint )
5711 raise RuntimeError("Invalid node ID: %s" % basePoint)
5713 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5714 basePoint = self.geompyD.PointCoordinates( basePoint )
5716 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5717 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5718 angles,angleParameters,hasVars = ParseAngles(angles)
5719 Parameters = StepVector.PS.parameters + var_separator + \
5720 Parameters + var_separator + \
5721 scaleParameters + var_separator + angleParameters
5722 self.mesh.SetParameters(Parameters)
5724 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5725 StepVector, NbOfSteps, MakeGroups,
5726 scaleFactors, linearVariation, basePoint,
5727 angles, anglesVariation )
5730 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5732 Generate new elements by extrusion of the elements with given ids
5735 IDsOfElements: the list of ids of elements or nodes for extrusion
5736 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5737 the direction and value of extrusion for one step (the total extrusion
5738 length will be NbOfSteps * ||StepVector||)
5739 NbOfSteps: the number of steps
5740 MakeGroups: forces the generation of new groups from existing ones
5741 IsNodes: is True if elements with given ids are nodes
5744 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5746 Example: :ref:`tui_extrusion`
5749 if IsNodes: n = IDsOfElements
5750 else : e,f, = IDsOfElements,IDsOfElements
5751 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5753 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5754 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5756 Generate new elements by extrusion along the normal to a discretized surface or wire
5759 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5760 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5761 StepSize: length of one extrusion step (the total extrusion
5762 length will be *NbOfSteps* *StepSize*).
5763 NbOfSteps: number of extrusion steps.
5764 ByAverageNormal: if True each node is translated by *StepSize*
5765 along the average of the normal vectors to the faces sharing the node;
5766 else each node is translated along the same average normal till
5767 intersection with the plane got by translation of the face sharing
5768 the node along its own normal by *StepSize*.
5769 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5770 for every node of *Elements*.
5771 MakeGroups: forces generation of new groups from existing ones.
5772 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5773 is not yet implemented. This parameter is used if *Elements* contains
5774 both faces and edges, i.e. *Elements* is a Mesh.
5777 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5778 empty list otherwise.
5779 Example: :ref:`tui_extrusion`
5782 unRegister = genObjUnRegister()
5783 if isinstance( Elements, Mesh ):
5784 Elements = [ Elements.GetMesh() ]
5785 if isinstance( Elements, list ):
5787 raise RuntimeError("Elements empty!")
5788 if isinstance( Elements[0], Mesh ):
5789 Elements = [ Elements[0].GetMesh() ]
5790 if isinstance( Elements[0], int ):
5791 Elements = self.GetIDSource( Elements, SMESH.ALL )
5792 unRegister.set( Elements )
5793 if not isinstance( Elements, list ):
5794 Elements = [ Elements ]
5795 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5796 self.mesh.SetParameters(Parameters)
5797 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5798 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5800 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5802 Generate new elements by extrusion of the elements or nodes which belong to the object
5805 theObject: the object whose elements or nodes should be processed.
5806 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5807 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5808 the direction and value of extrusion for one step (the total extrusion
5809 length will be NbOfSteps * ||StepVector||)
5810 NbOfSteps: the number of steps
5811 MakeGroups: forces the generation of new groups from existing ones
5812 IsNodes: is True if elements to extrude are nodes
5815 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5816 Example: :ref:`tui_extrusion`
5820 if IsNodes: n = theObject
5821 else : e,f, = theObject,theObject
5822 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5824 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5826 Generate new elements by extrusion of edges which belong to the object
5829 theObject: object whose 1D elements should be processed.
5830 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5831 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5832 the direction and value of extrusion for one step (the total extrusion
5833 length will be NbOfSteps * ||StepVector||)
5834 NbOfSteps: the number of steps
5835 MakeGroups: to generate new groups from existing ones
5838 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5839 Example: :ref:`tui_extrusion`
5842 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5844 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5846 Generate new elements by extrusion of faces which belong to the object
5849 theObject: object whose 2D elements should be processed.
5850 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5851 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5852 the direction and value of extrusion for one step (the total extrusion
5853 length will be NbOfSteps * ||StepVector||)
5854 NbOfSteps: the number of steps
5855 MakeGroups: forces the generation of new groups from existing ones
5858 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5859 Example: :ref:`tui_extrusion`
5862 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5864 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5865 ExtrFlags, SewTolerance, MakeGroups=False):
5867 Generate new elements by extrusion of the elements with given ids
5870 IDsOfElements: is ids of elements
5871 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5872 the direction and value of extrusion for one step (the total extrusion
5873 length will be NbOfSteps * ||StepVector||)
5874 NbOfSteps: the number of steps
5875 ExtrFlags: sets flags for extrusion
5876 SewTolerance: uses for comparing locations of nodes if flag
5877 EXTRUSION_FLAG_SEW is set
5878 MakeGroups: forces the generation of new groups from existing ones
5881 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5884 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5885 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5886 if isinstance( StepVector, list ):
5887 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5888 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5889 ExtrFlags, SewTolerance, MakeGroups)
5891 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5892 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5893 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5894 ScaleFactors=[], ScalesVariation=False):
5896 Generate new elements by extrusion of the given elements and nodes along the path.
5897 The path of extrusion must be a meshed edge.
5900 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5901 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5902 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5903 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5904 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
5905 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5906 HasAngles: not used obsolete
5907 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5908 around *basePoint*, additionally to previous steps.
5909 LinearVariation: forces the computation of rotation angles as linear
5910 variation of the given Angles along path steps
5911 HasRefPoint: allows using the reference point
5912 RefPoint: optional scaling and rotation center (mass center of the extruded
5913 elements by default). The User can specify any point as the Reference Point.
5914 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5915 MakeGroups: forces the generation of new groups from existing ones
5916 ScaleFactors: optional scale factors to apply during extrusion
5917 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5918 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5921 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5922 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5923 Example: :ref:`tui_extrusion_along_path`
5926 unRegister = genObjUnRegister()
5927 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5928 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5929 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5931 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5932 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5933 if isinstance( RefPoint, list ):
5934 if not RefPoint: RefPoint = [0,0,0]
5935 RefPoint = SMESH.PointStruct( *RefPoint )
5936 if isinstance( PathObject, Mesh ):
5937 PathObject = PathObject.GetMesh()
5938 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5939 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5940 Parameters = AnglesParameters + var_separator + \
5941 RefPoint.parameters + var_separator + ScalesParameters
5942 self.mesh.SetParameters(Parameters)
5943 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5944 PathObject, PathShape, NodeStart,
5945 HasAngles, Angles, LinearVariation,
5946 HasRefPoint, RefPoint, MakeGroups,
5947 ScaleFactors, ScalesVariation)
5949 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5950 HasAngles=False, Angles=[], LinearVariation=False,
5951 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5952 ElemType=SMESH.FACE):
5954 Generate new elements by extrusion of the given elements.
5955 The path of extrusion must be a meshed edge.
5958 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5959 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5960 NodeStart: the start node from Path. Defines the direction of extrusion
5961 HasAngles: not used obsolete
5962 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5963 around *basePoint*, additionally to previous steps.
5964 LinearVariation: forces the computation of rotation angles as linear
5965 variation of the given Angles along path steps
5966 HasRefPoint: allows using the reference point
5967 RefPoint: the reference point around which the elements are rotated (the mass
5968 center of the elements by default).
5969 The User can specify any point as the Reference Point.
5970 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5971 MakeGroups: forces the generation of new groups from existing ones
5972 ElemType: type of elements for extrusion (if param Base is a mesh)
5975 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5976 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5977 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5979 Example: :ref:`tui_extrusion_along_path`
5983 if ElemType == SMESH.NODE: n = Base
5984 if ElemType == SMESH.EDGE: e = Base
5985 if ElemType == SMESH.FACE: f = Base
5986 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5987 HasAngles, Angles, LinearVariation,
5988 HasRefPoint, RefPoint, MakeGroups)
5989 if MakeGroups: return gr,er
5992 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5993 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5994 MakeGroups=False, LinearVariation=False):
5996 Generate new elements by extrusion of the given elements.
5997 The path of extrusion must be a meshed edge.
6000 IDsOfElements: ids of elements
6001 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
6002 PathShape: shape (edge) defines the sub-mesh for the path
6003 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6004 HasAngles: not used obsolete
6005 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6006 around *basePoint*, additionally to previous steps.
6007 HasRefPoint: allows using the reference point
6008 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6009 The User can specify any point as the Reference Point.
6010 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6011 MakeGroups: forces the generation of new groups from existing ones
6012 LinearVariation: forces the computation of rotation angles as linear
6013 variation of the given Angles along path steps
6016 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6017 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6018 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6019 Example: :ref:`tui_extrusion_along_path`
6022 if not IDsOfElements:
6023 IDsOfElements = [ self.GetMesh() ]
6024 n,e,f = [],IDsOfElements,IDsOfElements
6025 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
6026 NodeStart, HasAngles, Angles,
6028 HasRefPoint, RefPoint, MakeGroups)
6029 if MakeGroups: return gr,er
6032 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
6033 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6034 MakeGroups=False, LinearVariation=False):
6036 Generate new elements by extrusion of the elements which belong to the object.
6037 The path of extrusion must be a meshed edge.
6040 theObject: the object whose elements should be processed.
6041 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6042 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6043 PathShape: shape (edge) defines the sub-mesh for the path
6044 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6045 HasAngles: not used obsolete
6046 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6047 around *basePoint*, additionally to previous steps.
6048 HasRefPoint: allows using the reference point
6049 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6050 The User can specify any point as the Reference Point.
6051 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6052 MakeGroups: forces the generation of new groups from existing ones
6053 LinearVariation: forces the computation of rotation angles as linear
6054 variation of the given Angles along path steps
6057 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6058 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6059 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6060 Example: :ref:`tui_extrusion_along_path`
6063 n,e,f = [],theObject,theObject
6064 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6065 HasAngles, Angles, LinearVariation,
6066 HasRefPoint, RefPoint, MakeGroups)
6067 if MakeGroups: return gr,er
6070 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
6071 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6072 MakeGroups=False, LinearVariation=False):
6074 Generate new elements by extrusion of mesh segments which belong to the object.
6075 The path of extrusion must be a meshed edge.
6078 theObject: the object whose 1D elements should be processed.
6079 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6080 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6081 PathShape: shape (edge) defines the sub-mesh for the path
6082 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6083 HasAngles: not used obsolete
6084 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6085 around *basePoint*, additionally to previous steps.
6086 HasRefPoint: allows using the reference point
6087 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6088 The User can specify any point as the Reference Point.
6089 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6090 MakeGroups: forces the generation of new groups from existing ones
6091 LinearVariation: forces the computation of rotation angles as linear
6092 variation of the given Angles along path steps
6095 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6096 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6097 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6098 Example: :ref:`tui_extrusion_along_path`
6101 n,e,f = [],theObject,[]
6102 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6103 HasAngles, Angles, LinearVariation,
6104 HasRefPoint, RefPoint, MakeGroups)
6105 if MakeGroups: return gr,er
6108 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6109 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6110 MakeGroups=False, LinearVariation=False):
6112 Generate new elements by extrusion of faces which belong to the object.
6113 The path of extrusion must be a meshed edge.
6116 theObject: the object whose 2D elements should be processed.
6117 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6118 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6119 PathShape: shape (edge) defines the sub-mesh for the path
6120 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6121 HasAngles: not used obsolete
6122 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6123 around *basePoint*, additionally to previous steps.
6124 HasRefPoint: allows using the reference point
6125 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6126 The User can specify any point as the Reference Point.
6127 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6128 MakeGroups: forces the generation of new groups from existing ones
6129 LinearVariation: forces the computation of rotation angles as linear
6130 variation of the given Angles along path steps
6133 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6134 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6135 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6136 Example: :ref:`tui_extrusion_along_path`
6139 n,e,f = [],[],theObject
6140 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6141 HasAngles, Angles, LinearVariation,
6142 HasRefPoint, RefPoint, MakeGroups)
6143 if MakeGroups: return gr,er
6146 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6148 Create a symmetrical copy of mesh elements
6151 IDsOfElements: list of elements ids
6152 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6153 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6154 If the *Mirror* is a geom object this parameter is unnecessary
6155 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6156 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6159 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6162 if IDsOfElements == []:
6163 IDsOfElements = self.GetElementsId()
6164 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6165 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6166 theMirrorType = Mirror._mirrorType
6168 self.mesh.SetParameters(Mirror.parameters)
6169 if Copy and MakeGroups:
6170 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6171 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6174 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6176 Create a new mesh by a symmetrical copy of mesh elements
6179 IDsOfElements: the list of elements ids
6180 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6181 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6182 If the *Mirror* is a geom object this parameter is unnecessary
6183 MakeGroups: to generate new groups from existing ones
6184 NewMeshName: a name of the new mesh to create
6187 instance of class :class:`Mesh`
6190 if IDsOfElements == []:
6191 IDsOfElements = self.GetElementsId()
6192 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6193 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6194 theMirrorType = Mirror._mirrorType
6196 self.mesh.SetParameters(Mirror.parameters)
6197 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6198 MakeGroups, NewMeshName)
6199 return Mesh(self.smeshpyD,self.geompyD,mesh)
6201 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6203 Create a symmetrical copy of the object
6206 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6207 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6208 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6209 If the *Mirror* is a geom object this parameter is unnecessary
6210 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6211 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6214 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6217 if ( isinstance( theObject, Mesh )):
6218 theObject = theObject.GetMesh()
6219 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6220 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6221 theMirrorType = Mirror._mirrorType
6223 self.mesh.SetParameters(Mirror.parameters)
6224 if Copy and MakeGroups:
6225 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6226 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6229 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6231 Create a new mesh by a symmetrical copy of the object
6234 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6235 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6236 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6237 If the *Mirror* is a geom object this parameter is unnecessary
6238 MakeGroups: forces the generation of new groups from existing ones
6239 NewMeshName: the name of the new mesh to create
6242 instance of class :class:`Mesh`
6245 if ( isinstance( theObject, Mesh )):
6246 theObject = theObject.GetMesh()
6247 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6248 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6249 theMirrorType = Mirror._mirrorType
6251 self.mesh.SetParameters(Mirror.parameters)
6252 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6253 MakeGroups, NewMeshName)
6254 return Mesh( self.smeshpyD,self.geompyD,mesh )
6256 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6258 Translate the elements
6261 IDsOfElements: list of elements ids
6262 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6263 Copy: allows copying the translated elements
6264 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6267 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6270 if IDsOfElements == []:
6271 IDsOfElements = self.GetElementsId()
6272 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6273 Vector = self.smeshpyD.GetDirStruct(Vector)
6274 if isinstance( Vector, list ):
6275 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6276 self.mesh.SetParameters(Vector.PS.parameters)
6277 if Copy and MakeGroups:
6278 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6279 self.editor.Translate(IDsOfElements, Vector, Copy)
6282 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6284 Create a new mesh of translated elements
6287 IDsOfElements: list of elements ids
6288 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6289 MakeGroups: forces the generation of new groups from existing ones
6290 NewMeshName: the name of the newly created mesh
6293 instance of class :class:`Mesh`
6296 if IDsOfElements == []:
6297 IDsOfElements = self.GetElementsId()
6298 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6299 Vector = self.smeshpyD.GetDirStruct(Vector)
6300 if isinstance( Vector, list ):
6301 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6302 self.mesh.SetParameters(Vector.PS.parameters)
6303 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6304 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6306 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6308 Translate the object
6311 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6312 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6313 Copy: allows copying the translated elements
6314 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6317 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6320 if ( isinstance( theObject, Mesh )):
6321 theObject = theObject.GetMesh()
6322 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6323 Vector = self.smeshpyD.GetDirStruct(Vector)
6324 if isinstance( Vector, list ):
6325 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6326 self.mesh.SetParameters(Vector.PS.parameters)
6327 if Copy and MakeGroups:
6328 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6329 self.editor.TranslateObject(theObject, Vector, Copy)
6332 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6334 Create a new mesh from the translated object
6337 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6338 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6339 MakeGroups: forces the generation of new groups from existing ones
6340 NewMeshName: the name of the newly created mesh
6343 instance of class :class:`Mesh`
6346 if isinstance( theObject, Mesh ):
6347 theObject = theObject.GetMesh()
6348 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6349 Vector = self.smeshpyD.GetDirStruct(Vector)
6350 if isinstance( Vector, list ):
6351 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6352 self.mesh.SetParameters(Vector.PS.parameters)
6353 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6354 return Mesh( self.smeshpyD, self.geompyD, mesh )
6358 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6363 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6364 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6365 theScaleFact: list of 1-3 scale factors for axises
6366 Copy: allows copying the translated elements
6367 MakeGroups: forces the generation of new groups from existing
6371 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6372 empty list otherwise
6374 unRegister = genObjUnRegister()
6375 if ( isinstance( theObject, Mesh )):
6376 theObject = theObject.GetMesh()
6377 if ( isinstance( theObject, list )):
6378 theObject = self.GetIDSource(theObject, SMESH.ALL)
6379 unRegister.set( theObject )
6380 if ( isinstance( thePoint, list )):
6381 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6382 if ( isinstance( theScaleFact, float )):
6383 theScaleFact = [theScaleFact]
6384 if ( isinstance( theScaleFact, int )):
6385 theScaleFact = [ float(theScaleFact)]
6387 self.mesh.SetParameters(thePoint.parameters)
6389 if Copy and MakeGroups:
6390 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6391 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6394 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6396 Create a new mesh from the translated object
6399 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6400 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6401 theScaleFact: list of 1-3 scale factors for axises
6402 MakeGroups: forces the generation of new groups from existing ones
6403 NewMeshName: the name of the newly created mesh
6406 instance of class :class:`Mesh`
6408 unRegister = genObjUnRegister()
6409 if (isinstance(theObject, Mesh)):
6410 theObject = theObject.GetMesh()
6411 if ( isinstance( theObject, list )):
6412 theObject = self.GetIDSource(theObject,SMESH.ALL)
6413 unRegister.set( theObject )
6414 if ( isinstance( thePoint, list )):
6415 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6416 if ( isinstance( theScaleFact, float )):
6417 theScaleFact = [theScaleFact]
6418 if ( isinstance( theScaleFact, int )):
6419 theScaleFact = [ float(theScaleFact)]
6421 self.mesh.SetParameters(thePoint.parameters)
6422 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6423 MakeGroups, NewMeshName)
6424 return Mesh( self.smeshpyD, self.geompyD, mesh )
6428 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6433 IDsOfElements: list of elements ids
6434 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6435 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6436 Copy: allows copying the rotated elements
6437 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6440 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6444 if IDsOfElements == []:
6445 IDsOfElements = self.GetElementsId()
6446 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6447 Axis = self.smeshpyD.GetAxisStruct(Axis)
6448 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6449 Parameters = Axis.parameters + var_separator + Parameters
6450 self.mesh.SetParameters(Parameters)
6451 if Copy and MakeGroups:
6452 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6453 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6456 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6458 Create a new mesh of rotated elements
6461 IDsOfElements: list of element ids
6462 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6463 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6464 MakeGroups: forces the generation of new groups from existing ones
6465 NewMeshName: the name of the newly created mesh
6468 instance of class :class:`Mesh`
6471 if IDsOfElements == []:
6472 IDsOfElements = self.GetElementsId()
6473 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6474 Axis = self.smeshpyD.GetAxisStruct(Axis)
6475 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6476 Parameters = Axis.parameters + var_separator + Parameters
6477 self.mesh.SetParameters(Parameters)
6478 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6479 MakeGroups, NewMeshName)
6480 return Mesh( self.smeshpyD, self.geompyD, mesh )
6482 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6487 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6488 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6489 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6490 Copy: allows copying the rotated elements
6491 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6494 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6497 if (isinstance(theObject, Mesh)):
6498 theObject = theObject.GetMesh()
6499 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6500 Axis = self.smeshpyD.GetAxisStruct(Axis)
6501 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6502 Parameters = Axis.parameters + ":" + Parameters
6503 self.mesh.SetParameters(Parameters)
6504 if Copy and MakeGroups:
6505 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6506 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6509 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6511 Create a new mesh from the rotated object
6514 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6515 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6516 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6517 MakeGroups: forces the generation of new groups from existing ones
6518 NewMeshName: the name of the newly created mesh
6521 instance of class :class:`Mesh`
6524 if (isinstance( theObject, Mesh )):
6525 theObject = theObject.GetMesh()
6526 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6527 Axis = self.smeshpyD.GetAxisStruct(Axis)
6528 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6529 Parameters = Axis.parameters + ":" + Parameters
6530 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6531 MakeGroups, NewMeshName)
6532 self.mesh.SetParameters(Parameters)
6533 return Mesh( self.smeshpyD, self.geompyD, mesh )
6535 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6537 Create an offset mesh from the given 2D object
6540 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6541 theValue (float): signed offset size
6542 MakeGroups (boolean): forces the generation of new groups from existing ones
6543 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6544 False means to remove original elements.
6545 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6548 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6551 if isinstance( theObject, Mesh ):
6552 theObject = theObject.GetMesh()
6553 theValue,Parameters,hasVars = ParseParameters(Value)
6554 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6555 self.mesh.SetParameters(Parameters)
6557 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6560 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6562 Find groups of adjacent nodes within Tolerance.
6565 Tolerance (float): the value of tolerance
6566 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6567 corner and medium nodes in separate groups thus preventing
6568 their further merge.
6571 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6574 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6576 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6577 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6579 Find groups of adjacent nodes within Tolerance.
6582 Tolerance: the value of tolerance
6583 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6584 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6585 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6586 corner and medium nodes in separate groups thus preventing
6587 their further merge.
6590 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6593 unRegister = genObjUnRegister()
6594 if not isinstance( SubMeshOrGroup, list ):
6595 SubMeshOrGroup = [ SubMeshOrGroup ]
6596 for i,obj in enumerate( SubMeshOrGroup ):
6597 if isinstance( obj, Mesh ):
6598 SubMeshOrGroup = [ obj.GetMesh() ]
6600 if isinstance( obj, int ):
6601 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6602 unRegister.set( SubMeshOrGroup )
6605 if not isinstance( exceptNodes, list ):
6606 exceptNodes = [ exceptNodes ]
6607 if exceptNodes and isinstance( exceptNodes[0], int ):
6608 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6609 unRegister.set( exceptNodes )
6611 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6612 exceptNodes, SeparateCornerAndMediumNodes)
6614 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6619 GroupsOfNodes: a list of groups of nodes IDs for merging.
6620 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6621 in all elements and mesh groups by nodes 1 and 25 correspondingly
6622 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6623 If *NodesToKeep* does not include a node to keep for some group to merge,
6624 then the first node in the group is kept.
6625 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6629 This operation can create gaps in numeration of nodes or elements.
6630 Call :meth:`RenumberElements` to remove the gaps.
6632 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6634 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6636 Find the elements built on the same nodes.
6639 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6640 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6644 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6647 unRegister = genObjUnRegister()
6648 if MeshOrSubMeshOrGroup is None:
6649 MeshOrSubMeshOrGroup = [ self.mesh ]
6650 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6651 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6652 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6653 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6654 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6655 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6656 unRegister.set( MeshOrSubMeshOrGroup )
6657 for item in MeshOrSubMeshOrGroup:
6658 if isinstance( item, Mesh ):
6659 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6661 if not isinstance( exceptElements, list ):
6662 exceptElements = [ exceptElements ]
6663 if exceptElements and isinstance( exceptElements[0], int ):
6664 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6665 unRegister.set( exceptElements )
6667 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6669 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6671 Merge elements in each given group.
6674 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6675 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6676 replaced in all mesh groups by elements 1 and 25)
6677 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6678 If *ElementsToKeep* does not include an element to keep for some group to merge,
6679 then the first element in the group is kept.
6682 This operation can create gaps in numeration of elements.
6683 Call :meth:`RenumberElements` to remove the gaps.
6686 unRegister = genObjUnRegister()
6688 if not isinstance( ElementsToKeep, list ):
6689 ElementsToKeep = [ ElementsToKeep ]
6690 if isinstance( ElementsToKeep[0], int ):
6691 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6692 unRegister.set( ElementsToKeep )
6694 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6696 def MergeEqualElements(self):
6698 Leave one element and remove all other elements built on the same nodes.
6701 This operation can create gaps in numeration of elements.
6702 Call :meth:`RenumberElements` to remove the gaps.
6705 self.editor.MergeEqualElements()
6707 def FindFreeBorders(self, ClosedOnly=True):
6709 Returns all or only closed free borders
6712 list of SMESH.FreeBorder's
6715 return self.editor.FindFreeBorders( ClosedOnly )
6717 def FillHole(self, holeNodes, groupName=""):
6719 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6722 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6723 must describe all sequential nodes of the hole border. The first and the last
6724 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6725 groupName (string): name of a group to add new faces
6727 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6731 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6732 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6733 if not isinstance( holeNodes, SMESH.FreeBorder ):
6734 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6735 return self.editor.FillHole( holeNodes, groupName )
6737 def FindCoincidentFreeBorders (self, tolerance=0.):
6739 Return groups of FreeBorder's coincident within the given tolerance.
6742 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6743 size of elements adjacent to free borders being compared is used.
6746 SMESH.CoincidentFreeBorders structure
6749 return self.editor.FindCoincidentFreeBorders( tolerance )
6751 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6753 Sew FreeBorder's of each group
6756 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6757 where each enclosed list contains node IDs of a group of coincident free
6758 borders such that each consequent triple of IDs within a group describes
6759 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6760 last node of a border.
6761 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6762 groups of coincident free borders, each group including two borders.
6763 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6764 polygons if a node of opposite border falls on a face edge, else such
6765 faces are split into several ones.
6766 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6767 polyhedra if a node of opposite border falls on a volume edge, else such
6768 volumes, if any, remain intact and the mesh becomes non-conformal.
6771 a number of successfully sewed groups
6774 This operation can create gaps in numeration of nodes or elements.
6775 Call :meth:`RenumberElements` to remove the gaps.
6778 if freeBorders and isinstance( freeBorders, list ):
6779 # construct SMESH.CoincidentFreeBorders
6780 if isinstance( freeBorders[0], int ):
6781 freeBorders = [freeBorders]
6783 coincidentGroups = []
6784 for nodeList in freeBorders:
6785 if not nodeList or len( nodeList ) % 3:
6786 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6789 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6790 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6791 nodeList = nodeList[3:]
6793 coincidentGroups.append( group )
6795 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6797 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6799 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6800 FirstNodeID2, SecondNodeID2, LastNodeID2,
6801 CreatePolygons, CreatePolyedrs):
6806 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6809 This operation can create gaps in numeration of nodes or elements.
6810 Call :meth:`RenumberElements` to remove the gaps.
6813 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6814 FirstNodeID2, SecondNodeID2, LastNodeID2,
6815 CreatePolygons, CreatePolyedrs)
6817 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6818 FirstNodeID2, SecondNodeID2):
6820 Sew conform free borders
6823 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6826 This operation can create gaps in numeration of elements.
6827 Call :meth:`RenumberElements` to remove the gaps.
6830 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6831 FirstNodeID2, SecondNodeID2)
6833 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6834 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6839 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6842 This operation can create gaps in numeration of elements.
6843 Call :meth:`RenumberElements` to remove the gaps.
6846 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6847 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6849 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6850 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6851 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6853 Sew two sides of a mesh. The nodes belonging to Side1 are
6854 merged with the nodes of elements of Side2.
6855 The number of elements in theSide1 and in theSide2 must be
6856 equal and they should have similar nodal connectivity.
6857 The nodes to merge should belong to side borders and
6858 the first node should be linked to the second.
6861 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6864 This operation can create gaps in numeration of nodes.
6865 Call :meth:`RenumberElements` to remove the gaps.
6868 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6869 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6870 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6872 def ChangeElemNodes(self, ide, newIDs):
6874 Set new nodes for the given element. Number of nodes should be kept.
6881 False if the number of nodes does not correspond to the type of element
6884 return self.editor.ChangeElemNodes(ide, newIDs)
6886 def GetLastCreatedNodes(self):
6888 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6889 created, this method return the list of their IDs.
6890 If new nodes were not created - return empty list
6893 the list of integer values (can be empty)
6896 return self.editor.GetLastCreatedNodes()
6898 def GetLastCreatedElems(self):
6900 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6901 created this method return the list of their IDs.
6902 If new elements were not created - return empty list
6905 the list of integer values (can be empty)
6908 return self.editor.GetLastCreatedElems()
6910 def ClearLastCreated(self):
6912 Forget what nodes and elements were created by the last mesh edition operation
6915 self.editor.ClearLastCreated()
6917 def DoubleElements(self, theElements, theGroupName=""):
6919 Create duplicates of given elements, i.e. create new elements based on the
6920 same nodes as the given ones.
6923 theElements: container of elements to duplicate. It can be a
6924 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6925 or a list of element IDs. If *theElements* is
6926 a :class:`Mesh`, elements of highest dimension are duplicated
6927 theGroupName: a name of group to contain the generated elements.
6928 If a group with such a name already exists, the new elements
6929 are added to the existing group, else a new group is created.
6930 If *theGroupName* is empty, new elements are not added
6934 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6935 None if *theGroupName* == "".
6938 unRegister = genObjUnRegister()
6939 if isinstance( theElements, Mesh ):
6940 theElements = theElements.mesh
6941 elif isinstance( theElements, list ):
6942 theElements = self.GetIDSource( theElements, SMESH.ALL )
6943 unRegister.set( theElements )
6944 return self.editor.DoubleElements(theElements, theGroupName)
6946 def DoubleNodes(self, theNodes, theModifiedElems):
6948 Create a hole in a mesh by doubling the nodes of some particular elements
6951 theNodes: IDs of nodes to be doubled
6952 theModifiedElems: IDs of elements to be updated by the new (doubled)
6953 nodes. If list of element identifiers is empty then nodes are doubled but
6954 they not assigned to elements
6957 True if operation has been completed successfully, False otherwise
6960 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6962 def DoubleNode(self, theNodeId, theModifiedElems):
6964 Create a hole in a mesh by doubling the nodes of some particular elements.
6965 This method provided for convenience works as :meth:`DoubleNodes`.
6968 theNodeId: IDs of node to double
6969 theModifiedElems: IDs of elements to update
6972 True if operation has been completed successfully, False otherwise
6975 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6977 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6979 Create a hole in a mesh by doubling the nodes of some particular elements.
6980 This method provided for convenience works as :meth:`DoubleNodes`.
6983 theNodes: group of nodes to double.
6984 theModifiedElems: group of elements to update.
6985 theMakeGroup: forces the generation of a group containing new nodes.
6988 True or a created group if operation has been completed successfully,
6989 False or None otherwise
6993 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6994 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6996 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6998 Create a hole in a mesh by doubling the nodes of some particular elements.
6999 This method provided for convenience works as :meth:`DoubleNodes`.
7002 theNodes: list of groups of nodes to double.
7003 theModifiedElems: list of groups of elements to update.
7004 theMakeGroup: forces the generation of a group containing new nodes.
7007 True if operation has been completed successfully, False otherwise
7011 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
7012 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
7014 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
7016 Create a hole in a mesh by doubling the nodes of some particular elements
7019 theElems: the list of elements (edges or faces) to replicate.
7020 The nodes for duplication could be found from these elements
7021 theNodesNot: list of nodes NOT to replicate
7022 theAffectedElems: the list of elements (cells and edges) to which the
7023 replicated nodes should be associated to
7026 True if operation has been completed successfully, False otherwise
7029 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
7031 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
7033 Create a hole in a mesh by doubling the nodes of some particular elements
7036 theElems: the list of elements (edges or faces) to replicate.
7037 The nodes for duplication could be found from these elements
7038 theNodesNot: list of nodes NOT to replicate
7039 theShape: shape to detect affected elements (element which geometric center
7040 located on or inside shape).
7041 The replicated nodes should be associated to affected elements.
7044 True if operation has been completed successfully, False otherwise
7047 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
7049 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
7050 theMakeGroup=False, theMakeNodeGroup=False):
7052 Create a hole in a mesh by doubling the nodes of some particular elements.
7053 This method provided for convenience works as :meth:`DoubleNodes`.
7056 theElems: group of of elements (edges or faces) to replicate.
7057 theNodesNot: group of nodes NOT to replicate.
7058 theAffectedElems: group of elements to which the replicated nodes
7059 should be associated to.
7060 theMakeGroup: forces the generation of a group containing new elements.
7061 theMakeNodeGroup: forces the generation of a group containing new nodes.
7064 True or created groups (one or two) if operation has been completed successfully,
7065 False or None otherwise
7068 if theMakeGroup or theMakeNodeGroup:
7069 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
7071 theMakeGroup, theMakeNodeGroup)
7072 if theMakeGroup and theMakeNodeGroup:
7075 return twoGroups[ int(theMakeNodeGroup) ]
7076 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7078 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7080 Create a hole in a mesh by doubling the nodes of some particular elements.
7081 This method provided for convenience works as :meth:`DoubleNodes`.
7084 theElems: group of of elements (edges or faces) to replicate
7085 theNodesNot: group of nodes not to replicate
7086 theShape: shape to detect affected elements (element which geometric center
7087 located on or inside shape).
7088 The replicated nodes should be associated to affected elements
7091 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7093 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7094 theMakeGroup=False, theMakeNodeGroup=False):
7096 Create a hole in a mesh by doubling the nodes of some particular elements.
7097 This method provided for convenience works as :meth:`DoubleNodes`.
7100 theElems: list of groups of elements (edges or faces) to replicate
7101 theNodesNot: list of groups of nodes NOT to replicate
7102 theAffectedElems: group of elements to which the replicated nodes
7103 should be associated to
7104 theMakeGroup: forces generation of a group containing new elements.
7105 theMakeNodeGroup: forces generation of a group containing new nodes
7108 True or created groups (one or two) if operation has been completed successfully,
7109 False or None otherwise
7112 if theMakeGroup or theMakeNodeGroup:
7113 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7115 theMakeGroup, theMakeNodeGroup)
7116 if theMakeGroup and theMakeNodeGroup:
7119 return twoGroups[ int(theMakeNodeGroup) ]
7120 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7122 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7124 Create a hole in a mesh by doubling the nodes of some particular elements.
7125 This method provided for convenience works as :meth:`DoubleNodes`.
7128 theElems: list of groups of elements (edges or faces) to replicate
7129 theNodesNot: list of groups of nodes NOT to replicate
7130 theShape: shape to detect affected elements (element which geometric center
7131 located on or inside shape).
7132 The replicated nodes should be associated to affected elements
7135 True if operation has been completed successfully, False otherwise
7138 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7140 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7142 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7143 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7146 theElems: list of groups of nodes or elements (edges or faces) to replicate
7147 theNodesNot: list of groups of nodes NOT to replicate
7148 theShape: shape to detect affected elements (element which geometric center
7149 located on or inside shape).
7150 The replicated nodes should be associated to affected elements
7153 groups of affected elements in order: volumes, faces, edges
7156 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7158 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7161 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7162 The list of groups must describe a partition of the mesh volumes.
7163 The nodes of the internal faces at the boundaries of the groups are doubled.
7164 In option, the internal faces are replaced by flat elements.
7165 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7168 theDomains: list of groups of volumes
7169 createJointElems: if True, create the elements
7170 onAllBoundaries: if True, the nodes and elements are also created on
7171 the boundary between *theDomains* and the rest mesh
7174 True if operation has been completed successfully, False otherwise
7177 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7179 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7181 Double nodes on some external faces and create flat elements.
7182 Flat elements are mainly used by some types of mechanic calculations.
7184 Each group of the list must be constituted of faces.
7185 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7188 theGroupsOfFaces: list of groups of faces
7191 True if operation has been completed successfully, False otherwise
7194 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7196 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7198 Identify all the elements around a geom shape, get the faces delimiting the hole
7200 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7202 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7204 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7205 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7206 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7207 If there are several paths connecting a pair of points, the shortest path is
7208 selected by the module. Position of the cutting plane is defined by the two
7209 points and an optional vector lying on the plane specified by a PolySegment.
7210 By default the vector is defined by Mesh module as following. A middle point
7211 of the two given points is computed. The middle point is projected to the mesh.
7212 The vector goes from the middle point to the projection point. In case of planar
7213 mesh, the vector is normal to the mesh.
7215 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7218 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7219 groupName: optional name of a group where created mesh segments will be added.
7222 editor = self.editor
7224 editor = self.mesh.GetMeshEditPreviewer()
7225 segmentsRes = editor.MakePolyLine( segments, groupName )
7226 for i, seg in enumerate( segmentsRes ):
7227 segments[i].vector = seg.vector
7229 return editor.GetPreviewData()
7232 def MakeSlot(self, segmentGroup, width ):
7234 Create a slot of given width around given 1D elements lying on a triangle mesh.
7235 The slot is constructed by cutting faces by cylindrical surfaces made
7236 around each segment. Segments are expected to be created by MakePolyLine().
7239 FaceEdge's located at the slot boundary
7241 return self.editor.MakeSlot( segmentGroup, width )
7243 def GetFunctor(self, funcType ):
7245 Return a cached numerical functor by its type.
7248 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7249 Note that not all items correspond to numerical functors.
7252 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7255 fn = self.functors[ funcType._v ]
7257 fn = self.smeshpyD.GetFunctor(funcType)
7258 fn.SetMesh(self.mesh)
7259 self.functors[ funcType._v ] = fn
7262 def FunctorValue(self, funcType, elemId, isElem=True):
7264 Return value of a functor for a given element
7267 funcType: an item of :class:`SMESH.FunctorType` enum.
7268 elemId: element or node ID
7269 isElem: *elemId* is ID of element or node
7272 the functor value or zero in case of invalid arguments
7275 fn = self.GetFunctor( funcType )
7276 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7277 val = fn.GetValue(elemId)
7282 def GetLength(self, elemId=None):
7284 Get length of given 1D elements or of all 1D mesh elements
7287 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.
7290 Sum of lengths of given elements
7295 length = self.smeshpyD.GetLength(self)
7296 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7297 length = self.smeshpyD.GetLength(elemId)
7300 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7302 length += self.smeshpyD.GetLength(obj)
7303 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7304 unRegister = genObjUnRegister()
7305 obj = self.GetIDSource( elemId )
7306 unRegister.set( obj )
7307 length = self.smeshpyD.GetLength( obj )
7309 length = self.FunctorValue(SMESH.FT_Length, elemId)
7312 def GetArea(self, elemId=None):
7314 Get area of given 2D elements or of all 2D mesh elements
7317 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.
7320 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7325 area = self.smeshpyD.GetArea(self)
7326 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7327 area = self.smeshpyD.GetArea(elemId)
7330 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7332 area += self.smeshpyD.GetArea(obj)
7333 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7334 unRegister = genObjUnRegister()
7335 obj = self.GetIDSource( elemId )
7336 unRegister.set( obj )
7337 area = self.smeshpyD.GetArea( obj )
7339 area = self.FunctorValue(SMESH.FT_Area, elemId)
7342 def GetVolume(self, elemId=None):
7344 Get volume of given 3D elements or of all 3D mesh elements
7347 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.
7350 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7355 volume= self.smeshpyD.GetVolume(self)
7356 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7357 volume= self.smeshpyD.GetVolume(elemId)
7360 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7362 volume+= self.smeshpyD.GetVolume(obj)
7363 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7364 unRegister = genObjUnRegister()
7365 obj = self.GetIDSource( elemId )
7366 unRegister.set( obj )
7367 volume= self.smeshpyD.GetVolume( obj )
7369 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7372 def GetAngle(self, node1, node2, node3 ):
7374 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7377 node1,node2,node3: IDs of the three nodes
7380 Angle in radians [0,PI]. -1 if failure case.
7382 p1 = self.GetNodeXYZ( node1 )
7383 p2 = self.GetNodeXYZ( node2 )
7384 p3 = self.GetNodeXYZ( node3 )
7385 if p1 and p2 and p3:
7386 return self.smeshpyD.GetAngle( p1,p2,p3 )
7390 def GetMaxElementLength(self, elemId):
7392 Get maximum element length.
7395 elemId: mesh element ID
7398 element's maximum length value
7401 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7402 ftype = SMESH.FT_MaxElementLength3D
7404 ftype = SMESH.FT_MaxElementLength2D
7405 return self.FunctorValue(ftype, elemId)
7407 def GetAspectRatio(self, elemId):
7409 Get aspect ratio of 2D or 3D element.
7412 elemId: mesh element ID
7415 element's aspect ratio value
7418 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7419 ftype = SMESH.FT_AspectRatio3D
7421 ftype = SMESH.FT_AspectRatio
7422 return self.FunctorValue(ftype, elemId)
7424 def GetWarping(self, elemId):
7426 Get warping angle of 2D element.
7429 elemId: mesh element ID
7432 element's warping angle value
7435 return self.FunctorValue(SMESH.FT_Warping, elemId)
7437 def GetMinimumAngle(self, elemId):
7439 Get minimum angle of 2D element.
7442 elemId: mesh element ID
7445 element's minimum angle value
7448 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7450 def GetTaper(self, elemId):
7452 Get taper of 2D element.
7455 elemId: mesh element ID
7458 element's taper value
7461 return self.FunctorValue(SMESH.FT_Taper, elemId)
7463 def GetSkew(self, elemId):
7465 Get skew of 2D element.
7468 elemId: mesh element ID
7471 element's skew value
7474 return self.FunctorValue(SMESH.FT_Skew, elemId)
7476 def GetMinMax(self, funType, meshPart=None):
7478 Return minimal and maximal value of a given functor.
7481 funType (SMESH.FunctorType): a functor type.
7482 Note that not all items of :class:`SMESH.FunctorType` corresponds
7483 to numerical functors.
7484 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7490 unRegister = genObjUnRegister()
7491 if isinstance( meshPart, list ):
7492 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7493 unRegister.set( meshPart )
7494 if isinstance( meshPart, Mesh ):
7495 meshPart = meshPart.mesh
7496 fun = self.GetFunctor( funType )
7499 if hasattr( meshPart, "SetMesh" ):
7500 meshPart.SetMesh( self.mesh ) # set mesh to filter
7501 hist = fun.GetLocalHistogram( 1, False, meshPart )
7503 hist = fun.GetHistogram( 1, False )
7505 return hist[0].min, hist[0].max
7508 pass # end of Mesh class
7511 class meshProxy(SMESH._objref_SMESH_Mesh):
7513 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7514 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7516 def __init__(self,*args):
7517 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7518 def __deepcopy__(self, memo=None):
7519 new = self.__class__(self)
7521 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7522 if len( args ) == 3:
7523 args += SMESH.ALL_NODES, True
7524 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7525 def ExportToMEDX(self, *args): # function removed
7526 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7527 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7528 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7529 def ExportToMED(self, *args): # function removed
7530 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7531 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7533 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7535 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7536 def ExportPartToMED(self, *args): # 'version' parameter removed
7537 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7538 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7539 def ExportMED(self, *args): # signature of method changed
7540 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7542 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7544 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7545 def ExportUNV(self, *args): # renumber arg added
7546 if len( args ) == 1:
7548 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
7549 def ExportDAT(self, *args): # renumber arg added
7550 if len( args ) == 1:
7552 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
7554 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7557 class submeshProxy(SMESH._objref_SMESH_subMesh):
7560 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7562 def __init__(self,*args):
7563 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7565 def __deepcopy__(self, memo=None):
7566 new = self.__class__(self)
7569 def Compute(self,refresh=False):
7571 Compute the sub-mesh and return the status of the computation
7574 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7579 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7580 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7584 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7586 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7588 if salome.sg.hasDesktop():
7589 if refresh: salome.sg.updateObjBrowser()
7594 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7597 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7599 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7600 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7603 def __init__(self,*args):
7604 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7606 def __getattr__(self, name ): # method called if an attribute not found
7607 if not self.mesh: # look for name() method in Mesh class
7608 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7609 if hasattr( self.mesh, name ):
7610 return getattr( self.mesh, name )
7611 if name == "ExtrusionAlongPathObjX":
7612 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7613 print("meshEditor: attribute '%s' NOT FOUND" % name)
7615 def __deepcopy__(self, memo=None):
7616 new = self.__class__(self)
7618 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7619 if len( args ) == 1: args += False,
7620 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7621 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7622 if len( args ) == 2: args += False,
7623 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7624 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7625 if len( args ) == 1:
7626 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7627 NodesToKeep = args[1]
7628 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7629 unRegister = genObjUnRegister()
7631 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7632 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7633 if not isinstance( NodesToKeep, list ):
7634 NodesToKeep = [ NodesToKeep ]
7635 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7637 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7639 class Pattern(SMESH._objref_SMESH_Pattern):
7641 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7642 variables in some methods
7645 def LoadFromFile(self, patternTextOrFile ):
7646 text = patternTextOrFile
7647 if os.path.exists( text ):
7648 text = open( patternTextOrFile ).read()
7650 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7652 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7653 decrFun = lambda i: i-1
7654 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7655 theMesh.SetParameters(Parameters)
7656 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7658 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7659 decrFun = lambda i: i-1
7660 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7661 theMesh.SetParameters(Parameters)
7662 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7664 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7665 if isinstance( mesh, Mesh ):
7666 mesh = mesh.GetMesh()
7667 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7669 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7671 Registering the new proxy for Pattern
7676 Private class used to bind methods creating algorithms to the class Mesh
7679 def __init__(self, method):
7681 self.defaultAlgoType = ""
7682 self.algoTypeToClass = {}
7683 self.method = method
7685 def add(self, algoClass):
7687 Store a python class of algorithm
7689 if inspect.isclass(algoClass) and \
7690 hasattr( algoClass, "algoType"):
7691 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7692 if not self.defaultAlgoType and \
7693 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7694 self.defaultAlgoType = algoClass.algoType
7695 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7697 def copy(self, mesh):
7699 Create a copy of self and assign mesh to the copy
7702 other = algoCreator( self.method )
7703 other.defaultAlgoType = self.defaultAlgoType
7704 other.algoTypeToClass = self.algoTypeToClass
7708 def __call__(self,algo="",geom=0,*args):
7710 Create an instance of algorithm
7714 if isinstance( algo, str ):
7716 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7717 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7722 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7724 elif not algoType and isinstance( geom, str ):
7729 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7731 elif isinstance( arg, str ) and not algoType:
7734 import traceback, sys
7735 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7736 sys.stderr.write( msg + '\n' )
7737 tb = traceback.extract_stack(None,2)
7738 traceback.print_list( [tb[0]] )
7740 algoType = self.defaultAlgoType
7741 if not algoType and self.algoTypeToClass:
7742 algoType = sorted( self.algoTypeToClass.keys() )[0]
7743 if algoType in self.algoTypeToClass:
7744 #print("Create algo",algoType)
7745 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7746 raise RuntimeError( "No class found for algo type %s" % algoType)
7749 class hypMethodWrapper:
7751 Private class used to substitute and store variable parameters of hypotheses.
7754 def __init__(self, hyp, method):
7756 self.method = method
7757 #print("REBIND:", method.__name__)
7760 def __call__(self,*args):
7762 call a method of hypothesis with calling SetVarParameter() before
7766 return self.method( self.hyp, *args ) # hypothesis method with no args
7768 #print("MethWrapper.__call__", self.method.__name__, args)
7770 parsed = ParseParameters(*args) # replace variables with their values
7771 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7772 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7773 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7774 # maybe there is a replaced string arg which is not variable
7775 result = self.method( self.hyp, *args )
7776 except ValueError as detail: # raised by ParseParameters()
7778 result = self.method( self.hyp, *args )
7779 except omniORB.CORBA.BAD_PARAM:
7780 raise ValueError(detail) # wrong variable name
7785 class genObjUnRegister:
7787 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7790 def __init__(self, genObj=None):
7791 self.genObjList = []
7795 def set(self, genObj):
7796 "Store one or a list of of SALOME.GenericObj'es"
7797 if isinstance( genObj, list ):
7798 self.genObjList.extend( genObj )
7800 self.genObjList.append( genObj )
7804 for genObj in self.genObjList:
7805 if genObj and hasattr( genObj, "UnRegister" ):
7808 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7810 Bind methods creating mesher plug-ins to the Mesh class
7813 # print("pluginName: ", pluginName)
7814 pluginBuilderName = pluginName + "Builder"
7816 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7817 except Exception as e:
7818 from salome_utils import verbose
7819 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7821 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7822 plugin = eval( pluginBuilderName )
7823 # print(" plugin:" , str(plugin))
7825 # add methods creating algorithms to Mesh
7826 for k in dir( plugin ):
7827 if k[0] == '_': continue
7828 algo = getattr( plugin, k )
7829 #print(" algo:", str(algo))
7830 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7831 #print(" meshMethod:" , str(algo.meshMethod))
7832 if not hasattr( Mesh, algo.meshMethod ):
7833 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7835 _mmethod = getattr( Mesh, algo.meshMethod )
7836 if hasattr( _mmethod, "add" ):