1 # Copyright (C) 2007-2020 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
49 # In case the omniORBpy EnumItem class does not fully support Python 3
50 # (for instance in version 4.2.1-2), the comparison ordering methods must be
54 SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
56 def enumitem_eq(self, other):
58 if isinstance(other, omniORB.EnumItem):
59 if other._parent_id == self._parent_id:
60 return self._v == other._v
62 return self._parent_id == other._parent_id
64 return id(self) == id(other)
66 return id(self) == id(other)
68 def enumitem_lt(self, other):
70 if isinstance(other, omniORB.EnumItem):
71 if other._parent_id == self._parent_id:
72 return self._v < other._v
74 return self._parent_id < other._parent_id
76 return id(self) < id(other)
78 return id(self) < id(other)
80 def enumitem_le(self, other):
82 if isinstance(other, omniORB.EnumItem):
83 if other._parent_id == self._parent_id:
84 return self._v <= other._v
86 return self._parent_id <= other._parent_id
88 return id(self) <= id(other)
90 return id(self) <= id(other)
92 def enumitem_gt(self, other):
94 if isinstance(other, omniORB.EnumItem):
95 if other._parent_id == self._parent_id:
96 return self._v > other._v
98 return self._parent_id > other._parent_id
100 return id(self) > id(other)
102 return id(self) > id(other)
104 def enumitem_ge(self, other):
106 if isinstance(other, omniORB.EnumItem):
107 if other._parent_id == self._parent_id:
108 return self._v >= other._v
110 return self._parent_id >= other._parent_id
112 return id(self) >= id(other)
114 return id(self) >= id(other)
116 omniORB.EnumItem.__eq__ = enumitem_eq
117 omniORB.EnumItem.__lt__ = enumitem_lt
118 omniORB.EnumItem.__le__ = enumitem_le
119 omniORB.EnumItem.__gt__ = enumitem_gt
120 omniORB.EnumItem.__ge__ = enumitem_ge
123 class MeshMeta(type):
124 """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
126 def __instancecheck__(cls, inst):
127 """Implement isinstance(inst, cls)."""
128 return any(cls.__subclasscheck__(c)
129 for c in {type(inst), inst.__class__})
131 def __subclasscheck__(cls, sub):
132 """Implement issubclass(sub, cls)."""
133 return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
135 def DegreesToRadians(AngleInDegrees):
136 """Convert an angle from degrees to radians
139 return AngleInDegrees * pi / 180.0
141 import salome_notebook
142 notebook = salome_notebook.notebook
143 # Salome notebook variable separator
146 def ParseParameters(*args):
148 Return list of variable values from salome notebook.
149 The last argument, if is callable, is used to modify values got from notebook
155 if args and callable(args[-1]):
156 args, varModifFun = args[:-1], args[-1]
157 for parameter in args:
159 Parameters += str(parameter) + var_separator
161 if isinstance(parameter,str):
162 # check if there is an inexistent variable name
163 if not notebook.isVariable(parameter):
164 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
165 parameter = notebook.get(parameter)
168 parameter = varModifFun(parameter)
171 Result.append(parameter)
174 Parameters = Parameters[:-1]
175 Result.append( Parameters )
176 Result.append( hasVariables )
179 def ParseAngles(*args):
181 Parse parameters while converting variables to radians
183 return ParseParameters( *( args + (DegreesToRadians, )))
185 def __initPointStruct(point,*args):
187 Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
188 Parameters are stored in PointStruct.parameters attribute
190 point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
192 SMESH.PointStruct.__init__ = __initPointStruct
194 def __initAxisStruct(ax,*args):
196 Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
197 Parameters are stored in AxisStruct.parameters attribute
200 raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
201 ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
203 SMESH.AxisStruct.__init__ = __initAxisStruct
205 smeshPrecisionConfusion = 1.e-07
206 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
207 """Compare real values using smeshPrecisionConfusion as tolerance
209 if abs(val1 - val2) < tol:
217 Return a name of an object
224 if isinstance(obj, SALOMEDS._objref_SObject):
228 ior = salome.orb.object_to_string(obj)
232 sobj = salome.myStudy.FindObjectIOR(ior)
234 return sobj.GetName()
235 if hasattr(obj, "GetName"):
236 # unknown CORBA object, having GetName() method
239 # unknown CORBA object, no GetName() method
242 if hasattr(obj, "GetName"):
243 # unknown non-CORBA object, having GetName() method
246 raise RuntimeError("Null or invalid object")
248 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
250 Print error message if a hypothesis was not assigned.
253 hypType = "algorithm"
255 hypType = "hypothesis"
258 if hasattr( status, "__getitem__" ):
259 status, reason = status[0], status[1]
260 if status == HYP_UNKNOWN_FATAL:
261 reason = "for unknown reason"
262 elif status == HYP_INCOMPATIBLE:
263 reason = "this hypothesis mismatches the algorithm"
264 elif status == HYP_NOTCONFORM:
265 reason = "a non-conform mesh would be built"
266 elif status == HYP_ALREADY_EXIST:
267 if isAlgo: return # it does not influence anything
268 reason = hypType + " of the same dimension is already assigned to this shape"
269 elif status == HYP_BAD_DIM:
270 reason = hypType + " mismatches the shape"
271 elif status == HYP_CONCURRENT :
272 reason = "there are concurrent hypotheses on sub-shapes"
273 elif status == HYP_BAD_SUBSHAPE:
274 reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
275 elif status == HYP_BAD_GEOMETRY:
276 reason = "the algorithm is not applicable to this geometry"
277 elif status == HYP_HIDDEN_ALGO:
278 reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
279 elif status == HYP_HIDING_ALGO:
280 reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
281 elif status == HYP_NEED_SHAPE:
282 reason = "algorithm can't work without shape"
283 elif status == HYP_INCOMPAT_HYPS:
289 where = '"%s"' % geomName
291 meshName = GetName( mesh )
292 if meshName and meshName != NO_NAME:
293 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
294 if status < HYP_UNKNOWN_FATAL and where:
295 print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
297 print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
299 print('"%s" was not assigned : %s' %( hypName, reason ))
302 def AssureGeomPublished(mesh, geom, name=''):
304 Private method. Add geom (sub-shape of the main shape) into the study if not yet there
306 if not mesh.smeshpyD.IsEnablePublish():
308 if not hasattr( geom, "GetShapeType" ):
310 if not geom.GetStudyEntry():
312 if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
313 # for all groups SubShapeName() return "Compound_-1"
314 name = mesh.geompyD.SubShapeName(geom, mesh.geom)
316 name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
318 mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
321 # def FirstVertexOnCurve(mesh, edge):
324 # the first vertex of a geometrical edge by ignoring orientation
326 # return mesh.geompyD.GetVertexByIndex( edge, 0, False )
332 smeshInst is a singleton
338 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
340 This class allows to create, load or manipulate meshes.
341 It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
342 It also has methods to get infos and measure meshes.
345 # MirrorType enumeration
346 POINT = SMESH_MeshEditor.POINT
347 AXIS = SMESH_MeshEditor.AXIS
348 PLANE = SMESH_MeshEditor.PLANE
350 # Smooth_Method enumeration
351 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
352 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
354 PrecisionConfusion = smeshPrecisionConfusion
356 # TopAbs_State enumeration
357 [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
359 # Methods of splitting a hexahedron into tetrahedra
360 Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
362 def __new__(cls, *args):
366 #print("==== __new__", engine, smeshInst, doLcc)
368 if smeshInst is None:
369 # smesh engine is either retrieved from engine, or created
371 # Following test avoids a recursive loop
373 if smeshInst is not None:
374 # smesh engine not created: existing engine found
378 # FindOrLoadComponent called:
379 # 1. CORBA resolution of server
380 # 2. the __new__ method is called again
381 #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
382 smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
384 # FindOrLoadComponent not called
385 if smeshInst is None:
386 # smeshBuilder instance is created from lcc.FindOrLoadComponent
387 #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
388 smeshInst = super(smeshBuilder,cls).__new__(cls)
390 # smesh engine not created: existing engine found
391 #print("==== existing ", engine, smeshInst, doLcc)
393 #print("====1 ", smeshInst)
396 #print("====2 ", smeshInst)
399 def __init__(self, *args):
401 #print("--------------- smeshbuilder __init__ ---", created)
404 SMESH._objref_SMESH_Gen.__init__(self, *args)
407 def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
409 Dump component to the Python script.
410 This method overrides IDL function to allow default values for the parameters.
413 return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
415 def SetDumpPythonHistorical(self, isHistorical):
417 Set mode of DumpPython(), *historical* or *snapshot*.
418 In the *historical* mode, the Python Dump script includes all commands
419 performed by SMESH engine. In the *snapshot* mode, commands
420 relating to objects removed from the Study are excluded from the script
421 as well as commands not influencing the current state of meshes
424 if isHistorical: val = "true"
426 SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
428 def init_smesh(self,geompyD = None):
430 Set Geometry component
433 self.UpdateStudy(geompyD)
434 notebook.myStudy = salome.myStudy
436 def Mesh(self, obj=0, name=0):
438 Create a mesh. This mesh can be either
440 * an empty mesh not bound to geometry, if *obj* == 0
441 * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
442 * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
447 1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
450 salome.myStudy.FindObjectID("0:1:2:3").GetObject()
452 2. a geometrical object for meshing
454 name: the name for the new mesh.
457 an instance of class :class:`Mesh`.
460 if isinstance(obj,str):
462 return Mesh(self, self.geompyD, obj, name)
464 def RemoveMesh( self, mesh ):
468 if isinstance( mesh, Mesh ):
469 mesh = mesh.GetMesh()
471 if not isinstance( mesh, SMESH._objref_SMESH_Mesh ):
472 raise TypeError("%s is not a mesh" % mesh )
473 so = salome.ObjectToSObject( mesh )
475 sb = salome.myStudy.NewBuilder()
476 sb.RemoveObjectWithChildren( so )
482 def EnumToLong(self,theItem):
484 Return a long value from enumeration
489 def ColorToString(self,c):
491 Convert SALOMEDS.Color to string.
492 To be used with filters.
495 c: color value (SALOMEDS.Color)
498 a string representation of the color.
502 if isinstance(c, SALOMEDS.Color):
503 val = "%s;%s;%s" % (c.R, c.G, c.B)
504 elif isinstance(c, str):
507 raise ValueError("Color value should be of string or SALOMEDS.Color type")
510 def GetPointStruct(self,theVertex):
512 Get :class:`SMESH.PointStruct` from vertex
515 theVertex (GEOM.GEOM_Object): vertex
518 :class:`SMESH.PointStruct`
520 geompyD = theVertex.GetGen()
521 [x, y, z] = geompyD.PointCoordinates(theVertex)
522 return PointStruct(x,y,z)
524 def GetDirStruct(self,theVector):
526 Get :class:`SMESH.DirStruct` from vector
529 theVector (GEOM.GEOM_Object): vector
532 :class:`SMESH.DirStruct`
534 geompyD = theVector.GetGen()
535 vertices = geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
536 if(len(vertices) != 2):
537 print("Error: vector object is incorrect.")
539 p1 = geompyD.PointCoordinates(vertices[0])
540 p2 = geompyD.PointCoordinates(vertices[1])
541 pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
542 dirst = DirStruct(pnt)
545 def MakeDirStruct(self,x,y,z):
547 Make :class:`SMESH.DirStruct` from a triplet of floats
550 x,y,z (float): vector components
553 :class:`SMESH.DirStruct`
556 pnt = PointStruct(x,y,z)
557 return DirStruct(pnt)
559 def GetAxisStruct(self,theObj):
561 Get :class:`SMESH.AxisStruct` from a geometrical object
564 theObj (GEOM.GEOM_Object): line or plane
567 :class:`SMESH.AxisStruct`
570 geompyD = theObj.GetGen()
571 edges = geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
574 vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
575 vertex3, vertex4 = geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
576 vertex1 = geompyD.PointCoordinates(vertex1)
577 vertex2 = geompyD.PointCoordinates(vertex2)
578 vertex3 = geompyD.PointCoordinates(vertex3)
579 vertex4 = geompyD.PointCoordinates(vertex4)
580 v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
581 v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
582 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] ]
583 axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
584 axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
585 elif len(edges) == 1:
586 vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
587 p1 = geompyD.PointCoordinates( vertex1 )
588 p2 = geompyD.PointCoordinates( vertex2 )
589 axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
590 axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
591 elif theObj.GetShapeType() == GEOM.VERTEX:
592 x,y,z = geompyD.PointCoordinates( theObj )
593 axis = AxisStruct( x,y,z, 1,0,0,)
594 axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
597 # From SMESH_Gen interface:
598 # ------------------------
600 def SetName(self, obj, name):
602 Set the given name to an object
605 obj: the object to rename
606 name: a new object name
609 if isinstance( obj, Mesh ):
611 elif isinstance( obj, Mesh_Algorithm ):
612 obj = obj.GetAlgorithm()
613 ior = salome.orb.object_to_string(obj)
614 SMESH._objref_SMESH_Gen.SetName(self, ior, name)
616 def SetEmbeddedMode( self,theMode ):
621 SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
623 def IsEmbeddedMode(self):
628 return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
630 def UpdateStudy( self, geompyD = None ):
632 Update the current study. Calling UpdateStudy() allows to
633 update meshes at switching GEOM->SMESH
637 from salome.geom import geomBuilder
638 geompyD = geomBuilder.geom
640 geompyD = geomBuilder.New()
643 self.SetGeomEngine(geompyD)
644 SMESH._objref_SMESH_Gen.UpdateStudy(self)
645 sb = salome.myStudy.NewBuilder()
646 sc = salome.myStudy.FindComponent("SMESH")
648 sb.LoadWith(sc, self)
651 def SetEnablePublish( self, theIsEnablePublish ):
653 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
654 switch **off** publishing in the Study of mesh objects.
656 #self.SetEnablePublish(theIsEnablePublish)
657 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
659 notebook = salome_notebook.NoteBook( theIsEnablePublish )
662 def CreateMeshesFromUNV( self,theFileName ):
664 Create a Mesh object importing data from the given UNV file
667 an instance of class :class:`Mesh`
670 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
671 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
674 def CreateMeshesFromMED( self,theFileName ):
676 Create a Mesh object(s) importing data from the given MED file
679 a tuple ( list of class :class:`Mesh` instances,
680 :class:`SMESH.DriverMED_ReadStatus` )
683 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
684 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
685 return aMeshes, aStatus
687 def CreateMeshesFromSAUV( self,theFileName ):
689 Create a Mesh object(s) importing data from the given SAUV file
692 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
695 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
696 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
697 return aMeshes, aStatus
699 def CreateMeshesFromSTL( self, theFileName ):
701 Create a Mesh object importing data from the given STL file
704 an instance of class :class:`Mesh`
707 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
708 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
711 def CreateMeshesFromCGNS( self, theFileName ):
713 Create Mesh objects importing data from the given CGNS file
716 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
719 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
720 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
721 return aMeshes, aStatus
723 def CreateMeshesFromGMF( self, theFileName ):
725 Create a Mesh object importing data from the given GMF file.
726 GMF files must have .mesh extension for the ASCII format and .meshb for
730 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
733 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
736 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
737 return Mesh(self, self.geompyD, aSmeshMesh), error
739 def Concatenate( self, meshes, uniteIdenticalGroups,
740 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
741 name = "", meshToAppendTo = None):
743 Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
744 All groups of input meshes will be present in the new mesh.
747 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
748 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
749 mergeNodesAndElements: if True, equal nodes and elements are merged
750 mergeTolerance: tolerance for merging nodes
751 allGroups: forces creation of groups corresponding to every input mesh
752 name: name of a new mesh
753 meshToAppendTo: a mesh to append all given meshes
756 an instance of class :class:`Mesh`
762 if not meshes: return None
763 if not isinstance( meshes, list ):
765 for i,m in enumerate( meshes ):
766 if isinstance( m, Mesh ):
767 meshes[i] = m.GetMesh()
768 mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
769 if hasattr(meshes[0], "SetParameters"):
770 meshes[0].SetParameters( Parameters )
772 meshes[0].GetMesh().SetParameters( Parameters )
773 if isinstance( meshToAppendTo, Mesh ):
774 meshToAppendTo = meshToAppendTo.GetMesh()
776 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
777 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
778 mergeTolerance,meshToAppendTo )
780 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
781 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
782 mergeTolerance,meshToAppendTo )
784 aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
787 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
789 Create a mesh by copying a part of another mesh.
792 meshPart: a part of mesh to copy, either
793 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
794 To copy nodes or elements not forming any mesh object,
795 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
796 meshName: a name of the new mesh
797 toCopyGroups: to create in the new mesh groups the copied elements belongs to
798 toKeepIDs: to preserve order of the copied elements or not
801 an instance of class :class:`Mesh`
804 if isinstance( meshPart, Mesh ):
805 meshPart = meshPart.GetMesh()
806 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
807 return Mesh(self, self.geompyD, mesh)
809 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
810 toReuseHypotheses=True, toCopyElements=True):
812 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
813 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
814 To facilitate and speed up the operation, consider using
815 "Set presentation parameters and sub-shapes from arguments" option in
816 a dialog of geometrical operation used to create the new geometry.
819 sourceMesh: the mesh to copy definition of.
820 newGeom: the new geometry.
821 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
822 toCopyGroups: to create groups in the new mesh.
823 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
824 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
827 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
828 *invalidEntries* are study entries of objects whose
829 counterparts are not found in the *newGeom*, followed by entries
830 of mesh sub-objects that are invalid because they depend on a not found
833 if isinstance( sourceMesh, Mesh ):
834 sourceMesh = sourceMesh.GetMesh()
836 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
837 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
841 return ( ok, Mesh(self, self.geompyD, newMesh),
842 newGroups, newSubMeshes, newHypotheses, invalidEntries )
844 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
846 Return IDs of sub-shapes
849 theMainObject (GEOM.GEOM_Object): a shape
850 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
852 the list of integer values
855 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
857 def GetPattern(self):
859 Create a pattern mapper.
862 an instance of :class:`SMESH.SMESH_Pattern`
864 :ref:`Example of Patterns usage <tui_pattern_mapping>`
867 return SMESH._objref_SMESH_Gen.GetPattern(self)
869 def SetBoundaryBoxSegmentation(self, nbSegments):
871 Set number of segments per diagonal of boundary box of geometry, by which
872 default segment length of appropriate 1D hypotheses is defined in GUI.
876 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
878 # Filtering. Auxiliary functions:
879 # ------------------------------
881 def GetEmptyCriterion(self):
883 Create an empty criterion
886 :class:`SMESH.Filter.Criterion`
889 Type = self.EnumToLong(FT_Undefined)
890 Compare = self.EnumToLong(FT_Undefined)
894 UnaryOp = self.EnumToLong(FT_Undefined)
895 BinaryOp = self.EnumToLong(FT_Undefined)
898 Precision = -1 ##@1e-07
899 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
900 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
902 def GetCriterion(self,elementType,
904 Compare = FT_EqualTo,
906 UnaryOp=FT_Undefined,
907 BinaryOp=FT_Undefined,
910 Create a criterion by the given parameters
911 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
914 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
915 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
916 Note that the items starting from FT_LessThan are not suitable for *CritType*.
917 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
918 Threshold: the threshold value (range of ids as string, shape, numeric)
919 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
920 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
922 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
923 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
926 :class:`SMESH.Filter.Criterion`
928 Example: :ref:`combining_filters`
931 if not CritType in SMESH.FunctorType._items:
932 raise TypeError("CritType should be of SMESH.FunctorType")
933 aCriterion = self.GetEmptyCriterion()
934 aCriterion.TypeOfElement = elementType
935 aCriterion.Type = self.EnumToLong(CritType)
936 aCriterion.Tolerance = Tolerance
938 aThreshold = Threshold
940 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
941 aCriterion.Compare = self.EnumToLong(Compare)
942 elif Compare == "=" or Compare == "==":
943 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
945 aCriterion.Compare = self.EnumToLong(FT_LessThan)
947 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
948 elif Compare != FT_Undefined:
949 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
952 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
953 FT_BelongToCylinder, FT_LyingOnGeom]:
954 # Check that Threshold is GEOM object
955 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
956 aCriterion.ThresholdStr = GetName(aThreshold)
957 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
958 if not aCriterion.ThresholdID:
959 name = aCriterion.ThresholdStr
961 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
962 geompyD = aThreshold.GetGen()
963 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
964 # or a name of GEOM object
965 elif isinstance( aThreshold, str ):
966 aCriterion.ThresholdStr = aThreshold
968 raise TypeError("The Threshold should be a shape.")
969 if isinstance(UnaryOp,float):
970 aCriterion.Tolerance = UnaryOp
971 UnaryOp = FT_Undefined
973 elif CritType == FT_BelongToMeshGroup:
974 # Check that Threshold is a group
975 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
976 if aThreshold.GetType() != elementType:
977 raise ValueError("Group type mismatches Element type")
978 aCriterion.ThresholdStr = aThreshold.GetName()
979 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
980 study = salome.myStudy
982 so = study.FindObjectIOR( aCriterion.ThresholdID )
986 aCriterion.ThresholdID = entry
988 raise TypeError("The Threshold should be a Mesh Group")
989 elif CritType == FT_RangeOfIds:
990 # Check that Threshold is string
991 if isinstance(aThreshold, str):
992 aCriterion.ThresholdStr = aThreshold
994 raise TypeError("The Threshold should be a string.")
995 elif CritType == FT_CoplanarFaces:
996 # Check the Threshold
997 if isinstance(aThreshold, int):
998 aCriterion.ThresholdID = str(aThreshold)
999 elif isinstance(aThreshold, str):
1000 ID = int(aThreshold)
1002 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
1003 aCriterion.ThresholdID = aThreshold
1005 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1006 elif CritType == FT_ConnectedElements:
1007 # Check the Threshold
1008 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1009 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1010 if not aCriterion.ThresholdID:
1011 name = aThreshold.GetName()
1013 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1014 geompyD = aThreshold.GetGen()
1015 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
1016 elif isinstance(aThreshold, int): # node id
1017 aCriterion.Threshold = aThreshold
1018 elif isinstance(aThreshold, list): # 3 point coordinates
1019 if len( aThreshold ) < 3:
1020 raise ValueError("too few point coordinates, must be 3")
1021 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1022 elif isinstance(aThreshold, str):
1023 if aThreshold.isdigit():
1024 aCriterion.Threshold = aThreshold # node id
1026 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1028 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1029 "or a list of point coordinates and not '%s'"%aThreshold)
1030 elif CritType == FT_ElemGeomType:
1031 # Check the Threshold
1033 aCriterion.Threshold = self.EnumToLong(aThreshold)
1034 assert( aThreshold in SMESH.GeometryType._items )
1036 if isinstance(aThreshold, int):
1037 aCriterion.Threshold = aThreshold
1039 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1042 elif CritType == FT_EntityType:
1043 # Check the Threshold
1045 aCriterion.Threshold = self.EnumToLong(aThreshold)
1046 assert( aThreshold in SMESH.EntityType._items )
1048 if isinstance(aThreshold, int):
1049 aCriterion.Threshold = aThreshold
1051 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1055 elif CritType == FT_GroupColor:
1056 # Check the Threshold
1058 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1060 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1062 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1063 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1064 FT_BareBorderFace, FT_BareBorderVolume,
1065 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1066 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1067 # At this point the Threshold is unnecessary
1068 if aThreshold == FT_LogicalNOT:
1069 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1070 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1071 aCriterion.BinaryOp = aThreshold
1075 aThreshold = float(aThreshold)
1076 aCriterion.Threshold = aThreshold
1078 raise TypeError("The Threshold should be a number.")
1081 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1082 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1084 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1085 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1087 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1088 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1090 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1091 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1095 def GetFilter(self,elementType,
1096 CritType=FT_Undefined,
1099 UnaryOp=FT_Undefined,
1103 Create a filter with the given parameters
1106 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1107 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1108 Note that the items starting from FT_LessThan are not suitable for CritType.
1109 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1110 Threshold: the threshold value (range of ids as string, shape, numeric)
1111 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1112 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1113 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1114 mesh: the mesh to initialize the filter with
1117 :class:`SMESH.Filter`
1120 See :doc:`Filters usage examples <tui_filters>`
1123 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1124 aFilterMgr = self.CreateFilterManager()
1125 aFilter = aFilterMgr.CreateFilter()
1127 aCriteria.append(aCriterion)
1128 aFilter.SetCriteria(aCriteria)
1130 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1131 else : aFilter.SetMesh( mesh )
1132 aFilterMgr.UnRegister()
1135 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1137 Create a filter from criteria
1140 criteria: a list of :class:`SMESH.Filter.Criterion`
1141 binOp: binary operator used when binary operator of criteria is undefined
1144 :class:`SMESH.Filter`
1147 See :doc:`Filters usage examples <tui_filters>`
1150 for i in range( len( criteria ) - 1 ):
1151 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1152 criteria[i].BinaryOp = self.EnumToLong( binOp )
1153 aFilterMgr = self.CreateFilterManager()
1154 aFilter = aFilterMgr.CreateFilter()
1155 aFilter.SetCriteria(criteria)
1156 aFilterMgr.UnRegister()
1159 def GetFunctor(self,theCriterion):
1161 Create a numerical functor by its type
1164 theCriterion (SMESH.FunctorType): functor type.
1165 Note that not all items correspond to numerical functors.
1168 :class:`SMESH.NumericalFunctor`
1171 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1173 aFilterMgr = self.CreateFilterManager()
1175 if theCriterion == FT_AspectRatio:
1176 functor = aFilterMgr.CreateAspectRatio()
1177 elif theCriterion == FT_AspectRatio3D:
1178 functor = aFilterMgr.CreateAspectRatio3D()
1179 elif theCriterion == FT_Warping:
1180 functor = aFilterMgr.CreateWarping()
1181 elif theCriterion == FT_MinimumAngle:
1182 functor = aFilterMgr.CreateMinimumAngle()
1183 elif theCriterion == FT_Taper:
1184 functor = aFilterMgr.CreateTaper()
1185 elif theCriterion == FT_Skew:
1186 functor = aFilterMgr.CreateSkew()
1187 elif theCriterion == FT_Area:
1188 functor = aFilterMgr.CreateArea()
1189 elif theCriterion == FT_Volume3D:
1190 functor = aFilterMgr.CreateVolume3D()
1191 elif theCriterion == FT_MaxElementLength2D:
1192 functor = aFilterMgr.CreateMaxElementLength2D()
1193 elif theCriterion == FT_MaxElementLength3D:
1194 functor = aFilterMgr.CreateMaxElementLength3D()
1195 elif theCriterion == FT_MultiConnection:
1196 functor = aFilterMgr.CreateMultiConnection()
1197 elif theCriterion == FT_MultiConnection2D:
1198 functor = aFilterMgr.CreateMultiConnection2D()
1199 elif theCriterion == FT_Length:
1200 functor = aFilterMgr.CreateLength()
1201 elif theCriterion == FT_Length2D:
1202 functor = aFilterMgr.CreateLength2D()
1203 elif theCriterion == FT_Length3D:
1204 functor = aFilterMgr.CreateLength3D()
1205 elif theCriterion == FT_Deflection2D:
1206 functor = aFilterMgr.CreateDeflection2D()
1207 elif theCriterion == FT_NodeConnectivityNumber:
1208 functor = aFilterMgr.CreateNodeConnectivityNumber()
1209 elif theCriterion == FT_BallDiameter:
1210 functor = aFilterMgr.CreateBallDiameter()
1212 print("Error: given parameter is not numerical functor type.")
1213 aFilterMgr.UnRegister()
1216 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1221 theHType (string): mesh hypothesis type
1222 theLibName (string): mesh plug-in library name
1225 created hypothesis instance
1227 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1229 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1232 # wrap hypothesis methods
1233 for meth_name in dir( hyp.__class__ ):
1234 if not meth_name.startswith("Get") and \
1235 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1236 method = getattr ( hyp.__class__, meth_name )
1237 if callable(method):
1238 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1242 def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1244 Create hypothesis initialized according to parameters
1247 hypType (string): hypothesis type
1248 libName (string): plug-in library name
1249 mesh: optional mesh by which a hypotheses can initialize self
1250 shape: optional geometry by size of which a hypotheses can initialize self
1251 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1254 created hypothesis instance
1256 if isinstance( mesh, Mesh ):
1257 mesh = mesh.GetMesh()
1258 if isinstance( initParams, (bool,int)):
1259 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1260 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1261 mesh, shape, initParams )
1263 def GetMeshInfo(self, obj):
1265 Get the mesh statistic.
1268 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1271 if isinstance( obj, Mesh ):
1274 if hasattr(obj, "GetMeshInfo"):
1275 values = obj.GetMeshInfo()
1276 for i in range(SMESH.Entity_Last._v):
1277 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1281 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1283 Get minimum distance between two objects
1285 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1286 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1289 src1 (SMESH.SMESH_IDSource): first source object
1290 src2 (SMESH.SMESH_IDSource): second source object
1291 id1 (int): node/element id from the first source
1292 id2 (int): node/element id from the second (or first) source
1293 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1294 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1297 minimum distance value
1300 :meth:`GetMinDistance`
1303 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1307 result = result.value
1310 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1312 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1314 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1315 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1318 src1 (SMESH.SMESH_IDSource): first source object
1319 src2 (SMESH.SMESH_IDSource): second source object
1320 id1 (int): node/element id from the first source
1321 id2 (int): node/element id from the second (or first) source
1322 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1323 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1326 :class:`SMESH.Measure` structure or None if input data is invalid
1331 if isinstance(src1, Mesh): src1 = src1.mesh
1332 if isinstance(src2, Mesh): src2 = src2.mesh
1333 if src2 is None and id2 != 0: src2 = src1
1334 if not hasattr(src1, "_narrow"): return None
1335 src1 = src1._narrow(SMESH.SMESH_IDSource)
1336 if not src1: return None
1337 unRegister = genObjUnRegister()
1340 e = m.GetMeshEditor()
1342 src1 = e.MakeIDSource([id1], SMESH.FACE)
1344 src1 = e.MakeIDSource([id1], SMESH.NODE)
1345 unRegister.set( src1 )
1347 if hasattr(src2, "_narrow"):
1348 src2 = src2._narrow(SMESH.SMESH_IDSource)
1349 if src2 and id2 != 0:
1351 e = m.GetMeshEditor()
1353 src2 = e.MakeIDSource([id2], SMESH.FACE)
1355 src2 = e.MakeIDSource([id2], SMESH.NODE)
1356 unRegister.set( src2 )
1359 aMeasurements = self.CreateMeasurements()
1360 unRegister.set( aMeasurements )
1361 result = aMeasurements.MinDistance(src1, src2)
1364 def BoundingBox(self, objects):
1366 Get bounding box of the specified object(s)
1369 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1372 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1375 :meth:`GetBoundingBox`
1378 result = self.GetBoundingBox(objects)
1382 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1385 def GetBoundingBox(self, objects):
1387 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1390 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1393 :class:`SMESH.Measure` structure
1399 if isinstance(objects, tuple):
1400 objects = list(objects)
1401 if not isinstance(objects, list):
1405 if isinstance(o, Mesh):
1406 srclist.append(o.mesh)
1407 elif hasattr(o, "_narrow"):
1408 src = o._narrow(SMESH.SMESH_IDSource)
1409 if src: srclist.append(src)
1412 aMeasurements = self.CreateMeasurements()
1413 result = aMeasurements.BoundingBox(srclist)
1414 aMeasurements.UnRegister()
1417 def GetLength(self, obj):
1419 Get sum of lengths of all 1D elements in the mesh object.
1422 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1425 sum of lengths of all 1D elements
1428 if isinstance(obj, Mesh): obj = obj.mesh
1429 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1430 aMeasurements = self.CreateMeasurements()
1431 value = aMeasurements.Length(obj)
1432 aMeasurements.UnRegister()
1435 def GetArea(self, obj):
1437 Get sum of areas of all 2D elements in the mesh object.
1440 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1443 sum of areas of all 2D elements
1446 if isinstance(obj, Mesh): obj = obj.mesh
1447 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1448 aMeasurements = self.CreateMeasurements()
1449 value = aMeasurements.Area(obj)
1450 aMeasurements.UnRegister()
1453 def GetVolume(self, obj):
1455 Get sum of volumes of all 3D elements in the mesh object.
1458 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1461 sum of volumes of all 3D elements
1464 if isinstance(obj, Mesh): obj = obj.mesh
1465 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1466 aMeasurements = self.CreateMeasurements()
1467 value = aMeasurements.Volume(obj)
1468 aMeasurements.UnRegister()
1471 def GetGravityCenter(self, obj):
1473 Get gravity center of all nodes of a mesh object.
1476 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1479 Three components of the gravity center (x,y,z)
1482 :meth:`Mesh.BaryCenter`
1484 if isinstance(obj, Mesh): obj = obj.mesh
1485 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1486 aMeasurements = self.CreateMeasurements()
1487 pointStruct = aMeasurements.GravityCenter(obj)
1488 aMeasurements.UnRegister()
1489 return pointStruct.x, pointStruct.y, pointStruct.z
1491 def GetAngle(self, p1, p2, p3 ):
1493 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1496 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1502 if isinstance( p1, list ): p1 = PointStruct(*p1)
1503 if isinstance( p2, list ): p2 = PointStruct(*p2)
1504 if isinstance( p3, list ): p3 = PointStruct(*p3)
1506 aMeasurements = self.CreateMeasurements()
1507 angle = aMeasurements.Angle(p1,p2,p3)
1508 aMeasurements.UnRegister()
1513 pass # end of class smeshBuilder
1516 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1517 """Registering the new proxy for SMESH.SMESH_Gen"""
1520 def New( instance=None, instanceGeom=None):
1522 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1523 interface to create or load meshes.
1528 salome.salome_init()
1529 from salome.smesh import smeshBuilder
1530 smesh = smeshBuilder.New()
1533 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1534 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1536 :class:`smeshBuilder` instance
1541 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1543 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1548 smeshInst = smeshBuilder()
1549 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1550 smeshInst.init_smesh(instanceGeom)
1554 # Public class: Mesh
1555 # ==================
1558 class Mesh(metaclass = MeshMeta):
1560 This class allows defining and managing a mesh.
1561 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1562 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1563 new nodes and elements and by changing the existing entities), to get information
1564 about a mesh and to export a mesh in different formats.
1571 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1576 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1577 sets the GUI name of this mesh to *name*.
1580 smeshpyD: an instance of smeshBuilder class
1581 geompyD: an instance of geomBuilder class
1582 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1583 name: Study name of the mesh
1586 self.smeshpyD = smeshpyD
1587 self.geompyD = geompyD
1592 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1595 # publish geom of mesh (issue 0021122)
1596 if not self.geom.GetStudyEntry():
1600 geo_name = name + " shape"
1602 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1603 geompyD.addToStudy( self.geom, geo_name )
1604 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1606 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1609 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1611 self.smeshpyD.SetName(self.mesh, name)
1613 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1616 self.geom = self.mesh.GetShapeToMesh()
1618 self.editor = self.mesh.GetMeshEditor()
1619 self.functors = [None] * SMESH.FT_Undefined._v
1621 # set self to algoCreator's
1622 for attrName in dir(self):
1623 attr = getattr( self, attrName )
1624 if isinstance( attr, algoCreator ):
1625 setattr( self, attrName, attr.copy( self ))
1632 Destructor. Clean-up resources
1635 #self.mesh.UnRegister()
1639 def SetMesh(self, theMesh):
1641 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1644 theMesh: a :class:`SMESH.SMESH_Mesh` object
1646 # do not call Register() as this prevents mesh servant deletion at closing study
1647 #if self.mesh: self.mesh.UnRegister()
1650 #self.mesh.Register()
1651 self.geom = self.mesh.GetShapeToMesh()
1653 self.geompyD = self.geom.GetGen()
1659 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1662 a :class:`SMESH.SMESH_Mesh` object
1667 def GetEngine(self):
1669 Return a smeshBuilder instance created this mesh
1671 return self.smeshpyD
1673 def GetGeomEngine(self):
1675 Return a geomBuilder instance
1681 Get the name of the mesh
1684 the name of the mesh as a string
1687 name = GetName(self.GetMesh())
1690 def SetName(self, name):
1692 Set a name to the mesh
1695 name: a new name of the mesh
1698 self.smeshpyD.SetName(self.GetMesh(), name)
1700 def GetSubMesh(self, geom, name):
1702 Get a sub-mesh object associated to a *geom* geometrical object.
1705 geom: a geometrical object (shape)
1706 name: a name for the sub-mesh in the Object Browser
1709 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1710 which lies on the given shape
1713 A sub-mesh is implicitly created when a sub-shape is specified at
1714 creating an algorithm, for example::
1716 algo1D = mesh.Segment(geom=Edge_1)
1718 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1719 The created sub-mesh can be retrieved from the algorithm::
1721 submesh = algo1D.GetSubMesh()
1724 AssureGeomPublished( self, geom, name )
1725 submesh = self.mesh.GetSubMesh( geom, name )
1730 Return the shape associated to the mesh
1738 def SetShape(self, geom):
1740 Associate the given shape to the mesh (entails the recreation of the mesh)
1743 geom: the shape to be meshed (GEOM_Object)
1746 self.mesh = self.smeshpyD.CreateMesh(geom)
1748 def HasShapeToMesh(self):
1750 Return ``True`` if this mesh is based on geometry
1752 return self.mesh.HasShapeToMesh()
1756 Load mesh from the study after opening the study
1760 def IsReadyToCompute(self, theSubObject):
1762 Return true if the hypotheses are defined well
1765 theSubObject: a sub-shape of a mesh shape
1771 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1773 def GetAlgoState(self, theSubObject):
1775 Return errors of hypotheses definition.
1776 The list of errors is empty if everything is OK.
1779 theSubObject: a sub-shape of a mesh shape
1785 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1787 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1789 Return a geometrical object on which the given element was built.
1790 The returned geometrical object, if not nil, is either found in the
1791 study or published by this method with the given name
1794 theElementID: the id of the mesh element
1795 theGeomName: the user-defined name of the geometrical object
1798 GEOM.GEOM_Object instance
1801 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1803 def MeshDimension(self):
1805 Return the mesh dimension depending on the dimension of the underlying shape
1806 or, if the mesh is not based on any shape, basing on deimension of elements
1809 mesh dimension as an integer value [0,3]
1812 if self.mesh.HasShapeToMesh():
1813 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1814 if len( shells ) > 0 :
1816 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1818 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1823 if self.NbVolumes() > 0: return 3
1824 if self.NbFaces() > 0: return 2
1825 if self.NbEdges() > 0: return 1
1828 def Evaluate(self, geom=0):
1830 Evaluate size of prospective mesh on a shape
1833 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1834 To know predicted number of e.g. edges, inquire it this way::
1836 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1839 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1841 geom = self.mesh.GetShapeToMesh()
1844 return self.smeshpyD.Evaluate(self.mesh, geom)
1847 def Compute(self, geom=0, discardModifs=False, refresh=False):
1849 Compute the mesh and return the status of the computation
1852 geom: geomtrical shape on which mesh data should be computed
1853 discardModifs: if True and the mesh has been edited since
1854 a last total re-compute and that may prevent successful partial re-compute,
1855 then the mesh is cleaned before Compute()
1856 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1862 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1863 geom = self.mesh.GetShapeToMesh()
1866 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1868 ok = self.smeshpyD.Compute(self.mesh, geom)
1869 except SALOME.SALOME_Exception as ex:
1870 print("Mesh computation failed, exception caught:")
1871 print(" ", ex.details.text)
1874 print("Mesh computation failed, exception caught:")
1875 traceback.print_exc()
1879 # Treat compute errors
1880 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1882 for err in computeErrors:
1883 if self.mesh.HasShapeToMesh():
1884 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1886 stdErrors = ["OK", #COMPERR_OK
1887 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1888 "std::exception", #COMPERR_STD_EXCEPTION
1889 "OCC exception", #COMPERR_OCC_EXCEPTION
1890 "..", #COMPERR_SLM_EXCEPTION
1891 "Unknown exception", #COMPERR_EXCEPTION
1892 "Memory allocation problem", #COMPERR_MEMORY_PB
1893 "Algorithm failed", #COMPERR_ALGO_FAILED
1894 "Unexpected geometry", #COMPERR_BAD_SHAPE
1895 "Warning", #COMPERR_WARNING
1896 "Computation cancelled",#COMPERR_CANCELED
1897 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1899 if err.code < len(stdErrors): errText = stdErrors[err.code]
1901 errText = "code %s" % -err.code
1902 if errText: errText += ". "
1903 errText += err.comment
1904 if allReasons: allReasons += "\n"
1906 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1908 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1912 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1914 if err.isGlobalAlgo:
1922 reason = '%s %sD algorithm is missing' % (glob, dim)
1923 elif err.state == HYP_MISSING:
1924 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1925 % (glob, dim, name, dim))
1926 elif err.state == HYP_NOTCONFORM:
1927 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1928 elif err.state == HYP_BAD_PARAMETER:
1929 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1930 % ( glob, dim, name ))
1931 elif err.state == HYP_BAD_GEOMETRY:
1932 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1933 'geometry' % ( glob, dim, name ))
1934 elif err.state == HYP_HIDDEN_ALGO:
1935 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1936 'algorithm of upper dimension generating %sD mesh'
1937 % ( glob, dim, name, glob, dim ))
1939 reason = ("For unknown reason. "
1940 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1942 if allReasons: allReasons += "\n"
1943 allReasons += "- " + reason
1945 if not ok or allReasons != "":
1946 msg = '"' + GetName(self.mesh) + '"'
1947 if ok: msg += " has been computed with warnings"
1948 else: msg += " has not been computed"
1949 if allReasons != "": msg += ":"
1954 if salome.sg.hasDesktop():
1955 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1956 if refresh: salome.sg.updateObjBrowser()
1960 def GetComputeErrors(self, shape=0 ):
1962 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1966 shape = self.mesh.GetShapeToMesh()
1967 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1969 def GetSubShapeName(self, subShapeID ):
1971 Return a name of a sub-shape by its ID.
1972 Possible variants (for *subShapeID* == 3):
1974 - **"Face_12"** - published sub-shape
1975 - **FACE #3** - not published sub-shape
1976 - **sub-shape #3** - invalid sub-shape ID
1977 - **#3** - error in this function
1980 subShapeID: a unique ID of a sub-shape
1983 a string describing the sub-shape
1987 if not self.mesh.HasShapeToMesh():
1991 mainIOR = salome.orb.object_to_string( self.GetShape() )
1993 mainSO = s.FindObjectIOR(mainIOR)
1996 shapeText = '"%s"' % mainSO.GetName()
1997 subIt = s.NewChildIterator(mainSO)
1999 subSO = subIt.Value()
2001 obj = subSO.GetObject()
2002 if not obj: continue
2003 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2006 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2009 if ids == subShapeID:
2010 shapeText = '"%s"' % subSO.GetName()
2013 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2015 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2017 shapeText = 'sub-shape #%s' % (subShapeID)
2019 shapeText = "#%s" % (subShapeID)
2022 def GetFailedShapes(self, publish=False):
2024 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2025 error of an algorithm
2028 publish: if *True*, the returned groups will be published in the study
2031 a list of GEOM groups each named after a failed algorithm
2036 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2037 for err in computeErrors:
2038 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2039 if not shape: continue
2040 if err.algoName in algo2shapes:
2041 algo2shapes[ err.algoName ].append( shape )
2043 algo2shapes[ err.algoName ] = [ shape ]
2047 for algoName, shapes in list(algo2shapes.items()):
2049 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2050 otherTypeShapes = []
2052 group = self.geompyD.CreateGroup( self.geom, groupType )
2053 for shape in shapes:
2054 if shape.GetShapeType() == shapes[0].GetShapeType():
2055 sameTypeShapes.append( shape )
2057 otherTypeShapes.append( shape )
2058 self.geompyD.UnionList( group, sameTypeShapes )
2060 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2062 group.SetName( algoName )
2063 groups.append( group )
2064 shapes = otherTypeShapes
2067 for group in groups:
2068 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2071 def GetMeshOrder(self):
2073 Return sub-mesh objects list in meshing order
2076 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2079 return self.mesh.GetMeshOrder()
2081 def SetMeshOrder(self, submeshes):
2083 Set priority of sub-meshes. It works in two ways:
2085 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2086 *several dimensions*, it sets the order in which the sub-meshes are computed.
2087 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2088 when looking for meshing parameters to apply to a sub-shape. To impose the
2089 order in which sub-meshes with uni-dimensional algorithms are computed,
2090 call **submesh.Compute()** in a desired order.
2093 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2095 Warning: the method is for setting the order for all sub-meshes at once:
2096 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2099 return self.mesh.SetMeshOrder(submeshes)
2101 def Clear(self, refresh=False):
2103 Remove all nodes and elements generated on geometry. Imported elements remain.
2106 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2110 if ( salome.sg.hasDesktop() ):
2111 if refresh: salome.sg.updateObjBrowser()
2113 def ClearSubMesh(self, geomId, refresh=False):
2115 Remove all nodes and elements of indicated shape
2118 geomId: the ID of a sub-shape to remove elements on
2119 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2122 self.mesh.ClearSubMesh(geomId)
2123 if salome.sg.hasDesktop():
2124 if refresh: salome.sg.updateObjBrowser()
2126 def AutomaticTetrahedralization(self, fineness=0):
2128 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2131 fineness: [0.0,1.0] defines mesh fineness
2137 dim = self.MeshDimension()
2139 self.RemoveGlobalHypotheses()
2140 self.Segment().AutomaticLength(fineness)
2142 self.Triangle().LengthFromEdges()
2147 return self.Compute()
2149 def AutomaticHexahedralization(self, fineness=0):
2151 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2154 fineness: [0.0, 1.0] defines mesh fineness
2160 dim = self.MeshDimension()
2161 # assign the hypotheses
2162 self.RemoveGlobalHypotheses()
2163 self.Segment().AutomaticLength(fineness)
2170 return self.Compute()
2172 def AddHypothesis(self, hyp, geom=0):
2177 hyp: a hypothesis to assign
2178 geom: a subhape of mesh geometry
2181 :class:`SMESH.Hypothesis_Status`
2184 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2185 hyp, geom = geom, hyp
2186 if isinstance( hyp, Mesh_Algorithm ):
2187 hyp = hyp.GetAlgorithm()
2192 geom = self.mesh.GetShapeToMesh()
2195 if self.mesh.HasShapeToMesh():
2196 hyp_type = hyp.GetName()
2197 lib_name = hyp.GetLibName()
2198 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2199 # if checkAll and geom:
2200 # checkAll = geom.GetType() == 37
2202 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2204 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2205 status = self.mesh.AddHypothesis(geom, hyp)
2207 status = HYP_BAD_GEOMETRY, ""
2208 hyp_name = GetName( hyp )
2211 geom_name = geom.GetName()
2212 isAlgo = hyp._narrow( SMESH_Algo )
2213 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2216 def IsUsedHypothesis(self, hyp, geom):
2218 Return True if an algorithm or hypothesis is assigned to a given shape
2221 hyp: an algorithm or hypothesis to check
2222 geom: a subhape of mesh geometry
2228 if not hyp: # or not geom
2230 if isinstance( hyp, Mesh_Algorithm ):
2231 hyp = hyp.GetAlgorithm()
2233 hyps = self.GetHypothesisList(geom)
2235 if h.GetId() == hyp.GetId():
2239 def RemoveHypothesis(self, hyp, geom=0):
2241 Unassign a hypothesis
2244 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2245 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2248 :class:`SMESH.Hypothesis_Status`
2253 if isinstance( hyp, Mesh_Algorithm ):
2254 hyp = hyp.GetAlgorithm()
2260 if self.IsUsedHypothesis( hyp, shape ):
2261 return self.mesh.RemoveHypothesis( shape, hyp )
2262 hypName = GetName( hyp )
2263 geoName = GetName( shape )
2264 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2267 def GetHypothesisList(self, geom):
2269 Get the list of hypotheses added on a geometry
2272 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2275 the sequence of :class:`SMESH.SMESH_Hypothesis`
2278 return self.mesh.GetHypothesisList( geom )
2280 def RemoveGlobalHypotheses(self):
2282 Remove all global hypotheses
2285 current_hyps = self.mesh.GetHypothesisList( self.geom )
2286 for hyp in current_hyps:
2287 self.mesh.RemoveHypothesis( self.geom, hyp )
2290 def ExportMED(self, *args, **kwargs):
2292 Export the mesh in a file in MED format
2293 allowing to overwrite the file if it exists or add the exported data to its contents
2296 fileName: is the file name
2297 auto_groups (boolean): parameter for creating/not creating
2298 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2299 the typical use is auto_groups=False.
2300 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2301 The minor must be between 0 and the current minor version of MED file library.
2302 If minor is equal to -1, the minor version is not changed (default).
2303 The major version (x, where version is x.y.z) cannot be changed.
2304 overwrite (boolean): parameter for overwriting/not overwriting the file
2305 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2306 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2308 - 1D if all mesh nodes lie on OX coordinate axis, or
2309 - 2D if all mesh nodes lie on XOY coordinate plane, or
2310 - 3D in the rest cases.
2312 If *autoDimension* is *False*, the space dimension is always 3.
2313 fields: list of GEOM fields defined on the shape to mesh.
2314 geomAssocFields: each character of this string means a need to export a
2315 corresponding field; correspondence between fields and characters
2318 - 'v' stands for "_vertices_" field;
2319 - 'e' stands for "_edges_" field;
2320 - 'f' stands for "_faces_" field;
2321 - 's' stands for "_solids_" field.
2323 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2324 close to zero within a given tolerance, the coordinate is set to zero.
2325 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2327 # process positional arguments
2328 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2330 auto_groups = args[1] if len(args) > 1 else False
2331 minor = args[2] if len(args) > 2 else -1
2332 overwrite = args[3] if len(args) > 3 else True
2333 meshPart = args[4] if len(args) > 4 else None
2334 autoDimension = args[5] if len(args) > 5 else True
2335 fields = args[6] if len(args) > 6 else []
2336 geomAssocFields = args[7] if len(args) > 7 else ''
2337 z_tolerance = args[8] if len(args) > 8 else -1.
2338 # process keywords arguments
2339 auto_groups = kwargs.get("auto_groups", auto_groups)
2340 minor = kwargs.get("minor", minor)
2341 overwrite = kwargs.get("overwrite", overwrite)
2342 meshPart = kwargs.get("meshPart", meshPart)
2343 autoDimension = kwargs.get("autoDimension", autoDimension)
2344 fields = kwargs.get("fields", fields)
2345 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2346 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2348 # invoke engine's function
2349 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2350 unRegister = genObjUnRegister()
2351 if isinstance( meshPart, list ):
2352 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2353 unRegister.set( meshPart )
2355 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2356 self.mesh.SetParameters(Parameters)
2358 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2359 fields, geomAssocFields, z_tolerance)
2361 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2363 def ExportSAUV(self, f, auto_groups=0):
2365 Export the mesh in a file in SAUV format
2370 auto_groups: boolean parameter for creating/not creating
2371 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2372 the typical use is auto_groups=False.
2375 self.mesh.ExportSAUV(f, auto_groups)
2377 def ExportDAT(self, f, meshPart=None):
2379 Export the mesh in a file in DAT format
2383 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2387 unRegister = genObjUnRegister()
2388 if isinstance( meshPart, list ):
2389 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2390 unRegister.set( meshPart )
2391 self.mesh.ExportPartToDAT( meshPart, f )
2393 self.mesh.ExportDAT(f)
2395 def ExportUNV(self, f, meshPart=None):
2397 Export the mesh in a file in UNV format
2401 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2405 unRegister = genObjUnRegister()
2406 if isinstance( meshPart, list ):
2407 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2408 unRegister.set( meshPart )
2409 self.mesh.ExportPartToUNV( meshPart, f )
2411 self.mesh.ExportUNV(f)
2413 def ExportSTL(self, f, ascii=1, meshPart=None):
2415 Export the mesh in a file in STL format
2419 ascii: defines the file encoding
2420 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2424 unRegister = genObjUnRegister()
2425 if isinstance( meshPart, list ):
2426 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2427 unRegister.set( meshPart )
2428 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2430 self.mesh.ExportSTL(f, ascii)
2432 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2434 Export the mesh in a file in CGNS format
2438 overwrite: boolean parameter for overwriting/not overwriting the file
2439 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2440 groupElemsByType: if True all elements of same entity type are exported at ones,
2441 else elements are exported in order of their IDs which can cause creation
2442 of multiple cgns sections
2445 unRegister = genObjUnRegister()
2446 if isinstance( meshPart, list ):
2447 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2448 unRegister.set( meshPart )
2449 if isinstance( meshPart, Mesh ):
2450 meshPart = meshPart.mesh
2452 meshPart = self.mesh
2453 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2455 def ExportGMF(self, f, meshPart=None):
2457 Export the mesh in a file in GMF format.
2458 GMF files must have .mesh extension for the ASCII format and .meshb for
2459 the bynary format. Other extensions are not allowed.
2463 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2466 unRegister = genObjUnRegister()
2467 if isinstance( meshPart, list ):
2468 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2469 unRegister.set( meshPart )
2470 if isinstance( meshPart, Mesh ):
2471 meshPart = meshPart.mesh
2473 meshPart = self.mesh
2474 self.mesh.ExportGMF(meshPart, f, True)
2476 def ExportToMED(self, *args, **kwargs):
2478 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2479 Export the mesh in a file in MED format
2480 allowing to overwrite the file if it exists or add the exported data to its contents
2483 fileName: the file name
2484 opt (boolean): parameter for creating/not creating
2485 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2486 overwrite: boolean parameter for overwriting/not overwriting the file
2487 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2489 - 1D if all mesh nodes lie on OX coordinate axis, or
2490 - 2D if all mesh nodes lie on XOY coordinate plane, or
2491 - 3D in the rest cases.
2493 If **autoDimension** is *False*, the space dimension is always 3.
2496 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2497 # process positional arguments
2498 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2500 auto_groups = args[1] if len(args) > 1 else False
2501 overwrite = args[2] if len(args) > 2 else True
2502 autoDimension = args[3] if len(args) > 3 else True
2503 # process keywords arguments
2504 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2505 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2506 overwrite = kwargs.get("overwrite", overwrite)
2507 autoDimension = kwargs.get("autoDimension", autoDimension)
2509 # invoke engine's function
2510 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2512 def ExportToMEDX(self, *args, **kwargs):
2514 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2515 Export the mesh in a file in MED format
2518 fileName: the file name
2519 opt (boolean): parameter for creating/not creating
2520 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2521 overwrite: boolean parameter for overwriting/not overwriting the file
2522 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2524 - 1D if all mesh nodes lie on OX coordinate axis, or
2525 - 2D if all mesh nodes lie on XOY coordinate plane, or
2526 - 3D in the rest cases.
2528 If **autoDimension** is *False*, the space dimension is always 3.
2531 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2532 # process positional arguments
2533 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2535 auto_groups = args[1] if len(args) > 1 else False
2536 overwrite = args[2] if len(args) > 2 else True
2537 autoDimension = args[3] if len(args) > 3 else True
2538 # process keywords arguments
2539 auto_groups = kwargs.get("auto_groups", auto_groups)
2540 overwrite = kwargs.get("overwrite", overwrite)
2541 autoDimension = kwargs.get("autoDimension", autoDimension)
2543 # invoke engine's function
2544 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2548 def Append(self, meshes, uniteIdenticalGroups = True,
2549 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2551 Append given meshes into this mesh.
2552 All groups of input meshes will be created in this mesh.
2555 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2556 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2557 mergeNodesAndElements: if True, equal nodes and elements are merged
2558 mergeTolerance: tolerance for merging nodes
2559 allGroups: forces creation of groups corresponding to every input mesh
2561 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2562 mergeNodesAndElements, mergeTolerance, allGroups,
2563 meshToAppendTo = self.GetMesh() )
2565 # Operations with groups:
2566 # ----------------------
2567 def CreateEmptyGroup(self, elementType, name):
2569 Create an empty standalone mesh group
2572 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2573 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2574 name: the name of the mesh group
2577 :class:`SMESH.SMESH_Group`
2580 return self.mesh.CreateGroup(elementType, name)
2582 def Group(self, grp, name=""):
2584 Create a mesh group based on the geometric object *grp*
2585 and give it a *name*.
2586 If *name* is not defined the name of the geometric group is used
2589 Works like :meth:`GroupOnGeom`.
2592 grp: a geometric group, a vertex, an edge, a face or a solid
2593 name: the name of the mesh group
2596 :class:`SMESH.SMESH_GroupOnGeom`
2599 return self.GroupOnGeom(grp, name)
2601 def GroupOnGeom(self, grp, name="", typ=None):
2603 Create a mesh group based on the geometrical object *grp*
2604 and give it a *name*.
2605 if *name* is not defined the name of the geometric group is used
2608 grp: a geometrical group, a vertex, an edge, a face or a solid
2609 name: the name of the mesh group
2610 typ: the type of elements in the group; either of
2611 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2612 automatically detected by the type of the geometry
2615 :class:`SMESH.SMESH_GroupOnGeom`
2618 AssureGeomPublished( self, grp, name )
2620 name = grp.GetName()
2622 typ = self._groupTypeFromShape( grp )
2623 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2625 def _groupTypeFromShape( self, shape ):
2627 Pivate method to get a type of group on geometry
2629 tgeo = str(shape.GetShapeType())
2630 if tgeo == "VERTEX":
2632 elif tgeo == "EDGE" or tgeo == "WIRE":
2634 elif tgeo == "FACE" or tgeo == "SHELL":
2636 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2638 elif tgeo == "COMPOUND":
2639 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2641 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2642 return self._groupTypeFromShape( sub[0] )
2644 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2647 def GroupOnFilter(self, typ, name, filter):
2649 Create a mesh group with given *name* based on the *filter*.
2650 It is a special type of group dynamically updating it's contents during
2654 typ: the type of elements in the group; either of
2655 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2656 name: the name of the mesh group
2657 filter (SMESH.Filter): the filter defining group contents
2660 :class:`SMESH.SMESH_GroupOnFilter`
2663 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2665 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2667 Create a mesh group by the given ids of elements
2670 groupName: the name of the mesh group
2671 elementType: the type of elements in the group; either of
2672 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2673 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2676 :class:`SMESH.SMESH_Group`
2679 group = self.mesh.CreateGroup(elementType, groupName)
2680 if isinstance( elemIDs, Mesh ):
2681 elemIDs = elemIDs.GetMesh()
2682 if hasattr( elemIDs, "GetIDs" ):
2683 if hasattr( elemIDs, "SetMesh" ):
2684 elemIDs.SetMesh( self.GetMesh() )
2685 group.AddFrom( elemIDs )
2693 CritType=FT_Undefined,
2696 UnaryOp=FT_Undefined,
2699 Create a mesh group by the given conditions
2702 groupName: the name of the mesh group
2703 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2704 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2705 Note that the items starting from FT_LessThan are not suitable for CritType.
2706 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2707 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2708 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2709 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2710 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2713 :class:`SMESH.SMESH_GroupOnFilter`
2716 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2717 group = self.MakeGroupByCriterion(groupName, aCriterion)
2720 def MakeGroupByCriterion(self, groupName, Criterion):
2722 Create a mesh group by the given criterion
2725 groupName: the name of the mesh group
2726 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2729 :class:`SMESH.SMESH_GroupOnFilter`
2732 :meth:`smeshBuilder.GetCriterion`
2735 return self.MakeGroupByCriteria( groupName, [Criterion] )
2737 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2739 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2742 groupName: the name of the mesh group
2743 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2744 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2747 :class:`SMESH.SMESH_GroupOnFilter`
2750 :meth:`smeshBuilder.GetCriterion`
2753 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2754 group = self.MakeGroupByFilter(groupName, aFilter)
2757 def MakeGroupByFilter(self, groupName, theFilter):
2759 Create a mesh group by the given filter
2762 groupName (string): the name of the mesh group
2763 theFilter (SMESH.Filter): the filter
2766 :class:`SMESH.SMESH_GroupOnFilter`
2769 :meth:`smeshBuilder.GetFilter`
2772 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2773 #theFilter.SetMesh( self.mesh )
2774 #group.AddFrom( theFilter )
2775 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2778 def RemoveGroup(self, group):
2783 group (SMESH.SMESH_GroupBase): group to remove
2786 self.mesh.RemoveGroup(group)
2788 def RemoveGroupWithContents(self, group):
2790 Remove a group with its contents
2793 group (SMESH.SMESH_GroupBase): group to remove
2796 This operation can create gaps in numeration of nodes or elements.
2797 Call :meth:`RenumberElements` to remove the gaps.
2800 self.mesh.RemoveGroupWithContents(group)
2802 def GetGroups(self, elemType = SMESH.ALL):
2804 Get the list of groups existing in the mesh in the order of creation
2805 (starting from the oldest one)
2808 elemType (SMESH.ElementType): type of elements the groups contain;
2809 by default groups of elements of all types are returned
2812 a list of :class:`SMESH.SMESH_GroupBase`
2815 groups = self.mesh.GetGroups()
2816 if elemType == SMESH.ALL:
2820 if g.GetType() == elemType:
2821 typedGroups.append( g )
2828 Get the number of groups existing in the mesh
2831 the quantity of groups as an integer value
2834 return self.mesh.NbGroups()
2836 def GetGroupNames(self):
2838 Get the list of names of groups existing in the mesh
2844 groups = self.GetGroups()
2846 for group in groups:
2847 names.append(group.GetName())
2850 def GetGroupByName(self, name, elemType = None):
2852 Find groups by name and type
2855 name (string): name of the group of interest
2856 elemType (SMESH.ElementType): type of elements the groups contain;
2857 by default one group of any type is returned;
2858 if elemType == SMESH.ALL then all groups of any type are returned
2861 a list of :class:`SMESH.SMESH_GroupBase`
2865 for group in self.GetGroups():
2866 if group.GetName() == name:
2867 if elemType is None:
2869 if ( elemType == SMESH.ALL or
2870 group.GetType() == elemType ):
2871 groups.append( group )
2874 def UnionGroups(self, group1, group2, name):
2876 Produce a union of two groups.
2877 A new group is created. All mesh elements that are
2878 present in the initial groups are added to the new one
2881 group1 (SMESH.SMESH_GroupBase): a group
2882 group2 (SMESH.SMESH_GroupBase): another group
2885 instance of :class:`SMESH.SMESH_Group`
2888 return self.mesh.UnionGroups(group1, group2, name)
2890 def UnionListOfGroups(self, groups, name):
2892 Produce a union list of groups.
2893 New group is created. All mesh elements that are present in
2894 initial groups are added to the new one
2897 groups: list of :class:`SMESH.SMESH_GroupBase`
2900 instance of :class:`SMESH.SMESH_Group`
2902 return self.mesh.UnionListOfGroups(groups, name)
2904 def IntersectGroups(self, group1, group2, name):
2906 Prodice an intersection of two groups.
2907 A new group is created. All mesh elements that are common
2908 for the two initial groups are added to the new one.
2911 group1 (SMESH.SMESH_GroupBase): a group
2912 group2 (SMESH.SMESH_GroupBase): another group
2915 instance of :class:`SMESH.SMESH_Group`
2918 return self.mesh.IntersectGroups(group1, group2, name)
2920 def IntersectListOfGroups(self, groups, name):
2922 Produce an intersection of groups.
2923 New group is created. All mesh elements that are present in all
2924 initial groups simultaneously are added to the new one
2927 groups: a list of :class:`SMESH.SMESH_GroupBase`
2930 instance of :class:`SMESH.SMESH_Group`
2932 return self.mesh.IntersectListOfGroups(groups, name)
2934 def CutGroups(self, main_group, tool_group, name):
2936 Produce a cut of two groups.
2937 A new group is created. All mesh elements that are present in
2938 the main group but are not present in the tool group are added to the new one
2941 main_group (SMESH.SMESH_GroupBase): a group to cut from
2942 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2945 an instance of :class:`SMESH.SMESH_Group`
2948 return self.mesh.CutGroups(main_group, tool_group, name)
2950 def CutListOfGroups(self, main_groups, tool_groups, name):
2952 Produce a cut of groups.
2953 A new group is created. All mesh elements that are present in main groups
2954 but do not present in tool groups are added to the new one
2957 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2958 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2961 an instance of :class:`SMESH.SMESH_Group`
2964 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2966 def CreateDimGroup(self, groups, elemType, name,
2967 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2969 Create a standalone group of entities basing on nodes of other groups.
2972 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2973 elemType: a type of elements to include to the new group; either of
2974 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2975 name: a name of the new group.
2976 nbCommonNodes: a criterion of inclusion of an element to the new group
2977 basing on number of element nodes common with reference *groups*.
2978 Meaning of possible values are:
2980 - SMESH.ALL_NODES - include if all nodes are common,
2981 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2982 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2983 - SMEHS.MAJORITY - include if half of nodes or more are common.
2984 underlyingOnly: if *True* (default), an element is included to the
2985 new group provided that it is based on nodes of an element of *groups*;
2986 in this case the reference *groups* are supposed to be of higher dimension
2987 than *elemType*, which can be useful for example to get all faces lying on
2988 volumes of the reference *groups*.
2991 an instance of :class:`SMESH.SMESH_Group`
2994 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2996 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2998 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3000 Distribute all faces of the mesh among groups using sharp edges and optionally
3001 existing 1D elements as group boundaries.
3004 sharpAngle: edge is considered sharp if an angle between normals of
3005 adjacent faces is more than \a sharpAngle in degrees.
3006 createEdges (boolean): to create 1D elements for detected sharp edges.
3007 useExistingEdges (boolean): to use existing edges as group boundaries
3009 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3011 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3012 self.mesh.SetParameters(Parameters)
3013 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3015 def ConvertToStandalone(self, group):
3017 Convert group on geom into standalone group
3020 return self.mesh.ConvertToStandalone(group)
3022 # Get some info about mesh:
3023 # ------------------------
3025 def GetLog(self, clearAfterGet):
3027 Return the log of nodes and elements added or removed
3028 since the previous clear of the log.
3031 clearAfterGet: log is emptied after Get (safe if concurrents access)
3034 list of SMESH.log_block structures { commandType, number, coords, indexes }
3037 return self.mesh.GetLog(clearAfterGet)
3041 Clear the log of nodes and elements added or removed since the previous
3042 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3045 self.mesh.ClearLog()
3047 def SetAutoColor(self, theAutoColor):
3049 Toggle auto color mode on the object.
3050 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3053 theAutoColor (boolean): the flag which toggles auto color mode.
3056 self.mesh.SetAutoColor(theAutoColor)
3058 def GetAutoColor(self):
3060 Get flag of object auto color mode.
3066 return self.mesh.GetAutoColor()
3073 integer value, which is the internal Id of the mesh
3076 return self.mesh.GetId()
3078 def HasDuplicatedGroupNamesMED(self):
3080 Check the group names for duplications.
3081 Consider the maximum group name length stored in MED file.
3087 return self.mesh.HasDuplicatedGroupNamesMED()
3089 def GetMeshEditor(self):
3091 Obtain the mesh editor tool
3094 an instance of :class:`SMESH.SMESH_MeshEditor`
3099 def GetIDSource(self, ids, elemType = SMESH.ALL):
3101 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3102 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3106 elemType: type of elements; this parameter is used to distinguish
3107 IDs of nodes from IDs of elements; by default ids are treated as
3108 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3111 an instance of :class:`SMESH.SMESH_IDSource`
3114 call UnRegister() for the returned object as soon as it is no more useful::
3116 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3117 mesh.DoSomething( idSrc )
3121 if isinstance( ids, int ):
3123 return self.editor.MakeIDSource(ids, elemType)
3126 # Get information about mesh contents:
3127 # ------------------------------------
3129 def GetMeshInfo(self, obj = None):
3131 Get the mesh statistic.
3134 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3137 if not obj: obj = self.mesh
3138 return self.smeshpyD.GetMeshInfo(obj)
3142 Return the number of nodes in the mesh
3148 return self.mesh.NbNodes()
3150 def NbElements(self):
3152 Return the number of elements in the mesh
3158 return self.mesh.NbElements()
3160 def Nb0DElements(self):
3162 Return the number of 0d elements in the mesh
3168 return self.mesh.Nb0DElements()
3172 Return the number of ball discrete elements in the mesh
3178 return self.mesh.NbBalls()
3182 Return the number of edges in the mesh
3188 return self.mesh.NbEdges()
3190 def NbEdgesOfOrder(self, elementOrder):
3192 Return the number of edges with the given order in the mesh
3195 elementOrder: the order of elements
3196 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3202 return self.mesh.NbEdgesOfOrder(elementOrder)
3206 Return the number of faces in the mesh
3212 return self.mesh.NbFaces()
3214 def NbFacesOfOrder(self, elementOrder):
3216 Return the number of faces with the given order in the mesh
3219 elementOrder: the order of elements
3220 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3226 return self.mesh.NbFacesOfOrder(elementOrder)
3228 def NbTriangles(self):
3230 Return the number of triangles in the mesh
3236 return self.mesh.NbTriangles()
3238 def NbTrianglesOfOrder(self, elementOrder):
3240 Return the number of triangles with the given order in the mesh
3243 elementOrder: is the order of elements
3244 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3250 return self.mesh.NbTrianglesOfOrder(elementOrder)
3252 def NbBiQuadTriangles(self):
3254 Return the number of biquadratic triangles in the mesh
3260 return self.mesh.NbBiQuadTriangles()
3262 def NbQuadrangles(self):
3264 Return the number of quadrangles in the mesh
3270 return self.mesh.NbQuadrangles()
3272 def NbQuadranglesOfOrder(self, elementOrder):
3274 Return the number of quadrangles with the given order in the mesh
3277 elementOrder: the order of elements
3278 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3284 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3286 def NbBiQuadQuadrangles(self):
3288 Return the number of biquadratic quadrangles in the mesh
3294 return self.mesh.NbBiQuadQuadrangles()
3296 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3298 Return the number of polygons of given order in the mesh
3301 elementOrder: the order of elements
3302 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3308 return self.mesh.NbPolygonsOfOrder(elementOrder)
3310 def NbVolumes(self):
3312 Return the number of volumes in the mesh
3318 return self.mesh.NbVolumes()
3321 def NbVolumesOfOrder(self, elementOrder):
3323 Return the number of volumes with the given order in the mesh
3326 elementOrder: the order of elements
3327 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3333 return self.mesh.NbVolumesOfOrder(elementOrder)
3337 Return the number of tetrahedrons in the mesh
3343 return self.mesh.NbTetras()
3345 def NbTetrasOfOrder(self, elementOrder):
3347 Return the number of tetrahedrons with the given order in the mesh
3350 elementOrder: the order of elements
3351 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3357 return self.mesh.NbTetrasOfOrder(elementOrder)
3361 Return the number of hexahedrons in the mesh
3367 return self.mesh.NbHexas()
3369 def NbHexasOfOrder(self, elementOrder):
3371 Return the number of hexahedrons with the given order in the mesh
3374 elementOrder: the order of elements
3375 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3381 return self.mesh.NbHexasOfOrder(elementOrder)
3383 def NbTriQuadraticHexas(self):
3385 Return the number of triquadratic hexahedrons in the mesh
3391 return self.mesh.NbTriQuadraticHexas()
3393 def NbPyramids(self):
3395 Return the number of pyramids in the mesh
3401 return self.mesh.NbPyramids()
3403 def NbPyramidsOfOrder(self, elementOrder):
3405 Return the number of pyramids with the given order in the mesh
3408 elementOrder: the order of elements
3409 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3415 return self.mesh.NbPyramidsOfOrder(elementOrder)
3419 Return the number of prisms in the mesh
3425 return self.mesh.NbPrisms()
3427 def NbPrismsOfOrder(self, elementOrder):
3429 Return the number of prisms with the given order in the mesh
3432 elementOrder: the order of elements
3433 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3439 return self.mesh.NbPrismsOfOrder(elementOrder)
3441 def NbHexagonalPrisms(self):
3443 Return the number of hexagonal prisms in the mesh
3449 return self.mesh.NbHexagonalPrisms()
3451 def NbPolyhedrons(self):
3453 Return the number of polyhedrons in the mesh
3459 return self.mesh.NbPolyhedrons()
3461 def NbSubMesh(self):
3463 Return the number of submeshes in the mesh
3469 return self.mesh.NbSubMesh()
3471 def GetElementsId(self):
3473 Return the list of all mesh elements IDs
3476 the list of integer values
3479 :meth:`GetElementsByType`
3482 return self.mesh.GetElementsId()
3484 def GetElementsByType(self, elementType):
3486 Return the list of IDs of mesh elements with the given type
3489 elementType (SMESH.ElementType): the required type of elements
3492 list of integer values
3495 return self.mesh.GetElementsByType(elementType)
3497 def GetNodesId(self):
3499 Return the list of mesh nodes IDs
3502 the list of integer values
3505 return self.mesh.GetNodesId()
3507 # Get the information about mesh elements:
3508 # ------------------------------------
3510 def GetElementType(self, id, iselem=True):
3512 Return the type of mesh element or node
3515 the value from :class:`SMESH.ElementType` enumeration.
3516 Return SMESH.ALL if element or node with the given ID does not exist
3519 return self.mesh.GetElementType(id, iselem)
3521 def GetElementGeomType(self, id):
3523 Return the geometric type of mesh element
3526 the value from :class:`SMESH.EntityType` enumeration.
3529 return self.mesh.GetElementGeomType(id)
3531 def GetElementShape(self, id):
3533 Return the shape type of mesh element
3536 the value from :class:`SMESH.GeometryType` enumeration.
3539 return self.mesh.GetElementShape(id)
3541 def GetSubMeshElementsId(self, Shape):
3543 Return the list of sub-mesh elements IDs
3546 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3547 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3550 list of integer values
3553 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3554 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3557 return self.mesh.GetSubMeshElementsId(ShapeID)
3559 def GetSubMeshNodesId(self, Shape, all):
3561 Return the list of sub-mesh nodes IDs
3564 Shape: a geom object (sub-shape).
3565 *Shape* must be the sub-shape of a :meth:`GetShape`
3566 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3569 list of integer values
3572 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3573 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3576 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3578 def GetSubMeshElementType(self, Shape):
3580 Return type of elements on given shape
3583 Shape: a geom object (sub-shape).
3584 *Shape* must be a sub-shape of a ShapeToMesh()
3587 :class:`SMESH.ElementType`
3590 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3591 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3594 return self.mesh.GetSubMeshElementType(ShapeID)
3598 Get the mesh description
3604 return self.mesh.Dump()
3607 # Get the information about nodes and elements of a mesh by its IDs:
3608 # -----------------------------------------------------------
3610 def GetNodeXYZ(self, id):
3612 Get XYZ coordinates of a node.
3613 If there is no node for the given ID - return an empty list
3616 list of float values
3619 return self.mesh.GetNodeXYZ(id)
3621 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3623 Return list of IDs of inverse elements for the given node.
3624 If there is no node for the given ID - return an empty list
3628 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3631 list of integer values
3634 return self.mesh.GetNodeInverseElements(id,elemType)
3636 def GetNodePosition(self,NodeID):
3638 Return the position of a node on the shape
3641 :class:`SMESH.NodePosition`
3644 return self.mesh.GetNodePosition(NodeID)
3646 def GetElementPosition(self,ElemID):
3648 Return the position of an element on the shape
3651 :class:`SMESH.ElementPosition`
3654 return self.mesh.GetElementPosition(ElemID)
3656 def GetShapeID(self, id):
3658 Return the ID of the shape, on which the given node was generated.
3661 an integer value > 0 or -1 if there is no node for the given
3662 ID or the node is not assigned to any geometry
3665 return self.mesh.GetShapeID(id)
3667 def GetShapeIDForElem(self,id):
3669 Return the ID of the shape, on which the given element was generated.
3672 an integer value > 0 or -1 if there is no element for the given
3673 ID or the element is not assigned to any geometry
3676 return self.mesh.GetShapeIDForElem(id)
3678 def GetElemNbNodes(self, id):
3680 Return the number of nodes of the given element
3683 an integer value > 0 or -1 if there is no element for the given ID
3686 return self.mesh.GetElemNbNodes(id)
3688 def GetElemNode(self, id, index):
3690 Return the node ID the given (zero based) index for the given element.
3692 * If there is no element for the given ID - return -1.
3693 * If there is no node for the given index - return -2.
3696 id (int): element ID
3697 index (int): node index within the element
3700 an integer value (ID)
3703 :meth:`GetElemNodes`
3706 return self.mesh.GetElemNode(id, index)
3708 def GetElemNodes(self, id):
3710 Return the IDs of nodes of the given element
3713 a list of integer values
3716 return self.mesh.GetElemNodes(id)
3718 def IsMediumNode(self, elementID, nodeID):
3720 Return true if the given node is the medium node in the given quadratic element
3723 return self.mesh.IsMediumNode(elementID, nodeID)
3725 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3727 Return true if the given node is the medium node in one of quadratic elements
3730 nodeID: ID of the node
3731 elementType: the type of elements to check a state of the node, either of
3732 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3735 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3737 def ElemNbEdges(self, id):
3739 Return the number of edges for the given element
3742 return self.mesh.ElemNbEdges(id)
3744 def ElemNbFaces(self, id):
3746 Return the number of faces for the given element
3749 return self.mesh.ElemNbFaces(id)
3751 def GetElemFaceNodes(self,elemId, faceIndex):
3753 Return nodes of given face (counted from zero) for given volumic element.
3756 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3758 def GetFaceNormal(self, faceId, normalized=False):
3760 Return three components of normal of given mesh face
3761 (or an empty array in KO case)
3764 return self.mesh.GetFaceNormal(faceId,normalized)
3766 def FindElementByNodes(self, nodes):
3768 Return an element based on all given nodes.
3771 return self.mesh.FindElementByNodes(nodes)
3773 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3775 Return elements including all given nodes.
3778 return self.mesh.GetElementsByNodes( nodes, elemType )
3780 def IsPoly(self, id):
3782 Return true if the given element is a polygon
3785 return self.mesh.IsPoly(id)
3787 def IsQuadratic(self, id):
3789 Return true if the given element is quadratic
3792 return self.mesh.IsQuadratic(id)
3794 def GetBallDiameter(self, id):
3796 Return diameter of a ball discrete element or zero in case of an invalid *id*
3799 return self.mesh.GetBallDiameter(id)
3801 def BaryCenter(self, id):
3803 Return XYZ coordinates of the barycenter of the given element.
3804 If there is no element for the given ID - return an empty list
3807 a list of three double values
3810 :meth:`smeshBuilder.GetGravityCenter`
3813 return self.mesh.BaryCenter(id)
3815 def GetIdsFromFilter(self, filter, meshParts=[] ):
3817 Pass mesh elements through the given filter and return IDs of fitting elements
3820 filter: :class:`SMESH.Filter`
3821 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3827 :meth:`SMESH.Filter.GetIDs`
3828 :meth:`SMESH.Filter.GetElementsIdFromParts`
3831 filter.SetMesh( self.mesh )
3834 if isinstance( meshParts, Mesh ):
3835 filter.SetMesh( meshParts.GetMesh() )
3836 return theFilter.GetIDs()
3837 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3838 meshParts = [ meshParts ]
3839 return filter.GetElementsIdFromParts( meshParts )
3841 return filter.GetIDs()
3843 # Get mesh measurements information:
3844 # ------------------------------------
3846 def GetFreeBorders(self):
3848 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3849 Return a list of special structures (borders).
3852 a list of :class:`SMESH.FreeEdges.Border`
3855 aFilterMgr = self.smeshpyD.CreateFilterManager()
3856 aPredicate = aFilterMgr.CreateFreeEdges()
3857 aPredicate.SetMesh(self.mesh)
3858 aBorders = aPredicate.GetBorders()
3859 aFilterMgr.UnRegister()
3862 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3864 Get minimum distance between two nodes, elements or distance to the origin
3867 id1: first node/element id
3868 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3869 isElem1: *True* if *id1* is element id, *False* if it is node id
3870 isElem2: *True* if *id2* is element id, *False* if it is node id
3873 minimum distance value
3875 :meth:`GetMinDistance`
3878 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3879 return aMeasure.value
3881 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3883 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3886 id1: first node/element id
3887 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3888 isElem1: *True* if *id1* is element id, *False* if it is node id
3889 isElem2: *True* if *id2* is element id, *False* if it is node id
3892 :class:`SMESH.Measure` structure
3898 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3900 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3903 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3905 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3910 aMeasurements = self.smeshpyD.CreateMeasurements()
3911 aMeasure = aMeasurements.MinDistance(id1, id2)
3912 genObjUnRegister([aMeasurements,id1, id2])
3915 def BoundingBox(self, objects=None, isElem=False):
3917 Get bounding box of the specified object(s)
3920 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3921 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3922 *False* specifies that *objects* are nodes
3925 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3928 :meth:`GetBoundingBox()`
3931 result = self.GetBoundingBox(objects, isElem)
3935 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3938 def GetBoundingBox(self, objects=None, isElem=False):
3940 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3943 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3944 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3945 False means that *objects* are nodes
3948 :class:`SMESH.Measure` structure
3951 :meth:`BoundingBox()`
3955 objects = [self.mesh]
3956 elif isinstance(objects, tuple):
3957 objects = list(objects)
3958 if not isinstance(objects, list):
3960 if len(objects) > 0 and isinstance(objects[0], int):
3963 unRegister = genObjUnRegister()
3965 if isinstance(o, Mesh):
3966 srclist.append(o.mesh)
3967 elif hasattr(o, "_narrow"):
3968 src = o._narrow(SMESH.SMESH_IDSource)
3969 if src: srclist.append(src)
3971 elif isinstance(o, list):
3973 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3975 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3976 unRegister.set( srclist[-1] )
3979 aMeasurements = self.smeshpyD.CreateMeasurements()
3980 unRegister.set( aMeasurements )
3981 aMeasure = aMeasurements.BoundingBox(srclist)
3984 # Mesh edition (SMESH_MeshEditor functionality):
3985 # ---------------------------------------------
3987 def RemoveElements(self, IDsOfElements):
3989 Remove the elements from the mesh by ids
3992 IDsOfElements: is a list of ids of elements to remove
3998 This operation can create gaps in numeration of elements.
3999 Call :meth:`RenumberElements` to remove the gaps.
4002 return self.editor.RemoveElements(IDsOfElements)
4004 def RemoveNodes(self, IDsOfNodes):
4006 Remove nodes from mesh by ids
4009 IDsOfNodes: is a list of ids of nodes to remove
4015 This operation can create gaps in numeration of nodes.
4016 Call :meth:`RenumberElements` to remove the gaps.
4019 return self.editor.RemoveNodes(IDsOfNodes)
4021 def RemoveOrphanNodes(self):
4023 Remove all orphan (free) nodes from mesh
4026 number of the removed nodes
4029 This operation can create gaps in numeration of nodes.
4030 Call :meth:`RenumberElements` to remove the gaps.
4033 return self.editor.RemoveOrphanNodes()
4035 def AddNode(self, x, y, z):
4037 Add a node to the mesh by coordinates
4043 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4044 if hasVars: self.mesh.SetParameters(Parameters)
4045 return self.editor.AddNode( x, y, z)
4047 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4049 Create a 0D element on a node with given number.
4052 IDOfNode: the ID of node for creation of the element.
4053 DuplicateElements: to add one more 0D element to a node or not
4056 ID of the new 0D element
4059 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4061 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4063 Create 0D elements on all nodes of the given elements except those
4064 nodes on which a 0D element already exists.
4067 theObject: an object on whose nodes 0D elements will be created.
4068 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4069 theGroupName: optional name of a group to add 0D elements created
4070 and/or found on nodes of *theObject*.
4071 DuplicateElements: to add one more 0D element to a node or not
4074 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4075 IDs of new and/or found 0D elements. IDs of 0D elements
4076 can be retrieved from the returned object by
4077 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4080 unRegister = genObjUnRegister()
4081 if isinstance( theObject, Mesh ):
4082 theObject = theObject.GetMesh()
4083 elif isinstance( theObject, list ):
4084 theObject = self.GetIDSource( theObject, SMESH.ALL )
4085 unRegister.set( theObject )
4086 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4088 def AddBall(self, IDOfNode, diameter):
4090 Create a ball element on a node with given ID.
4093 IDOfNode: the ID of node for creation of the element.
4094 diameter: the bal diameter.
4097 ID of the new ball element
4100 return self.editor.AddBall( IDOfNode, diameter )
4102 def AddEdge(self, IDsOfNodes):
4104 Create a linear or quadratic edge (this is determined
4105 by the number of given nodes).
4108 IDsOfNodes: list of node IDs for creation of the element.
4109 The order of nodes in this list should correspond to
4110 the :ref:`connectivity convention <connectivity_page>`.
4116 return self.editor.AddEdge(IDsOfNodes)
4118 def AddFace(self, IDsOfNodes):
4120 Create a linear or quadratic face (this is determined
4121 by the number of given nodes).
4124 IDsOfNodes: list of node IDs for creation of the element.
4125 The order of nodes in this list should correspond to
4126 the :ref:`connectivity convention <connectivity_page>`.
4132 return self.editor.AddFace(IDsOfNodes)
4134 def AddPolygonalFace(self, IdsOfNodes):
4136 Add a polygonal face defined by a list of node IDs
4139 IdsOfNodes: the list of node IDs for creation of the element.
4145 return self.editor.AddPolygonalFace(IdsOfNodes)
4147 def AddQuadPolygonalFace(self, IdsOfNodes):
4149 Add a quadratic polygonal face defined by a list of node IDs
4152 IdsOfNodes: the list of node IDs for creation of the element;
4153 corner nodes follow first.
4159 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4161 def AddVolume(self, IDsOfNodes):
4163 Create both simple and quadratic volume (this is determined
4164 by the number of given nodes).
4167 IDsOfNodes: list of node IDs for creation of the element.
4168 The order of nodes in this list should correspond to
4169 the :ref:`connectivity convention <connectivity_page>`.
4172 ID of the new volumic element
4175 return self.editor.AddVolume(IDsOfNodes)
4177 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4179 Create a volume of many faces, giving nodes for each face.
4182 IdsOfNodes: list of node IDs for volume creation, face by face.
4183 Quantities: list of integer values, Quantities[i]
4184 gives the quantity of nodes in face number i.
4187 ID of the new volumic element
4190 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4192 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4194 Create a volume of many faces, giving the IDs of the existing faces.
4197 The created volume will refer only to the nodes
4198 of the given faces, not to the faces themselves.
4201 IdsOfFaces: the list of face IDs for volume creation.
4204 ID of the new volumic element
4207 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4210 def SetNodeOnVertex(self, NodeID, Vertex):
4212 Bind a node to a vertex
4216 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4219 True if succeed else raises an exception
4222 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4223 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4227 self.editor.SetNodeOnVertex(NodeID, VertexID)
4228 except SALOME.SALOME_Exception as inst:
4229 raise ValueError(inst.details.text)
4233 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4235 Store the node position on an edge
4239 Edge: an edge (GEOM.GEOM_Object) or edge ID
4240 paramOnEdge: a parameter on the edge where the node is located
4243 True if succeed else raises an exception
4246 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4247 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4251 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4252 except SALOME.SALOME_Exception as inst:
4253 raise ValueError(inst.details.text)
4256 def SetNodeOnFace(self, NodeID, Face, u, v):
4258 Store node position on a face
4262 Face: a face (GEOM.GEOM_Object) or face ID
4263 u: U parameter on the face where the node is located
4264 v: V parameter on the face where the node is located
4267 True if succeed else raises an exception
4270 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4271 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4275 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4276 except SALOME.SALOME_Exception as inst:
4277 raise ValueError(inst.details.text)
4280 def SetNodeInVolume(self, NodeID, Solid):
4282 Bind a node to a solid
4286 Solid: a solid (GEOM.GEOM_Object) or solid ID
4289 True if succeed else raises an exception
4292 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4293 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4297 self.editor.SetNodeInVolume(NodeID, SolidID)
4298 except SALOME.SALOME_Exception as inst:
4299 raise ValueError(inst.details.text)
4302 def SetMeshElementOnShape(self, ElementID, Shape):
4304 Bind an element to a shape
4307 ElementID: an element ID
4308 Shape: a shape (GEOM.GEOM_Object) or shape ID
4311 True if succeed else raises an exception
4314 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4315 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4319 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4320 except SALOME.SALOME_Exception as inst:
4321 raise ValueError(inst.details.text)
4325 def MoveNode(self, NodeID, x, y, z):
4327 Move the node with the given id
4330 NodeID: the id of the node
4331 x: a new X coordinate
4332 y: a new Y coordinate
4333 z: a new Z coordinate
4336 True if succeed else False
4339 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4340 if hasVars: self.mesh.SetParameters(Parameters)
4341 return self.editor.MoveNode(NodeID, x, y, z)
4343 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4345 Find the node closest to a point and moves it to a point location
4348 x: the X coordinate of a point
4349 y: the Y coordinate of a point
4350 z: the Z coordinate of a point
4351 NodeID: if specified (>0), the node with this ID is moved,
4352 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4355 the ID of a moved node
4358 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4359 if hasVars: self.mesh.SetParameters(Parameters)
4360 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4362 def FindNodeClosestTo(self, x, y, z):
4364 Find the node closest to a point
4367 x: the X coordinate of a point
4368 y: the Y coordinate of a point
4369 z: the Z coordinate of a point
4375 return self.editor.FindNodeClosestTo(x, y, z)
4377 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4379 Find the elements where a point lays IN or ON
4382 x,y,z (float): coordinates of the point
4383 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4384 means elements of any type excluding nodes, discrete and 0D elements.
4385 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4388 list of IDs of found elements
4391 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4393 return self.editor.FindElementsByPoint(x, y, z, elementType)
4395 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4397 Project a point to a mesh object.
4398 Return ID of an element of given type where the given point is projected
4399 and coordinates of the projection point.
4400 In the case if nothing found, return -1 and []
4402 if isinstance( meshObject, Mesh ):
4403 meshObject = meshObject.GetMesh()
4405 meshObject = self.GetMesh()
4406 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4408 def GetPointState(self, x, y, z):
4410 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4411 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4412 UNKNOWN state means that either mesh is wrong or the analysis fails.
4415 return self.editor.GetPointState(x, y, z)
4417 def IsManifold(self):
4419 Check if a 2D mesh is manifold
4422 return self.editor.IsManifold()
4424 def IsCoherentOrientation2D(self):
4426 Check if orientation of 2D elements is coherent
4429 return self.editor.IsCoherentOrientation2D()
4431 def Get1DBranches( self, edges, startNode = 0 ):
4433 Partition given 1D elements into groups of contiguous edges.
4434 A node where number of meeting edges != 2 is a group end.
4435 An optional startNode is used to orient groups it belongs to.
4438 A list of edge groups and a list of corresponding node groups,
4439 where the group is a list of IDs of edges or elements, like follows
4440 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4441 If a group is closed, the first and last nodes of the group are same.
4443 if isinstance( edges, Mesh ):
4444 edges = edges.GetMesh()
4445 unRegister = genObjUnRegister()
4446 if isinstance( edges, list ):
4447 edges = self.GetIDSource( edges, SMESH.EDGE )
4448 unRegister.set( edges )
4449 return self.editor.Get1DBranches( edges, startNode )
4451 def FindSharpEdges( self, angle, addExisting=False ):
4453 Return sharp edges of faces and non-manifold ones.
4454 Optionally add existing edges.
4457 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4458 addExisting: to return existing edges (1D elements) as well
4461 list of FaceEdge structures
4463 angle = ParseParameters( angle )[0]
4464 return self.editor.FindSharpEdges( angle, addExisting )
4466 def MeshToPassThroughAPoint(self, x, y, z):
4468 Find the node closest to a point and moves it to a point location
4471 x: the X coordinate of a point
4472 y: the Y coordinate of a point
4473 z: the Z coordinate of a point
4476 the ID of a moved node
4479 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4481 def InverseDiag(self, NodeID1, NodeID2):
4483 Replace two neighbour triangles sharing Node1-Node2 link
4484 with the triangles built on the same 4 nodes but having other common link.
4487 NodeID1: the ID of the first node
4488 NodeID2: the ID of the second node
4491 False if proper faces were not found
4493 return self.editor.InverseDiag(NodeID1, NodeID2)
4495 def DeleteDiag(self, NodeID1, NodeID2):
4497 Replace two neighbour triangles sharing *Node1-Node2* link
4498 with a quadrangle built on the same 4 nodes.
4501 NodeID1: ID of the first node
4502 NodeID2: ID of the second node
4505 False if proper faces were not found
4508 This operation can create gaps in numeration of elements.
4509 Call :meth:`RenumberElements` to remove the gaps.
4512 return self.editor.DeleteDiag(NodeID1, NodeID2)
4514 def Reorient(self, IDsOfElements=None):
4516 Reorient elements by ids
4519 IDsOfElements: if undefined reorients all mesh elements
4522 True if succeed else False
4525 if IDsOfElements == None:
4526 IDsOfElements = self.GetElementsId()
4527 return self.editor.Reorient(IDsOfElements)
4529 def ReorientObject(self, theObject):
4531 Reorient all elements of the object
4534 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4537 True if succeed else False
4540 if ( isinstance( theObject, Mesh )):
4541 theObject = theObject.GetMesh()
4542 return self.editor.ReorientObject(theObject)
4544 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4546 Reorient faces contained in *the2DObject*.
4549 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4550 theDirection: a desired direction of normal of *theFace*.
4551 It can be either a GEOM vector or a list of coordinates [x,y,z].
4552 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4553 compared with theDirection. It can be either ID of face or a point
4554 by which the face will be found. The point can be given as either
4555 a GEOM vertex or a list of point coordinates.
4558 number of reoriented faces
4561 unRegister = genObjUnRegister()
4563 if isinstance( the2DObject, Mesh ):
4564 the2DObject = the2DObject.GetMesh()
4565 if isinstance( the2DObject, list ):
4566 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4567 unRegister.set( the2DObject )
4568 # check theDirection
4569 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4570 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4571 if isinstance( theDirection, list ):
4572 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4573 # prepare theFace and thePoint
4574 theFace = theFaceOrPoint
4575 thePoint = PointStruct(0,0,0)
4576 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4577 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4579 if isinstance( theFaceOrPoint, list ):
4580 thePoint = PointStruct( *theFaceOrPoint )
4582 if isinstance( theFaceOrPoint, PointStruct ):
4583 thePoint = theFaceOrPoint
4585 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4587 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4589 Reorient faces according to adjacent volumes.
4592 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4593 either IDs of faces or face groups.
4594 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4595 theOutsideNormal: to orient faces to have their normals
4596 pointing either *outside* or *inside* the adjacent volumes.
4599 number of reoriented faces.
4602 unRegister = genObjUnRegister()
4604 if not isinstance( the2DObject, list ):
4605 the2DObject = [ the2DObject ]
4606 elif the2DObject and isinstance( the2DObject[0], int ):
4607 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4608 unRegister.set( the2DObject )
4609 the2DObject = [ the2DObject ]
4610 for i,obj2D in enumerate( the2DObject ):
4611 if isinstance( obj2D, Mesh ):
4612 the2DObject[i] = obj2D.GetMesh()
4613 if isinstance( obj2D, list ):
4614 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4615 unRegister.set( the2DObject[i] )
4617 if isinstance( the3DObject, Mesh ):
4618 the3DObject = the3DObject.GetMesh()
4619 if isinstance( the3DObject, list ):
4620 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4621 unRegister.set( the3DObject )
4622 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4624 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4626 Fuse the neighbouring triangles into quadrangles.
4629 IDsOfElements: The triangles to be fused.
4630 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4631 applied to possible quadrangles to choose a neighbour to fuse with.
4632 Note that not all items of :class:`SMESH.FunctorType` corresponds
4633 to numerical functors.
4634 MaxAngle: is the maximum angle between element normals at which the fusion
4635 is still performed; theMaxAngle is measured in radians.
4636 Also it could be a name of variable which defines angle in degrees.
4639 True in case of success, False otherwise.
4642 This operation can create gaps in numeration of elements.
4643 Call :meth:`RenumberElements` to remove the gaps.
4646 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4647 self.mesh.SetParameters(Parameters)
4648 if not IDsOfElements:
4649 IDsOfElements = self.GetElementsId()
4650 Functor = self.smeshpyD.GetFunctor(theCriterion)
4651 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4653 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4655 Fuse the neighbouring triangles of the object into quadrangles
4658 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4659 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4660 applied to possible quadrangles to choose a neighbour to fuse with.
4661 Note that not all items of :class:`SMESH.FunctorType` corresponds
4662 to numerical functors.
4663 MaxAngle: a max angle between element normals at which the fusion
4664 is still performed; theMaxAngle is measured in radians.
4667 True in case of success, False otherwise.
4670 This operation can create gaps in numeration of elements.
4671 Call :meth:`RenumberElements` to remove the gaps.
4674 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4675 self.mesh.SetParameters(Parameters)
4676 if isinstance( theObject, Mesh ):
4677 theObject = theObject.GetMesh()
4678 Functor = self.smeshpyD.GetFunctor(theCriterion)
4679 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4681 def QuadToTri (self, IDsOfElements, theCriterion = None):
4683 Split quadrangles into triangles.
4686 IDsOfElements: the faces to be splitted.
4687 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4688 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4689 value, then quadrangles will be split by the smallest diagonal.
4690 Note that not all items of :class:`SMESH.FunctorType` corresponds
4691 to numerical functors.
4694 True in case of success, False otherwise.
4697 This operation can create gaps in numeration of elements.
4698 Call :meth:`RenumberElements` to remove the gaps.
4700 if IDsOfElements == []:
4701 IDsOfElements = self.GetElementsId()
4702 if theCriterion is None:
4703 theCriterion = FT_MaxElementLength2D
4704 Functor = self.smeshpyD.GetFunctor(theCriterion)
4705 return self.editor.QuadToTri(IDsOfElements, Functor)
4707 def QuadToTriObject (self, theObject, theCriterion = None):
4709 Split quadrangles into triangles.
4712 theObject: the object from which the list of elements is taken,
4713 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4714 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4715 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4716 value, then quadrangles will be split by the smallest diagonal.
4717 Note that not all items of :class:`SMESH.FunctorType` corresponds
4718 to numerical functors.
4721 True in case of success, False otherwise.
4724 This operation can create gaps in numeration of elements.
4725 Call :meth:`RenumberElements` to remove the gaps.
4727 if ( isinstance( theObject, Mesh )):
4728 theObject = theObject.GetMesh()
4729 if theCriterion is None:
4730 theCriterion = FT_MaxElementLength2D
4731 Functor = self.smeshpyD.GetFunctor(theCriterion)
4732 return self.editor.QuadToTriObject(theObject, Functor)
4734 def QuadTo4Tri (self, theElements=[]):
4736 Split each of given quadrangles into 4 triangles. A node is added at the center of
4740 theElements: the faces to be splitted. This can be either
4741 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4742 or a list of face IDs. By default all quadrangles are split
4745 This operation can create gaps in numeration of elements.
4746 Call :meth:`RenumberElements` to remove the gaps.
4748 unRegister = genObjUnRegister()
4749 if isinstance( theElements, Mesh ):
4750 theElements = theElements.mesh
4751 elif not theElements:
4752 theElements = self.mesh
4753 elif isinstance( theElements, list ):
4754 theElements = self.GetIDSource( theElements, SMESH.FACE )
4755 unRegister.set( theElements )
4756 return self.editor.QuadTo4Tri( theElements )
4758 def SplitQuad (self, IDsOfElements, Diag13):
4760 Split quadrangles into triangles.
4763 IDsOfElements: the faces to be splitted
4764 Diag13 (boolean): is used to choose a diagonal for splitting.
4767 True in case of success, False otherwise.
4770 This operation can create gaps in numeration of elements.
4771 Call :meth:`RenumberElements` to remove the gaps.
4773 if IDsOfElements == []:
4774 IDsOfElements = self.GetElementsId()
4775 return self.editor.SplitQuad(IDsOfElements, Diag13)
4777 def SplitQuadObject (self, theObject, Diag13):
4779 Split quadrangles into triangles.
4782 theObject: the object from which the list of elements is taken,
4783 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4784 Diag13 (boolean): is used to choose a diagonal for splitting.
4787 True in case of success, False otherwise.
4790 This operation can create gaps in numeration of elements.
4791 Call :meth:`RenumberElements` to remove the gaps.
4793 if ( isinstance( theObject, Mesh )):
4794 theObject = theObject.GetMesh()
4795 return self.editor.SplitQuadObject(theObject, Diag13)
4797 def BestSplit (self, IDOfQuad, theCriterion):
4799 Find a better splitting of the given quadrangle.
4802 IDOfQuad: the ID of the quadrangle to be splitted.
4803 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4804 choose a diagonal for splitting.
4805 Note that not all items of :class:`SMESH.FunctorType` corresponds
4806 to numerical functors.
4809 * 1 if 1-3 diagonal is better,
4810 * 2 if 2-4 diagonal is better,
4811 * 0 if error occurs.
4814 This operation can create gaps in numeration of elements.
4815 Call :meth:`RenumberElements` to remove the gaps.
4817 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4819 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4821 Split volumic elements into tetrahedrons
4824 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4825 method: flags passing splitting method:
4826 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4827 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4830 This operation can create gaps in numeration of elements.
4831 Call :meth:`RenumberElements` to remove the gaps.
4833 unRegister = genObjUnRegister()
4834 if isinstance( elems, Mesh ):
4835 elems = elems.GetMesh()
4836 if ( isinstance( elems, list )):
4837 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4838 unRegister.set( elems )
4839 self.editor.SplitVolumesIntoTetra(elems, method)
4842 def SplitBiQuadraticIntoLinear(self, elems=None):
4844 Split bi-quadratic elements into linear ones without creation of additional nodes:
4846 - bi-quadratic triangle will be split into 3 linear quadrangles;
4847 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4848 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4850 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4851 will be split in order to keep the mesh conformal.
4854 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4855 if None (default), all bi-quadratic elements will be split
4858 This operation can create gaps in numeration of elements.
4859 Call :meth:`RenumberElements` to remove the gaps.
4861 unRegister = genObjUnRegister()
4862 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4863 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4864 unRegister.set( elems )
4866 elems = [ self.GetMesh() ]
4867 if isinstance( elems, Mesh ):
4868 elems = [ elems.GetMesh() ]
4869 if not isinstance( elems, list ):
4871 self.editor.SplitBiQuadraticIntoLinear( elems )
4873 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4874 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4876 Split hexahedra into prisms
4879 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4880 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4881 gives a normal vector defining facets to split into triangles.
4882 *startHexPoint* can be either a triple of coordinates or a vertex.
4883 facetNormal: a normal to a facet to split into triangles of a
4884 hexahedron found by *startHexPoint*.
4885 *facetNormal* can be either a triple of coordinates or an edge.
4886 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4887 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4888 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4889 to *startHexPoint* are split, else *startHexPoint*
4890 is used to find the facet to split in all domains present in *elems*.
4893 This operation can create gaps in numeration of elements.
4894 Call :meth:`RenumberElements` to remove the gaps.
4897 unRegister = genObjUnRegister()
4898 if isinstance( elems, Mesh ):
4899 elems = elems.GetMesh()
4900 if ( isinstance( elems, list )):
4901 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4902 unRegister.set( elems )
4905 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4906 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4907 elif isinstance( startHexPoint, list ):
4908 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4911 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4912 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4913 elif isinstance( facetNormal, list ):
4914 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4917 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4919 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4921 def SplitQuadsNearTriangularFacets(self):
4923 Split quadrangle faces near triangular facets of volumes
4926 This operation can create gaps in numeration of elements.
4927 Call :meth:`RenumberElements` to remove the gaps.
4929 faces_array = self.GetElementsByType(SMESH.FACE)
4930 for face_id in faces_array:
4931 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4932 quad_nodes = self.mesh.GetElemNodes(face_id)
4933 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4934 isVolumeFound = False
4935 for node1_elem in node1_elems:
4936 if not isVolumeFound:
4937 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4938 nb_nodes = self.GetElemNbNodes(node1_elem)
4939 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4940 volume_elem = node1_elem
4941 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4942 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4943 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4944 isVolumeFound = True
4945 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4946 self.SplitQuad([face_id], False) # diagonal 2-4
4947 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4948 isVolumeFound = True
4949 self.SplitQuad([face_id], True) # diagonal 1-3
4950 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4951 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4952 isVolumeFound = True
4953 self.SplitQuad([face_id], True) # diagonal 1-3
4955 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4957 Split hexahedrons into tetrahedrons.
4959 This operation uses :doc:`pattern_mapping` functionality for splitting.
4962 theObject: the object from which the list of hexahedrons is taken;
4963 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4964 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4965 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4966 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4967 key-point will be mapped into *theNode001*-th node of each volume.
4968 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4971 True in case of success, False otherwise.
4974 This operation can create gaps in numeration of elements.
4975 Call :meth:`RenumberElements` to remove the gaps.
4983 # (0,0,1) 4.---------.7 * |
4990 # (0,0,0) 0.---------.3
4991 pattern_tetra = "!!! Nb of points: \n 8 \n\
5001 !!! Indices of points of 6 tetras: \n\
5009 pattern = self.smeshpyD.GetPattern()
5010 isDone = pattern.LoadFromFile(pattern_tetra)
5012 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5015 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5016 isDone = pattern.MakeMesh(self.mesh, False, False)
5017 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5019 # split quafrangle faces near triangular facets of volumes
5020 self.SplitQuadsNearTriangularFacets()
5024 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5026 Split hexahedrons into prisms.
5028 Uses the :doc:`pattern_mapping` functionality for splitting.
5031 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5032 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5033 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5034 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5035 will be mapped into the *theNode001* -th node of each volume.
5036 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5039 True in case of success, False otherwise.
5042 This operation can create gaps in numeration of elements.
5043 Call :meth:`RenumberElements` to remove the gaps.
5045 # Pattern: 5.---------.6
5050 # (0,0,1) 4.---------.7 |
5057 # (0,0,0) 0.---------.3
5058 pattern_prism = "!!! Nb of points: \n 8 \n\
5068 !!! Indices of points of 2 prisms: \n\
5072 pattern = self.smeshpyD.GetPattern()
5073 isDone = pattern.LoadFromFile(pattern_prism)
5075 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5078 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5079 isDone = pattern.MakeMesh(self.mesh, False, False)
5080 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5082 # Split quafrangle faces near triangular facets of volumes
5083 self.SplitQuadsNearTriangularFacets()
5087 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5088 MaxNbOfIterations, MaxAspectRatio, Method):
5093 IDsOfElements: the list if ids of elements to smooth
5094 IDsOfFixedNodes: the list of ids of fixed nodes.
5095 Note that nodes built on edges and boundary nodes are always fixed.
5096 MaxNbOfIterations: the maximum number of iterations
5097 MaxAspectRatio: varies in range [1.0, inf]
5098 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5099 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5102 True in case of success, False otherwise.
5105 if IDsOfElements == []:
5106 IDsOfElements = self.GetElementsId()
5107 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5108 self.mesh.SetParameters(Parameters)
5109 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5110 MaxNbOfIterations, MaxAspectRatio, Method)
5112 def SmoothObject(self, theObject, IDsOfFixedNodes,
5113 MaxNbOfIterations, MaxAspectRatio, Method):
5115 Smooth elements which belong to the given object
5118 theObject: the object to smooth
5119 IDsOfFixedNodes: the list of ids of fixed nodes.
5120 Note that nodes built on edges and boundary nodes are always fixed.
5121 MaxNbOfIterations: the maximum number of iterations
5122 MaxAspectRatio: varies in range [1.0, inf]
5123 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5124 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5127 True in case of success, False otherwise.
5130 if ( isinstance( theObject, Mesh )):
5131 theObject = theObject.GetMesh()
5132 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5133 MaxNbOfIterations, MaxAspectRatio, Method)
5135 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5136 MaxNbOfIterations, MaxAspectRatio, Method):
5138 Parametrically smooth the given elements
5141 IDsOfElements: the list if ids of elements to smooth
5142 IDsOfFixedNodes: the list of ids of fixed nodes.
5143 Note that nodes built on edges and boundary nodes are always fixed.
5144 MaxNbOfIterations: the maximum number of iterations
5145 MaxAspectRatio: varies in range [1.0, inf]
5146 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5147 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5150 True in case of success, False otherwise.
5153 if IDsOfElements == []:
5154 IDsOfElements = self.GetElementsId()
5155 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5156 self.mesh.SetParameters(Parameters)
5157 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5158 MaxNbOfIterations, MaxAspectRatio, Method)
5160 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5161 MaxNbOfIterations, MaxAspectRatio, Method):
5163 Parametrically smooth the elements which belong to the given object
5166 theObject: the object to smooth
5167 IDsOfFixedNodes: the list of ids of fixed nodes.
5168 Note that nodes built on edges and boundary nodes are always fixed.
5169 MaxNbOfIterations: the maximum number of iterations
5170 MaxAspectRatio: varies in range [1.0, inf]
5171 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5172 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5175 True in case of success, False otherwise.
5178 if ( isinstance( theObject, Mesh )):
5179 theObject = theObject.GetMesh()
5180 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5181 MaxNbOfIterations, MaxAspectRatio, Method)
5183 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5185 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5186 them with quadratic with the same id.
5189 theForce3d: method of new node creation:
5191 * False - the medium node lies at the geometrical entity from which the mesh element is built
5192 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5193 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5194 theToBiQuad: If True, converts the mesh to bi-quadratic
5197 :class:`SMESH.ComputeError` which can hold a warning
5200 If *theSubMesh* is provided, the mesh can become non-conformal
5203 This operation can create gaps in numeration of nodes or elements.
5204 Call :meth:`RenumberElements` to remove the gaps.
5207 if isinstance( theSubMesh, Mesh ):
5208 theSubMesh = theSubMesh.mesh
5210 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5213 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5215 self.editor.ConvertToQuadratic(theForce3d)
5216 error = self.editor.GetLastError()
5217 if error and error.comment:
5218 print(error.comment)
5221 def ConvertFromQuadratic(self, theSubMesh=None):
5223 Convert the mesh from quadratic to ordinary,
5224 deletes old quadratic elements,
5225 replacing them with ordinary mesh elements with the same id.
5228 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5231 If *theSubMesh* is provided, the mesh can become non-conformal
5234 This operation can create gaps in numeration of nodes or elements.
5235 Call :meth:`RenumberElements` to remove the gaps.
5239 self.editor.ConvertFromQuadraticObject(theSubMesh)
5241 return self.editor.ConvertFromQuadratic()
5243 def Make2DMeshFrom3D(self):
5245 Create 2D mesh as skin on boundary faces of a 3D mesh
5248 True if operation has been completed successfully, False otherwise
5251 return self.editor.Make2DMeshFrom3D()
5253 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5254 toCopyElements=False, toCopyExistingBondary=False):
5256 Create missing boundary elements
5259 elements: elements whose boundary is to be checked:
5260 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5261 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5262 dimension: defines type of boundary elements to create, either of
5263 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5264 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5265 groupName: a name of group to store created boundary elements in,
5266 "" means not to create the group
5267 meshName: a name of new mesh to store created boundary elements in,
5268 "" means not to create the new mesh
5269 toCopyElements: if True, the checked elements will be copied into
5270 the new mesh else only boundary elements will be copied into the new mesh
5271 toCopyExistingBondary: if True, not only new but also pre-existing
5272 boundary elements will be copied into the new mesh
5275 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5278 unRegister = genObjUnRegister()
5279 if isinstance( elements, Mesh ):
5280 elements = elements.GetMesh()
5281 if ( isinstance( elements, list )):
5282 elemType = SMESH.ALL
5283 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5284 elements = self.editor.MakeIDSource(elements, elemType)
5285 unRegister.set( elements )
5286 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5287 toCopyElements,toCopyExistingBondary)
5288 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5291 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5292 toCopyAll=False, groups=[]):
5294 Create missing boundary elements around either the whole mesh or
5298 dimension: defines type of boundary elements to create, either of
5299 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5300 groupName: a name of group to store all boundary elements in,
5301 "" means not to create the group
5302 meshName: a name of a new mesh, which is a copy of the initial
5303 mesh + created boundary elements; "" means not to create the new mesh
5304 toCopyAll: if True, the whole initial mesh will be copied into
5305 the new mesh else only boundary elements will be copied into the new mesh
5306 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5309 tuple( long, mesh, group )
5310 - long - number of added boundary elements
5311 - mesh - the :class:`Mesh` where elements were added to
5312 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5315 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5317 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5318 return nb, mesh, group
5320 def RenumberNodes(self):
5322 Renumber mesh nodes to remove unused node IDs
5324 self.editor.RenumberNodes()
5326 def RenumberElements(self):
5328 Renumber mesh elements to remove unused element IDs
5330 self.editor.RenumberElements()
5332 def _getIdSourceList(self, arg, idType, unRegister):
5334 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5336 if arg and isinstance( arg, list ):
5337 if isinstance( arg[0], int ):
5338 arg = self.GetIDSource( arg, idType )
5339 unRegister.set( arg )
5340 elif isinstance( arg[0], Mesh ):
5341 arg[0] = arg[0].GetMesh()
5342 elif isinstance( arg, Mesh ):
5344 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5348 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5349 MakeGroups=False, TotalAngle=False):
5351 Generate new elements by rotation of the given elements and nodes around the axis
5354 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5355 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5356 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5357 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5358 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5359 which defines angle in degrees
5360 NbOfSteps: the number of steps
5361 Tolerance: tolerance
5362 MakeGroups: forces the generation of new groups from existing ones
5363 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5364 of all steps, else - size of each step
5367 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5370 unRegister = genObjUnRegister()
5371 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5372 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5373 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5375 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5376 Axis = self.smeshpyD.GetAxisStruct( Axis )
5377 if isinstance( Axis, list ):
5378 Axis = SMESH.AxisStruct( *Axis )
5380 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5381 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5382 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5383 self.mesh.SetParameters(Parameters)
5384 if TotalAngle and NbOfSteps:
5385 AngleInRadians /= NbOfSteps
5386 return self.editor.RotationSweepObjects( nodes, edges, faces,
5387 Axis, AngleInRadians,
5388 NbOfSteps, Tolerance, MakeGroups)
5390 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5391 MakeGroups=False, TotalAngle=False):
5393 Generate new elements by rotation of the elements around the axis
5396 IDsOfElements: the list of ids of elements to sweep
5397 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5398 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5399 NbOfSteps: the number of steps
5400 Tolerance: tolerance
5401 MakeGroups: forces the generation of new groups from existing ones
5402 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5403 of all steps, else - size of each step
5406 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5409 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5410 AngleInRadians, NbOfSteps, Tolerance,
5411 MakeGroups, TotalAngle)
5413 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5414 MakeGroups=False, TotalAngle=False):
5416 Generate new elements by rotation of the elements of object around the axis
5417 theObject object which elements should be sweeped.
5418 It can be a mesh, a sub mesh or a group.
5421 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5422 AngleInRadians: the angle of Rotation
5423 NbOfSteps: number of steps
5424 Tolerance: tolerance
5425 MakeGroups: forces the generation of new groups from existing ones
5426 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5427 of all steps, else - size of each step
5430 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5433 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5434 AngleInRadians, NbOfSteps, Tolerance,
5435 MakeGroups, TotalAngle )
5437 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5438 MakeGroups=False, TotalAngle=False):
5440 Generate new elements by rotation of the elements of object around the axis
5441 theObject object which elements should be sweeped.
5442 It can be a mesh, a sub mesh or a group.
5445 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5446 AngleInRadians: the angle of Rotation
5447 NbOfSteps: number of steps
5448 Tolerance: tolerance
5449 MakeGroups: forces the generation of new groups from existing ones
5450 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5451 of all steps, else - size of each step
5454 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5455 empty list otherwise
5458 return self.RotationSweepObjects([],theObject,[], Axis,
5459 AngleInRadians, NbOfSteps, Tolerance,
5460 MakeGroups, TotalAngle)
5462 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5463 MakeGroups=False, TotalAngle=False):
5465 Generate new elements by rotation of the elements of object around the axis
5466 theObject object which elements should be sweeped.
5467 It can be a mesh, a sub mesh or a group.
5470 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5471 AngleInRadians: the angle of Rotation
5472 NbOfSteps: number of steps
5473 Tolerance: tolerance
5474 MakeGroups: forces the generation of new groups from existing ones
5475 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5476 of all steps, else - size of each step
5479 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5482 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5483 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5485 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5486 scaleFactors=[], linearVariation=False, basePoint=[],
5487 angles=[], anglesVariation=False):
5489 Generate new elements by extrusion of the given elements and nodes
5492 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5493 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5494 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5495 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5496 the direction and value of extrusion for one step (the total extrusion
5497 length will be NbOfSteps * ||StepVector||)
5498 NbOfSteps: the number of steps
5499 MakeGroups: forces the generation of new groups from existing ones
5500 scaleFactors: optional scale factors to apply during extrusion
5501 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5502 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5503 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5504 nodes and elements being extruded is used as the scaling center.
5507 - a list of tree components of the point or
5510 angles: list of angles in radians. Nodes at each extrusion step are rotated
5511 around *basePoint*, additionally to previous steps.
5512 anglesVariation: forces the computation of rotation angles as linear
5513 variation of the given *angles* along path steps
5515 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5517 Example: :ref:`tui_extrusion`
5519 unRegister = genObjUnRegister()
5520 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5521 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5522 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5524 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5525 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5526 if isinstance( StepVector, list ):
5527 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5529 if isinstance( basePoint, int):
5530 xyz = self.GetNodeXYZ( basePoint )
5532 raise RuntimeError("Invalid node ID: %s" % basePoint)
5534 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5535 basePoint = self.geompyD.PointCoordinates( basePoint )
5537 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5538 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5539 angles,angleParameters,hasVars = ParseAngles(angles)
5540 Parameters = StepVector.PS.parameters + var_separator + \
5541 Parameters + var_separator + \
5542 scaleParameters + var_separator + angleParameters
5543 self.mesh.SetParameters(Parameters)
5545 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5546 StepVector, NbOfSteps, MakeGroups,
5547 scaleFactors, linearVariation, basePoint,
5548 angles, anglesVariation )
5551 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5553 Generate new elements by extrusion of the elements with given ids
5556 IDsOfElements: the list of ids of elements or nodes for extrusion
5557 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5558 the direction and value of extrusion for one step (the total extrusion
5559 length will be NbOfSteps * ||StepVector||)
5560 NbOfSteps: the number of steps
5561 MakeGroups: forces the generation of new groups from existing ones
5562 IsNodes: is True if elements with given ids are nodes
5565 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5567 Example: :ref:`tui_extrusion`
5570 if IsNodes: n = IDsOfElements
5571 else : e,f, = IDsOfElements,IDsOfElements
5572 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5574 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5575 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5577 Generate new elements by extrusion along the normal to a discretized surface or wire
5580 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5581 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5582 StepSize: length of one extrusion step (the total extrusion
5583 length will be *NbOfSteps* *StepSize*).
5584 NbOfSteps: number of extrusion steps.
5585 ByAverageNormal: if True each node is translated by *StepSize*
5586 along the average of the normal vectors to the faces sharing the node;
5587 else each node is translated along the same average normal till
5588 intersection with the plane got by translation of the face sharing
5589 the node along its own normal by *StepSize*.
5590 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5591 for every node of *Elements*.
5592 MakeGroups: forces generation of new groups from existing ones.
5593 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5594 is not yet implemented. This parameter is used if *Elements* contains
5595 both faces and edges, i.e. *Elements* is a Mesh.
5598 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5599 empty list otherwise.
5600 Example: :ref:`tui_extrusion`
5603 unRegister = genObjUnRegister()
5604 if isinstance( Elements, Mesh ):
5605 Elements = [ Elements.GetMesh() ]
5606 if isinstance( Elements, list ):
5608 raise RuntimeError("Elements empty!")
5609 if isinstance( Elements[0], Mesh ):
5610 Elements = [ Elements[0].GetMesh() ]
5611 if isinstance( Elements[0], int ):
5612 Elements = self.GetIDSource( Elements, SMESH.ALL )
5613 unRegister.set( Elements )
5614 if not isinstance( Elements, list ):
5615 Elements = [ Elements ]
5616 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5617 self.mesh.SetParameters(Parameters)
5618 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5619 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5621 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5623 Generate new elements by extrusion of the elements or nodes which belong to the object
5626 theObject: the object whose elements or nodes should be processed.
5627 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5628 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5629 the direction and value of extrusion for one step (the total extrusion
5630 length will be NbOfSteps * ||StepVector||)
5631 NbOfSteps: the number of steps
5632 MakeGroups: forces the generation of new groups from existing ones
5633 IsNodes: is True if elements to extrude are nodes
5636 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5637 Example: :ref:`tui_extrusion`
5641 if IsNodes: n = theObject
5642 else : e,f, = theObject,theObject
5643 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5645 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5647 Generate new elements by extrusion of edges which belong to the object
5650 theObject: object whose 1D elements should be processed.
5651 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5652 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5653 the direction and value of extrusion for one step (the total extrusion
5654 length will be NbOfSteps * ||StepVector||)
5655 NbOfSteps: the number of steps
5656 MakeGroups: to generate new groups from existing ones
5659 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5660 Example: :ref:`tui_extrusion`
5663 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5665 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5667 Generate new elements by extrusion of faces which belong to the object
5670 theObject: object whose 2D elements should be processed.
5671 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5672 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5673 the direction and value of extrusion for one step (the total extrusion
5674 length will be NbOfSteps * ||StepVector||)
5675 NbOfSteps: the number of steps
5676 MakeGroups: forces the generation of new groups from existing ones
5679 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5680 Example: :ref:`tui_extrusion`
5683 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5685 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5686 ExtrFlags, SewTolerance, MakeGroups=False):
5688 Generate new elements by extrusion of the elements with given ids
5691 IDsOfElements: is ids of elements
5692 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5693 the direction and value of extrusion for one step (the total extrusion
5694 length will be NbOfSteps * ||StepVector||)
5695 NbOfSteps: the number of steps
5696 ExtrFlags: sets flags for extrusion
5697 SewTolerance: uses for comparing locations of nodes if flag
5698 EXTRUSION_FLAG_SEW is set
5699 MakeGroups: forces the generation of new groups from existing ones
5702 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5705 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5706 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5707 if isinstance( StepVector, list ):
5708 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5709 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5710 ExtrFlags, SewTolerance, MakeGroups)
5712 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5713 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5714 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5715 ScaleFactors=[], ScalesVariation=False):
5717 Generate new elements by extrusion of the given elements and nodes along the path.
5718 The path of extrusion must be a meshed edge.
5721 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5722 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5723 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5724 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5725 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
5726 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5727 HasAngles: not used obsolete
5728 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5729 around *basePoint*, additionally to previous steps.
5730 LinearVariation: forces the computation of rotation angles as linear
5731 variation of the given Angles along path steps
5732 HasRefPoint: allows using the reference point
5733 RefPoint: optional scaling and rotation center (mass center of the extruded
5734 elements by default). The User can specify any point as the Reference Point.
5735 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5736 MakeGroups: forces the generation of new groups from existing ones
5737 ScaleFactors: optional scale factors to apply during extrusion
5738 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5739 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5742 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5743 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5744 Example: :ref:`tui_extrusion_along_path`
5747 unRegister = genObjUnRegister()
5748 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5749 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5750 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5752 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5753 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5754 if isinstance( RefPoint, list ):
5755 if not RefPoint: RefPoint = [0,0,0]
5756 RefPoint = SMESH.PointStruct( *RefPoint )
5757 if isinstance( PathObject, Mesh ):
5758 PathObject = PathObject.GetMesh()
5759 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5760 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5761 Parameters = AnglesParameters + var_separator + \
5762 RefPoint.parameters + var_separator + ScalesParameters
5763 self.mesh.SetParameters(Parameters)
5764 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5765 PathObject, PathShape, NodeStart,
5766 HasAngles, Angles, LinearVariation,
5767 HasRefPoint, RefPoint, MakeGroups,
5768 ScaleFactors, ScalesVariation)
5770 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5771 HasAngles=False, Angles=[], LinearVariation=False,
5772 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5773 ElemType=SMESH.FACE):
5775 Generate new elements by extrusion of the given elements.
5776 The path of extrusion must be a meshed edge.
5779 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5780 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5781 NodeStart: the start node from Path. Defines the direction of extrusion
5782 HasAngles: not used obsolete
5783 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5784 around *basePoint*, additionally to previous steps.
5785 LinearVariation: forces the computation of rotation angles as linear
5786 variation of the given Angles along path steps
5787 HasRefPoint: allows using the reference point
5788 RefPoint: the reference point around which the elements are rotated (the mass
5789 center of the elements by default).
5790 The User can specify any point as the Reference Point.
5791 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5792 MakeGroups: forces the generation of new groups from existing ones
5793 ElemType: type of elements for extrusion (if param Base is a mesh)
5796 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5797 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5798 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5800 Example: :ref:`tui_extrusion_along_path`
5804 if ElemType == SMESH.NODE: n = Base
5805 if ElemType == SMESH.EDGE: e = Base
5806 if ElemType == SMESH.FACE: f = Base
5807 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5808 HasAngles, Angles, LinearVariation,
5809 HasRefPoint, RefPoint, MakeGroups)
5810 if MakeGroups: return gr,er
5813 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5814 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5815 MakeGroups=False, LinearVariation=False):
5817 Generate new elements by extrusion of the given elements.
5818 The path of extrusion must be a meshed edge.
5821 IDsOfElements: ids of elements
5822 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5823 PathShape: shape (edge) defines the sub-mesh for the path
5824 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5825 HasAngles: not used obsolete
5826 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5827 around *basePoint*, additionally to previous steps.
5828 HasRefPoint: allows using the reference point
5829 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5830 The User can specify any point as the Reference Point.
5831 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5832 MakeGroups: forces the generation of new groups from existing ones
5833 LinearVariation: forces the computation of rotation angles as linear
5834 variation of the given Angles along path steps
5837 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5838 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5839 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5840 Example: :ref:`tui_extrusion_along_path`
5843 if not IDsOfElements:
5844 IDsOfElements = [ self.GetMesh() ]
5845 n,e,f = [],IDsOfElements,IDsOfElements
5846 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5847 NodeStart, HasAngles, Angles,
5849 HasRefPoint, RefPoint, MakeGroups)
5850 if MakeGroups: return gr,er
5853 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5854 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5855 MakeGroups=False, LinearVariation=False):
5857 Generate new elements by extrusion of the elements which belong to the object.
5858 The path of extrusion must be a meshed edge.
5861 theObject: the object whose elements should be processed.
5862 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5863 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5864 PathShape: shape (edge) defines the sub-mesh for the path
5865 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5866 HasAngles: not used obsolete
5867 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5868 around *basePoint*, additionally to previous steps.
5869 HasRefPoint: allows using the reference point
5870 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5871 The User can specify any point as the Reference Point.
5872 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5873 MakeGroups: forces the generation of new groups from existing ones
5874 LinearVariation: forces the computation of rotation angles as linear
5875 variation of the given Angles along path steps
5878 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5879 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5880 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5881 Example: :ref:`tui_extrusion_along_path`
5884 n,e,f = [],theObject,theObject
5885 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5886 HasAngles, Angles, LinearVariation,
5887 HasRefPoint, RefPoint, MakeGroups)
5888 if MakeGroups: return gr,er
5891 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5892 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5893 MakeGroups=False, LinearVariation=False):
5895 Generate new elements by extrusion of mesh segments which belong to the object.
5896 The path of extrusion must be a meshed edge.
5899 theObject: the object whose 1D elements should be processed.
5900 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5901 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5902 PathShape: shape (edge) defines the sub-mesh for the path
5903 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5904 HasAngles: not used obsolete
5905 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5906 around *basePoint*, additionally to previous steps.
5907 HasRefPoint: allows using the reference point
5908 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5909 The User can specify any point as the Reference Point.
5910 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5911 MakeGroups: forces the generation of new groups from existing ones
5912 LinearVariation: forces the computation of rotation angles as linear
5913 variation of the given Angles along path steps
5916 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5917 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5918 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5919 Example: :ref:`tui_extrusion_along_path`
5922 n,e,f = [],theObject,[]
5923 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5924 HasAngles, Angles, LinearVariation,
5925 HasRefPoint, RefPoint, MakeGroups)
5926 if MakeGroups: return gr,er
5929 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5930 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5931 MakeGroups=False, LinearVariation=False):
5933 Generate new elements by extrusion of faces which belong to the object.
5934 The path of extrusion must be a meshed edge.
5937 theObject: the object whose 2D elements should be processed.
5938 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5939 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5940 PathShape: shape (edge) defines the sub-mesh for the path
5941 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5942 HasAngles: not used obsolete
5943 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5944 around *basePoint*, additionally to previous steps.
5945 HasRefPoint: allows using the reference point
5946 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5947 The User can specify any point as the Reference Point.
5948 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5949 MakeGroups: forces the generation of new groups from existing ones
5950 LinearVariation: forces the computation of rotation angles as linear
5951 variation of the given Angles along path steps
5954 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5955 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5956 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5957 Example: :ref:`tui_extrusion_along_path`
5960 n,e,f = [],[],theObject
5961 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5962 HasAngles, Angles, LinearVariation,
5963 HasRefPoint, RefPoint, MakeGroups)
5964 if MakeGroups: return gr,er
5967 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5969 Create a symmetrical copy of mesh elements
5972 IDsOfElements: list of elements ids
5973 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5974 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5975 If the *Mirror* is a geom object this parameter is unnecessary
5976 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5977 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5980 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5983 if IDsOfElements == []:
5984 IDsOfElements = self.GetElementsId()
5985 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5986 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5987 theMirrorType = Mirror._mirrorType
5989 self.mesh.SetParameters(Mirror.parameters)
5990 if Copy and MakeGroups:
5991 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5992 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5995 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5997 Create a new mesh by a symmetrical copy of mesh elements
6000 IDsOfElements: the list of elements ids
6001 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6002 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6003 If the *Mirror* is a geom object this parameter is unnecessary
6004 MakeGroups: to generate new groups from existing ones
6005 NewMeshName: a name of the new mesh to create
6008 instance of class :class:`Mesh`
6011 if IDsOfElements == []:
6012 IDsOfElements = self.GetElementsId()
6013 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6014 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6015 theMirrorType = Mirror._mirrorType
6017 self.mesh.SetParameters(Mirror.parameters)
6018 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6019 MakeGroups, NewMeshName)
6020 return Mesh(self.smeshpyD,self.geompyD,mesh)
6022 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6024 Create a symmetrical copy of the object
6027 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6028 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6029 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6030 If the *Mirror* is a geom object this parameter is unnecessary
6031 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6032 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6035 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6038 if ( isinstance( theObject, Mesh )):
6039 theObject = theObject.GetMesh()
6040 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6041 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6042 theMirrorType = Mirror._mirrorType
6044 self.mesh.SetParameters(Mirror.parameters)
6045 if Copy and MakeGroups:
6046 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6047 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6050 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6052 Create a new mesh by a symmetrical copy of the object
6055 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6056 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6057 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6058 If the *Mirror* is a geom object this parameter is unnecessary
6059 MakeGroups: forces the generation of new groups from existing ones
6060 NewMeshName: the name of the new mesh to create
6063 instance of class :class:`Mesh`
6066 if ( isinstance( theObject, Mesh )):
6067 theObject = theObject.GetMesh()
6068 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6069 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6070 theMirrorType = Mirror._mirrorType
6072 self.mesh.SetParameters(Mirror.parameters)
6073 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6074 MakeGroups, NewMeshName)
6075 return Mesh( self.smeshpyD,self.geompyD,mesh )
6077 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6079 Translate the elements
6082 IDsOfElements: list of elements ids
6083 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6084 Copy: allows copying the translated elements
6085 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6088 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6091 if IDsOfElements == []:
6092 IDsOfElements = self.GetElementsId()
6093 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6094 Vector = self.smeshpyD.GetDirStruct(Vector)
6095 if isinstance( Vector, list ):
6096 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6097 self.mesh.SetParameters(Vector.PS.parameters)
6098 if Copy and MakeGroups:
6099 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6100 self.editor.Translate(IDsOfElements, Vector, Copy)
6103 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6105 Create a new mesh of translated elements
6108 IDsOfElements: list of elements ids
6109 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6110 MakeGroups: forces the generation of new groups from existing ones
6111 NewMeshName: the name of the newly created mesh
6114 instance of class :class:`Mesh`
6117 if IDsOfElements == []:
6118 IDsOfElements = self.GetElementsId()
6119 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6120 Vector = self.smeshpyD.GetDirStruct(Vector)
6121 if isinstance( Vector, list ):
6122 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6123 self.mesh.SetParameters(Vector.PS.parameters)
6124 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6125 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6127 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6129 Translate the object
6132 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6133 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6134 Copy: allows copying the translated elements
6135 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6138 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6141 if ( isinstance( theObject, Mesh )):
6142 theObject = theObject.GetMesh()
6143 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6144 Vector = self.smeshpyD.GetDirStruct(Vector)
6145 if isinstance( Vector, list ):
6146 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6147 self.mesh.SetParameters(Vector.PS.parameters)
6148 if Copy and MakeGroups:
6149 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6150 self.editor.TranslateObject(theObject, Vector, Copy)
6153 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6155 Create a new mesh from the translated object
6158 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6159 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6160 MakeGroups: forces the generation of new groups from existing ones
6161 NewMeshName: the name of the newly created mesh
6164 instance of class :class:`Mesh`
6167 if isinstance( theObject, Mesh ):
6168 theObject = theObject.GetMesh()
6169 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6170 Vector = self.smeshpyD.GetDirStruct(Vector)
6171 if isinstance( Vector, list ):
6172 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6173 self.mesh.SetParameters(Vector.PS.parameters)
6174 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6175 return Mesh( self.smeshpyD, self.geompyD, mesh )
6179 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6184 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6185 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6186 theScaleFact: list of 1-3 scale factors for axises
6187 Copy: allows copying the translated elements
6188 MakeGroups: forces the generation of new groups from existing
6192 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6193 empty list otherwise
6195 unRegister = genObjUnRegister()
6196 if ( isinstance( theObject, Mesh )):
6197 theObject = theObject.GetMesh()
6198 if ( isinstance( theObject, list )):
6199 theObject = self.GetIDSource(theObject, SMESH.ALL)
6200 unRegister.set( theObject )
6201 if ( isinstance( thePoint, list )):
6202 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6203 if ( isinstance( theScaleFact, float )):
6204 theScaleFact = [theScaleFact]
6205 if ( isinstance( theScaleFact, int )):
6206 theScaleFact = [ float(theScaleFact)]
6208 self.mesh.SetParameters(thePoint.parameters)
6210 if Copy and MakeGroups:
6211 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6212 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6215 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6217 Create a new mesh from the translated object
6220 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6221 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6222 theScaleFact: list of 1-3 scale factors for axises
6223 MakeGroups: forces the generation of new groups from existing ones
6224 NewMeshName: the name of the newly created mesh
6227 instance of class :class:`Mesh`
6229 unRegister = genObjUnRegister()
6230 if (isinstance(theObject, Mesh)):
6231 theObject = theObject.GetMesh()
6232 if ( isinstance( theObject, list )):
6233 theObject = self.GetIDSource(theObject,SMESH.ALL)
6234 unRegister.set( theObject )
6235 if ( isinstance( thePoint, list )):
6236 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6237 if ( isinstance( theScaleFact, float )):
6238 theScaleFact = [theScaleFact]
6239 if ( isinstance( theScaleFact, int )):
6240 theScaleFact = [ float(theScaleFact)]
6242 self.mesh.SetParameters(thePoint.parameters)
6243 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6244 MakeGroups, NewMeshName)
6245 return Mesh( self.smeshpyD, self.geompyD, mesh )
6249 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6254 IDsOfElements: list of elements ids
6255 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6256 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6257 Copy: allows copying the rotated elements
6258 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6261 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6265 if IDsOfElements == []:
6266 IDsOfElements = self.GetElementsId()
6267 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6268 Axis = self.smeshpyD.GetAxisStruct(Axis)
6269 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6270 Parameters = Axis.parameters + var_separator + Parameters
6271 self.mesh.SetParameters(Parameters)
6272 if Copy and MakeGroups:
6273 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6274 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6277 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6279 Create a new mesh of rotated elements
6282 IDsOfElements: list of element ids
6283 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6284 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6285 MakeGroups: forces the generation of new groups from existing ones
6286 NewMeshName: the name of the newly created mesh
6289 instance of class :class:`Mesh`
6292 if IDsOfElements == []:
6293 IDsOfElements = self.GetElementsId()
6294 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6295 Axis = self.smeshpyD.GetAxisStruct(Axis)
6296 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6297 Parameters = Axis.parameters + var_separator + Parameters
6298 self.mesh.SetParameters(Parameters)
6299 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6300 MakeGroups, NewMeshName)
6301 return Mesh( self.smeshpyD, self.geompyD, mesh )
6303 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6308 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6309 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6310 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6311 Copy: allows copying the rotated elements
6312 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6315 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6318 if (isinstance(theObject, Mesh)):
6319 theObject = theObject.GetMesh()
6320 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6321 Axis = self.smeshpyD.GetAxisStruct(Axis)
6322 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6323 Parameters = Axis.parameters + ":" + Parameters
6324 self.mesh.SetParameters(Parameters)
6325 if Copy and MakeGroups:
6326 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6327 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6330 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6332 Create a new mesh from the rotated object
6335 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6336 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6337 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6338 MakeGroups: forces the generation of new groups from existing ones
6339 NewMeshName: the name of the newly created mesh
6342 instance of class :class:`Mesh`
6345 if (isinstance( theObject, Mesh )):
6346 theObject = theObject.GetMesh()
6347 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6348 Axis = self.smeshpyD.GetAxisStruct(Axis)
6349 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6350 Parameters = Axis.parameters + ":" + Parameters
6351 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6352 MakeGroups, NewMeshName)
6353 self.mesh.SetParameters(Parameters)
6354 return Mesh( self.smeshpyD, self.geompyD, mesh )
6356 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6358 Create an offset mesh from the given 2D object
6361 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6362 theValue (float): signed offset size
6363 MakeGroups (boolean): forces the generation of new groups from existing ones
6364 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6365 False means to remove original elements.
6366 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6369 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6372 if isinstance( theObject, Mesh ):
6373 theObject = theObject.GetMesh()
6374 theValue,Parameters,hasVars = ParseParameters(Value)
6375 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6376 self.mesh.SetParameters(Parameters)
6378 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6381 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6383 Find groups of adjacent nodes within Tolerance.
6386 Tolerance (float): the value of tolerance
6387 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6388 corner and medium nodes in separate groups thus preventing
6389 their further merge.
6392 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6395 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6397 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6398 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6400 Find groups of adjacent nodes within Tolerance.
6403 Tolerance: the value of tolerance
6404 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6405 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6406 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6407 corner and medium nodes in separate groups thus preventing
6408 their further merge.
6411 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6414 unRegister = genObjUnRegister()
6415 if not isinstance( SubMeshOrGroup, list ):
6416 SubMeshOrGroup = [ SubMeshOrGroup ]
6417 for i,obj in enumerate( SubMeshOrGroup ):
6418 if isinstance( obj, Mesh ):
6419 SubMeshOrGroup = [ obj.GetMesh() ]
6421 if isinstance( obj, int ):
6422 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6423 unRegister.set( SubMeshOrGroup )
6426 if not isinstance( exceptNodes, list ):
6427 exceptNodes = [ exceptNodes ]
6428 if exceptNodes and isinstance( exceptNodes[0], int ):
6429 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6430 unRegister.set( exceptNodes )
6432 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6433 exceptNodes, SeparateCornerAndMediumNodes)
6435 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6440 GroupsOfNodes: a list of groups of nodes IDs for merging.
6441 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6442 in all elements and mesh groups by nodes 1 and 25 correspondingly
6443 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6444 If *NodesToKeep* does not include a node to keep for some group to merge,
6445 then the first node in the group is kept.
6446 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6450 This operation can create gaps in numeration of nodes or elements.
6451 Call :meth:`RenumberElements` to remove the gaps.
6453 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6455 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6457 Find the elements built on the same nodes.
6460 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6461 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6465 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6468 unRegister = genObjUnRegister()
6469 if MeshOrSubMeshOrGroup is None:
6470 MeshOrSubMeshOrGroup = [ self.mesh ]
6471 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6472 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6473 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6474 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6475 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6476 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6477 unRegister.set( MeshOrSubMeshOrGroup )
6478 for item in MeshOrSubMeshOrGroup:
6479 if isinstance( item, Mesh ):
6480 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6482 if not isinstance( exceptElements, list ):
6483 exceptElements = [ exceptElements ]
6484 if exceptElements and isinstance( exceptElements[0], int ):
6485 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6486 unRegister.set( exceptElements )
6488 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6490 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6492 Merge elements in each given group.
6495 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6496 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6497 replaced in all mesh groups by elements 1 and 25)
6498 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6499 If *ElementsToKeep* does not include an element to keep for some group to merge,
6500 then the first element in the group is kept.
6503 This operation can create gaps in numeration of elements.
6504 Call :meth:`RenumberElements` to remove the gaps.
6507 unRegister = genObjUnRegister()
6509 if not isinstance( ElementsToKeep, list ):
6510 ElementsToKeep = [ ElementsToKeep ]
6511 if isinstance( ElementsToKeep[0], int ):
6512 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6513 unRegister.set( ElementsToKeep )
6515 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6517 def MergeEqualElements(self):
6519 Leave one element and remove all other elements built on the same nodes.
6522 This operation can create gaps in numeration of elements.
6523 Call :meth:`RenumberElements` to remove the gaps.
6526 self.editor.MergeEqualElements()
6528 def FindFreeBorders(self, ClosedOnly=True):
6530 Returns all or only closed free borders
6533 list of SMESH.FreeBorder's
6536 return self.editor.FindFreeBorders( ClosedOnly )
6538 def FillHole(self, holeNodes, groupName=""):
6540 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6543 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6544 must describe all sequential nodes of the hole border. The first and the last
6545 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6546 groupName (string): name of a group to add new faces
6548 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6552 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6553 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6554 if not isinstance( holeNodes, SMESH.FreeBorder ):
6555 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6556 return self.editor.FillHole( holeNodes, groupName )
6558 def FindCoincidentFreeBorders (self, tolerance=0.):
6560 Return groups of FreeBorder's coincident within the given tolerance.
6563 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6564 size of elements adjacent to free borders being compared is used.
6567 SMESH.CoincidentFreeBorders structure
6570 return self.editor.FindCoincidentFreeBorders( tolerance )
6572 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6574 Sew FreeBorder's of each group
6577 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6578 where each enclosed list contains node IDs of a group of coincident free
6579 borders such that each consequent triple of IDs within a group describes
6580 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6581 last node of a border.
6582 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6583 groups of coincident free borders, each group including two borders.
6584 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6585 polygons if a node of opposite border falls on a face edge, else such
6586 faces are split into several ones.
6587 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6588 polyhedra if a node of opposite border falls on a volume edge, else such
6589 volumes, if any, remain intact and the mesh becomes non-conformal.
6592 a number of successfully sewed groups
6595 This operation can create gaps in numeration of nodes or elements.
6596 Call :meth:`RenumberElements` to remove the gaps.
6599 if freeBorders and isinstance( freeBorders, list ):
6600 # construct SMESH.CoincidentFreeBorders
6601 if isinstance( freeBorders[0], int ):
6602 freeBorders = [freeBorders]
6604 coincidentGroups = []
6605 for nodeList in freeBorders:
6606 if not nodeList or len( nodeList ) % 3:
6607 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6610 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6611 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6612 nodeList = nodeList[3:]
6614 coincidentGroups.append( group )
6616 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6618 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6620 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6621 FirstNodeID2, SecondNodeID2, LastNodeID2,
6622 CreatePolygons, CreatePolyedrs):
6627 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6630 This operation can create gaps in numeration of nodes or elements.
6631 Call :meth:`RenumberElements` to remove the gaps.
6634 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6635 FirstNodeID2, SecondNodeID2, LastNodeID2,
6636 CreatePolygons, CreatePolyedrs)
6638 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6639 FirstNodeID2, SecondNodeID2):
6641 Sew conform free borders
6644 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6647 This operation can create gaps in numeration of elements.
6648 Call :meth:`RenumberElements` to remove the gaps.
6651 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6652 FirstNodeID2, SecondNodeID2)
6654 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6655 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6660 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6663 This operation can create gaps in numeration of elements.
6664 Call :meth:`RenumberElements` to remove the gaps.
6667 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6668 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6670 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6671 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6672 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6674 Sew two sides of a mesh. The nodes belonging to Side1 are
6675 merged with the nodes of elements of Side2.
6676 The number of elements in theSide1 and in theSide2 must be
6677 equal and they should have similar nodal connectivity.
6678 The nodes to merge should belong to side borders and
6679 the first node should be linked to the second.
6682 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6685 This operation can create gaps in numeration of nodes.
6686 Call :meth:`RenumberElements` to remove the gaps.
6689 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6690 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6691 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6693 def ChangeElemNodes(self, ide, newIDs):
6695 Set new nodes for the given element. Number of nodes should be kept.
6702 False if the number of nodes does not correspond to the type of element
6705 return self.editor.ChangeElemNodes(ide, newIDs)
6707 def GetLastCreatedNodes(self):
6709 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6710 created, this method return the list of their IDs.
6711 If new nodes were not created - return empty list
6714 the list of integer values (can be empty)
6717 return self.editor.GetLastCreatedNodes()
6719 def GetLastCreatedElems(self):
6721 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6722 created this method return the list of their IDs.
6723 If new elements were not created - return empty list
6726 the list of integer values (can be empty)
6729 return self.editor.GetLastCreatedElems()
6731 def ClearLastCreated(self):
6733 Forget what nodes and elements were created by the last mesh edition operation
6736 self.editor.ClearLastCreated()
6738 def DoubleElements(self, theElements, theGroupName=""):
6740 Create duplicates of given elements, i.e. create new elements based on the
6741 same nodes as the given ones.
6744 theElements: container of elements to duplicate. It can be a
6745 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6746 or a list of element IDs. If *theElements* is
6747 a :class:`Mesh`, elements of highest dimension are duplicated
6748 theGroupName: a name of group to contain the generated elements.
6749 If a group with such a name already exists, the new elements
6750 are added to the existing group, else a new group is created.
6751 If *theGroupName* is empty, new elements are not added
6755 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6756 None if *theGroupName* == "".
6759 unRegister = genObjUnRegister()
6760 if isinstance( theElements, Mesh ):
6761 theElements = theElements.mesh
6762 elif isinstance( theElements, list ):
6763 theElements = self.GetIDSource( theElements, SMESH.ALL )
6764 unRegister.set( theElements )
6765 return self.editor.DoubleElements(theElements, theGroupName)
6767 def DoubleNodes(self, theNodes, theModifiedElems):
6769 Create a hole in a mesh by doubling the nodes of some particular elements
6772 theNodes: IDs of nodes to be doubled
6773 theModifiedElems: IDs of elements to be updated by the new (doubled)
6774 nodes. If list of element identifiers is empty then nodes are doubled but
6775 they not assigned to elements
6778 True if operation has been completed successfully, False otherwise
6781 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6783 def DoubleNode(self, theNodeId, theModifiedElems):
6785 Create a hole in a mesh by doubling the nodes of some particular elements.
6786 This method provided for convenience works as :meth:`DoubleNodes`.
6789 theNodeId: IDs of node to double
6790 theModifiedElems: IDs of elements to update
6793 True if operation has been completed successfully, False otherwise
6796 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6798 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6800 Create a hole in a mesh by doubling the nodes of some particular elements.
6801 This method provided for convenience works as :meth:`DoubleNodes`.
6804 theNodes: group of nodes to double.
6805 theModifiedElems: group of elements to update.
6806 theMakeGroup: forces the generation of a group containing new nodes.
6809 True or a created group if operation has been completed successfully,
6810 False or None otherwise
6814 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6815 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6817 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6819 Create a hole in a mesh by doubling the nodes of some particular elements.
6820 This method provided for convenience works as :meth:`DoubleNodes`.
6823 theNodes: list of groups of nodes to double.
6824 theModifiedElems: list of groups of elements to update.
6825 theMakeGroup: forces the generation of a group containing new nodes.
6828 True if operation has been completed successfully, False otherwise
6832 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6833 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6835 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6837 Create a hole in a mesh by doubling the nodes of some particular elements
6840 theElems: the list of elements (edges or faces) to replicate.
6841 The nodes for duplication could be found from these elements
6842 theNodesNot: list of nodes NOT to replicate
6843 theAffectedElems: the list of elements (cells and edges) to which the
6844 replicated nodes should be associated to
6847 True if operation has been completed successfully, False otherwise
6850 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6852 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6854 Create a hole in a mesh by doubling the nodes of some particular elements
6857 theElems: the list of elements (edges or faces) to replicate.
6858 The nodes for duplication could be found from these elements
6859 theNodesNot: list of nodes NOT to replicate
6860 theShape: shape to detect affected elements (element which geometric center
6861 located on or inside shape).
6862 The replicated nodes should be associated to affected elements.
6865 True if operation has been completed successfully, False otherwise
6868 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6870 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6871 theMakeGroup=False, theMakeNodeGroup=False):
6873 Create a hole in a mesh by doubling the nodes of some particular elements.
6874 This method provided for convenience works as :meth:`DoubleNodes`.
6877 theElems: group of of elements (edges or faces) to replicate.
6878 theNodesNot: group of nodes NOT to replicate.
6879 theAffectedElems: group of elements to which the replicated nodes
6880 should be associated to.
6881 theMakeGroup: forces the generation of a group containing new elements.
6882 theMakeNodeGroup: forces the generation of a group containing new nodes.
6885 True or created groups (one or two) if operation has been completed successfully,
6886 False or None otherwise
6889 if theMakeGroup or theMakeNodeGroup:
6890 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6892 theMakeGroup, theMakeNodeGroup)
6893 if theMakeGroup and theMakeNodeGroup:
6896 return twoGroups[ int(theMakeNodeGroup) ]
6897 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6899 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6901 Create a hole in a mesh by doubling the nodes of some particular elements.
6902 This method provided for convenience works as :meth:`DoubleNodes`.
6905 theElems: group of of elements (edges or faces) to replicate
6906 theNodesNot: group of nodes not to replicate
6907 theShape: shape to detect affected elements (element which geometric center
6908 located on or inside shape).
6909 The replicated nodes should be associated to affected elements
6912 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6914 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6915 theMakeGroup=False, theMakeNodeGroup=False):
6917 Create a hole in a mesh by doubling the nodes of some particular elements.
6918 This method provided for convenience works as :meth:`DoubleNodes`.
6921 theElems: list of groups of elements (edges or faces) to replicate
6922 theNodesNot: list of groups of nodes NOT to replicate
6923 theAffectedElems: group of elements to which the replicated nodes
6924 should be associated to
6925 theMakeGroup: forces generation of a group containing new elements.
6926 theMakeNodeGroup: forces generation of a group containing new nodes
6929 True or created groups (one or two) if operation has been completed successfully,
6930 False or None otherwise
6933 if theMakeGroup or theMakeNodeGroup:
6934 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6936 theMakeGroup, theMakeNodeGroup)
6937 if theMakeGroup and theMakeNodeGroup:
6940 return twoGroups[ int(theMakeNodeGroup) ]
6941 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6943 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6945 Create a hole in a mesh by doubling the nodes of some particular elements.
6946 This method provided for convenience works as :meth:`DoubleNodes`.
6949 theElems: list of groups of elements (edges or faces) to replicate
6950 theNodesNot: list of groups of nodes NOT to replicate
6951 theShape: shape to detect affected elements (element which geometric center
6952 located on or inside shape).
6953 The replicated nodes should be associated to affected elements
6956 True if operation has been completed successfully, False otherwise
6959 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6961 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6963 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6964 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6967 theElems: list of groups of nodes or elements (edges or faces) to replicate
6968 theNodesNot: list of groups of nodes NOT to replicate
6969 theShape: shape to detect affected elements (element which geometric center
6970 located on or inside shape).
6971 The replicated nodes should be associated to affected elements
6974 groups of affected elements in order: volumes, faces, edges
6977 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6979 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6982 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6983 The list of groups must describe a partition of the mesh volumes.
6984 The nodes of the internal faces at the boundaries of the groups are doubled.
6985 In option, the internal faces are replaced by flat elements.
6986 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6989 theDomains: list of groups of volumes
6990 createJointElems: if True, create the elements
6991 onAllBoundaries: if True, the nodes and elements are also created on
6992 the boundary between *theDomains* and the rest mesh
6995 True if operation has been completed successfully, False otherwise
6998 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7000 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7002 Double nodes on some external faces and create flat elements.
7003 Flat elements are mainly used by some types of mechanic calculations.
7005 Each group of the list must be constituted of faces.
7006 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7009 theGroupsOfFaces: list of groups of faces
7012 True if operation has been completed successfully, False otherwise
7015 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7017 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7019 Identify all the elements around a geom shape, get the faces delimiting the hole
7021 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7023 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7025 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7026 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7027 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7028 If there are several paths connecting a pair of points, the shortest path is
7029 selected by the module. Position of the cutting plane is defined by the two
7030 points and an optional vector lying on the plane specified by a PolySegment.
7031 By default the vector is defined by Mesh module as following. A middle point
7032 of the two given points is computed. The middle point is projected to the mesh.
7033 The vector goes from the middle point to the projection point. In case of planar
7034 mesh, the vector is normal to the mesh.
7036 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7039 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7040 groupName: optional name of a group where created mesh segments will be added.
7043 editor = self.editor
7045 editor = self.mesh.GetMeshEditPreviewer()
7046 segmentsRes = editor.MakePolyLine( segments, groupName )
7047 for i, seg in enumerate( segmentsRes ):
7048 segments[i].vector = seg.vector
7050 return editor.GetPreviewData()
7053 def MakeSlot(self, segmentGroup, width ):
7055 Create a slot of given width around given 1D elements lying on a triangle mesh.
7056 The slot is constructed by cutting faces by cylindrical surfaces made
7057 around each segment. Segments are expected to be created by MakePolyLine().
7060 FaceEdge's located at the slot boundary
7062 return self.editor.MakeSlot( segmentGroup, width )
7064 def GetFunctor(self, funcType ):
7066 Return a cached numerical functor by its type.
7069 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7070 Note that not all items correspond to numerical functors.
7073 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7076 fn = self.functors[ funcType._v ]
7078 fn = self.smeshpyD.GetFunctor(funcType)
7079 fn.SetMesh(self.mesh)
7080 self.functors[ funcType._v ] = fn
7083 def FunctorValue(self, funcType, elemId, isElem=True):
7085 Return value of a functor for a given element
7088 funcType: an item of :class:`SMESH.FunctorType` enum.
7089 elemId: element or node ID
7090 isElem: *elemId* is ID of element or node
7093 the functor value or zero in case of invalid arguments
7096 fn = self.GetFunctor( funcType )
7097 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7098 val = fn.GetValue(elemId)
7103 def GetLength(self, elemId=None):
7105 Get length of given 1D elements or of all 1D mesh elements
7108 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.
7111 Sum of lengths of given elements
7116 length = self.smeshpyD.GetLength(self)
7117 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7118 length = self.smeshpyD.GetLength(elemId)
7121 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7123 length += self.smeshpyD.GetLength(obj)
7124 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7125 unRegister = genObjUnRegister()
7126 obj = self.GetIDSource( elemId )
7127 unRegister.set( obj )
7128 length = self.smeshpyD.GetLength( obj )
7130 length = self.FunctorValue(SMESH.FT_Length, elemId)
7133 def GetArea(self, elemId=None):
7135 Get area of given 2D elements or of all 2D mesh elements
7138 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.
7141 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7146 area = self.smeshpyD.GetArea(self)
7147 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7148 area = self.smeshpyD.GetArea(elemId)
7151 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7153 area += self.smeshpyD.GetArea(obj)
7154 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7155 unRegister = genObjUnRegister()
7156 obj = self.GetIDSource( elemId )
7157 unRegister.set( obj )
7158 area = self.smeshpyD.GetArea( obj )
7160 area = self.FunctorValue(SMESH.FT_Area, elemId)
7163 def GetVolume(self, elemId=None):
7165 Get volume of given 3D elements or of all 3D mesh elements
7168 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.
7171 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7176 volume= self.smeshpyD.GetVolume(self)
7177 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7178 volume= self.smeshpyD.GetVolume(elemId)
7181 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7183 volume+= self.smeshpyD.GetVolume(obj)
7184 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7185 unRegister = genObjUnRegister()
7186 obj = self.GetIDSource( elemId )
7187 unRegister.set( obj )
7188 volume= self.smeshpyD.GetVolume( obj )
7190 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7193 def GetAngle(self, node1, node2, node3 ):
7195 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7198 node1,node2,node3: IDs of the three nodes
7201 Angle in radians [0,PI]. -1 if failure case.
7203 p1 = self.GetNodeXYZ( node1 )
7204 p2 = self.GetNodeXYZ( node2 )
7205 p3 = self.GetNodeXYZ( node3 )
7206 if p1 and p2 and p3:
7207 return self.smeshpyD.GetAngle( p1,p2,p3 )
7211 def GetMaxElementLength(self, elemId):
7213 Get maximum element length.
7216 elemId: mesh element ID
7219 element's maximum length value
7222 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7223 ftype = SMESH.FT_MaxElementLength3D
7225 ftype = SMESH.FT_MaxElementLength2D
7226 return self.FunctorValue(ftype, elemId)
7228 def GetAspectRatio(self, elemId):
7230 Get aspect ratio of 2D or 3D element.
7233 elemId: mesh element ID
7236 element's aspect ratio value
7239 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7240 ftype = SMESH.FT_AspectRatio3D
7242 ftype = SMESH.FT_AspectRatio
7243 return self.FunctorValue(ftype, elemId)
7245 def GetWarping(self, elemId):
7247 Get warping angle of 2D element.
7250 elemId: mesh element ID
7253 element's warping angle value
7256 return self.FunctorValue(SMESH.FT_Warping, elemId)
7258 def GetMinimumAngle(self, elemId):
7260 Get minimum angle of 2D element.
7263 elemId: mesh element ID
7266 element's minimum angle value
7269 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7271 def GetTaper(self, elemId):
7273 Get taper of 2D element.
7276 elemId: mesh element ID
7279 element's taper value
7282 return self.FunctorValue(SMESH.FT_Taper, elemId)
7284 def GetSkew(self, elemId):
7286 Get skew of 2D element.
7289 elemId: mesh element ID
7292 element's skew value
7295 return self.FunctorValue(SMESH.FT_Skew, elemId)
7297 def GetMinMax(self, funType, meshPart=None):
7299 Return minimal and maximal value of a given functor.
7302 funType (SMESH.FunctorType): a functor type.
7303 Note that not all items of :class:`SMESH.FunctorType` corresponds
7304 to numerical functors.
7305 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7311 unRegister = genObjUnRegister()
7312 if isinstance( meshPart, list ):
7313 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7314 unRegister.set( meshPart )
7315 if isinstance( meshPart, Mesh ):
7316 meshPart = meshPart.mesh
7317 fun = self.GetFunctor( funType )
7320 if hasattr( meshPart, "SetMesh" ):
7321 meshPart.SetMesh( self.mesh ) # set mesh to filter
7322 hist = fun.GetLocalHistogram( 1, False, meshPart )
7324 hist = fun.GetHistogram( 1, False )
7326 return hist[0].min, hist[0].max
7329 pass # end of Mesh class
7332 class meshProxy(SMESH._objref_SMESH_Mesh):
7334 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7335 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7337 def __init__(self,*args):
7338 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7339 def __deepcopy__(self, memo=None):
7340 new = self.__class__(self)
7342 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7343 if len( args ) == 3:
7344 args += SMESH.ALL_NODES, True
7345 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7346 def ExportToMEDX(self, *args): # function removed
7347 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7348 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7349 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7350 def ExportToMED(self, *args): # function removed
7351 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7352 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7354 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7356 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7357 def ExportPartToMED(self, *args): # 'version' parameter removed
7358 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7359 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7360 def ExportMED(self, *args): # signature of method changed
7361 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7363 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7365 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7367 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7370 class submeshProxy(SMESH._objref_SMESH_subMesh):
7373 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7375 def __init__(self,*args):
7376 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7378 def __deepcopy__(self, memo=None):
7379 new = self.__class__(self)
7382 def Compute(self,refresh=False):
7384 Compute the sub-mesh and return the status of the computation
7387 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7392 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7393 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7397 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7399 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7401 if salome.sg.hasDesktop():
7402 if refresh: salome.sg.updateObjBrowser()
7407 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7410 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7412 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7413 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7416 def __init__(self,*args):
7417 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7419 def __getattr__(self, name ): # method called if an attribute not found
7420 if not self.mesh: # look for name() method in Mesh class
7421 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7422 if hasattr( self.mesh, name ):
7423 return getattr( self.mesh, name )
7424 if name == "ExtrusionAlongPathObjX":
7425 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7426 print("meshEditor: attribute '%s' NOT FOUND" % name)
7428 def __deepcopy__(self, memo=None):
7429 new = self.__class__(self)
7431 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7432 if len( args ) == 1: args += False,
7433 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7434 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7435 if len( args ) == 2: args += False,
7436 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7437 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7438 if len( args ) == 1:
7439 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7440 NodesToKeep = args[1]
7441 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7442 unRegister = genObjUnRegister()
7444 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7445 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7446 if not isinstance( NodesToKeep, list ):
7447 NodesToKeep = [ NodesToKeep ]
7448 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7450 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7452 class Pattern(SMESH._objref_SMESH_Pattern):
7454 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7455 variables in some methods
7458 def LoadFromFile(self, patternTextOrFile ):
7459 text = patternTextOrFile
7460 if os.path.exists( text ):
7461 text = open( patternTextOrFile ).read()
7463 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7465 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7466 decrFun = lambda i: i-1
7467 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7468 theMesh.SetParameters(Parameters)
7469 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7471 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7472 decrFun = lambda i: i-1
7473 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7474 theMesh.SetParameters(Parameters)
7475 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7477 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7478 if isinstance( mesh, Mesh ):
7479 mesh = mesh.GetMesh()
7480 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7482 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7484 Registering the new proxy for Pattern
7489 Private class used to bind methods creating algorithms to the class Mesh
7492 def __init__(self, method):
7494 self.defaultAlgoType = ""
7495 self.algoTypeToClass = {}
7496 self.method = method
7498 def add(self, algoClass):
7500 Store a python class of algorithm
7502 if inspect.isclass(algoClass) and \
7503 hasattr( algoClass, "algoType"):
7504 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7505 if not self.defaultAlgoType and \
7506 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7507 self.defaultAlgoType = algoClass.algoType
7508 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7510 def copy(self, mesh):
7512 Create a copy of self and assign mesh to the copy
7515 other = algoCreator( self.method )
7516 other.defaultAlgoType = self.defaultAlgoType
7517 other.algoTypeToClass = self.algoTypeToClass
7521 def __call__(self,algo="",geom=0,*args):
7523 Create an instance of algorithm
7527 if isinstance( algo, str ):
7529 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7530 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7535 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7537 elif not algoType and isinstance( geom, str ):
7542 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7544 elif isinstance( arg, str ) and not algoType:
7547 import traceback, sys
7548 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7549 sys.stderr.write( msg + '\n' )
7550 tb = traceback.extract_stack(None,2)
7551 traceback.print_list( [tb[0]] )
7553 algoType = self.defaultAlgoType
7554 if not algoType and self.algoTypeToClass:
7555 algoType = sorted( self.algoTypeToClass.keys() )[0]
7556 if algoType in self.algoTypeToClass:
7557 #print("Create algo",algoType)
7558 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7559 raise RuntimeError( "No class found for algo type %s" % algoType)
7562 class hypMethodWrapper:
7564 Private class used to substitute and store variable parameters of hypotheses.
7567 def __init__(self, hyp, method):
7569 self.method = method
7570 #print("REBIND:", method.__name__)
7573 def __call__(self,*args):
7575 call a method of hypothesis with calling SetVarParameter() before
7579 return self.method( self.hyp, *args ) # hypothesis method with no args
7581 #print("MethWrapper.__call__", self.method.__name__, args)
7583 parsed = ParseParameters(*args) # replace variables with their values
7584 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7585 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7586 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7587 # maybe there is a replaced string arg which is not variable
7588 result = self.method( self.hyp, *args )
7589 except ValueError as detail: # raised by ParseParameters()
7591 result = self.method( self.hyp, *args )
7592 except omniORB.CORBA.BAD_PARAM:
7593 raise ValueError(detail) # wrong variable name
7598 class genObjUnRegister:
7600 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7603 def __init__(self, genObj=None):
7604 self.genObjList = []
7608 def set(self, genObj):
7609 "Store one or a list of of SALOME.GenericObj'es"
7610 if isinstance( genObj, list ):
7611 self.genObjList.extend( genObj )
7613 self.genObjList.append( genObj )
7617 for genObj in self.genObjList:
7618 if genObj and hasattr( genObj, "UnRegister" ):
7621 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7623 Bind methods creating mesher plug-ins to the Mesh class
7626 # print("pluginName: ", pluginName)
7627 pluginBuilderName = pluginName + "Builder"
7629 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7630 except Exception as e:
7631 from salome_utils import verbose
7632 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7634 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7635 plugin = eval( pluginBuilderName )
7636 # print(" plugin:" , str(plugin))
7638 # add methods creating algorithms to Mesh
7639 for k in dir( plugin ):
7640 if k[0] == '_': continue
7641 algo = getattr( plugin, k )
7642 #print(" algo:", str(algo))
7643 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7644 #print(" meshMethod:" , str(algo.meshMethod))
7645 if not hasattr( Mesh, algo.meshMethod ):
7646 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7648 _mmethod = getattr( Mesh, algo.meshMethod )
7649 if hasattr( _mmethod, "add" ):