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":
2640 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2642 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2643 # simplification of access in geomBuilder: omniORB.registerObjref
2644 from SHAPERSTUDY_utils import getEngine
2647 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2649 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2650 return self._groupTypeFromShape( sub[0] )
2652 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2655 def GroupOnFilter(self, typ, name, filter):
2657 Create a mesh group with given *name* based on the *filter*.
2658 It is a special type of group dynamically updating it's contents during
2662 typ: the type of elements in the group; either of
2663 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2664 name: the name of the mesh group
2665 filter (SMESH.Filter): the filter defining group contents
2668 :class:`SMESH.SMESH_GroupOnFilter`
2671 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2673 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2675 Create a mesh group by the given ids of elements
2678 groupName: the name of the mesh group
2679 elementType: the type of elements in the group; either of
2680 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2681 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2684 :class:`SMESH.SMESH_Group`
2687 group = self.mesh.CreateGroup(elementType, groupName)
2688 if isinstance( elemIDs, Mesh ):
2689 elemIDs = elemIDs.GetMesh()
2690 if hasattr( elemIDs, "GetIDs" ):
2691 if hasattr( elemIDs, "SetMesh" ):
2692 elemIDs.SetMesh( self.GetMesh() )
2693 group.AddFrom( elemIDs )
2701 CritType=FT_Undefined,
2704 UnaryOp=FT_Undefined,
2707 Create a mesh group by the given conditions
2710 groupName: the name of the mesh group
2711 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2712 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2713 Note that the items starting from FT_LessThan are not suitable for CritType.
2714 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2715 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2716 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2717 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2718 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2721 :class:`SMESH.SMESH_GroupOnFilter`
2724 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2725 group = self.MakeGroupByCriterion(groupName, aCriterion)
2728 def MakeGroupByCriterion(self, groupName, Criterion):
2730 Create a mesh group by the given criterion
2733 groupName: the name of the mesh group
2734 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2737 :class:`SMESH.SMESH_GroupOnFilter`
2740 :meth:`smeshBuilder.GetCriterion`
2743 return self.MakeGroupByCriteria( groupName, [Criterion] )
2745 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2747 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2750 groupName: the name of the mesh group
2751 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2752 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2755 :class:`SMESH.SMESH_GroupOnFilter`
2758 :meth:`smeshBuilder.GetCriterion`
2761 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2762 group = self.MakeGroupByFilter(groupName, aFilter)
2765 def MakeGroupByFilter(self, groupName, theFilter):
2767 Create a mesh group by the given filter
2770 groupName (string): the name of the mesh group
2771 theFilter (SMESH.Filter): the filter
2774 :class:`SMESH.SMESH_GroupOnFilter`
2777 :meth:`smeshBuilder.GetFilter`
2780 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2781 #theFilter.SetMesh( self.mesh )
2782 #group.AddFrom( theFilter )
2783 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2786 def RemoveGroup(self, group):
2791 group (SMESH.SMESH_GroupBase): group to remove
2794 self.mesh.RemoveGroup(group)
2796 def RemoveGroupWithContents(self, group):
2798 Remove a group with its contents
2801 group (SMESH.SMESH_GroupBase): group to remove
2804 This operation can create gaps in numeration of nodes or elements.
2805 Call :meth:`RenumberElements` to remove the gaps.
2808 self.mesh.RemoveGroupWithContents(group)
2810 def GetGroups(self, elemType = SMESH.ALL):
2812 Get the list of groups existing in the mesh in the order of creation
2813 (starting from the oldest one)
2816 elemType (SMESH.ElementType): type of elements the groups contain;
2817 by default groups of elements of all types are returned
2820 a list of :class:`SMESH.SMESH_GroupBase`
2823 groups = self.mesh.GetGroups()
2824 if elemType == SMESH.ALL:
2828 if g.GetType() == elemType:
2829 typedGroups.append( g )
2836 Get the number of groups existing in the mesh
2839 the quantity of groups as an integer value
2842 return self.mesh.NbGroups()
2844 def GetGroupNames(self):
2846 Get the list of names of groups existing in the mesh
2852 groups = self.GetGroups()
2854 for group in groups:
2855 names.append(group.GetName())
2858 def GetGroupByName(self, name, elemType = None):
2860 Find groups by name and type
2863 name (string): name of the group of interest
2864 elemType (SMESH.ElementType): type of elements the groups contain;
2865 by default one group of any type is returned;
2866 if elemType == SMESH.ALL then all groups of any type are returned
2869 a list of :class:`SMESH.SMESH_GroupBase`
2873 for group in self.GetGroups():
2874 if group.GetName() == name:
2875 if elemType is None:
2877 if ( elemType == SMESH.ALL or
2878 group.GetType() == elemType ):
2879 groups.append( group )
2882 def UnionGroups(self, group1, group2, name):
2884 Produce a union of two groups.
2885 A new group is created. All mesh elements that are
2886 present in the initial groups are added to the new one
2889 group1 (SMESH.SMESH_GroupBase): a group
2890 group2 (SMESH.SMESH_GroupBase): another group
2893 instance of :class:`SMESH.SMESH_Group`
2896 return self.mesh.UnionGroups(group1, group2, name)
2898 def UnionListOfGroups(self, groups, name):
2900 Produce a union list of groups.
2901 New group is created. All mesh elements that are present in
2902 initial groups are added to the new one
2905 groups: list of :class:`SMESH.SMESH_GroupBase`
2908 instance of :class:`SMESH.SMESH_Group`
2910 return self.mesh.UnionListOfGroups(groups, name)
2912 def IntersectGroups(self, group1, group2, name):
2914 Prodice an intersection of two groups.
2915 A new group is created. All mesh elements that are common
2916 for the two initial groups are added to the new one.
2919 group1 (SMESH.SMESH_GroupBase): a group
2920 group2 (SMESH.SMESH_GroupBase): another group
2923 instance of :class:`SMESH.SMESH_Group`
2926 return self.mesh.IntersectGroups(group1, group2, name)
2928 def IntersectListOfGroups(self, groups, name):
2930 Produce an intersection of groups.
2931 New group is created. All mesh elements that are present in all
2932 initial groups simultaneously are added to the new one
2935 groups: a list of :class:`SMESH.SMESH_GroupBase`
2938 instance of :class:`SMESH.SMESH_Group`
2940 return self.mesh.IntersectListOfGroups(groups, name)
2942 def CutGroups(self, main_group, tool_group, name):
2944 Produce a cut of two groups.
2945 A new group is created. All mesh elements that are present in
2946 the main group but are not present in the tool group are added to the new one
2949 main_group (SMESH.SMESH_GroupBase): a group to cut from
2950 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2953 an instance of :class:`SMESH.SMESH_Group`
2956 return self.mesh.CutGroups(main_group, tool_group, name)
2958 def CutListOfGroups(self, main_groups, tool_groups, name):
2960 Produce a cut of groups.
2961 A new group is created. All mesh elements that are present in main groups
2962 but do not present in tool groups are added to the new one
2965 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2966 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2969 an instance of :class:`SMESH.SMESH_Group`
2972 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2974 def CreateDimGroup(self, groups, elemType, name,
2975 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2977 Create a standalone group of entities basing on nodes of other groups.
2980 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2981 elemType: a type of elements to include to the new group; either of
2982 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2983 name: a name of the new group.
2984 nbCommonNodes: a criterion of inclusion of an element to the new group
2985 basing on number of element nodes common with reference *groups*.
2986 Meaning of possible values are:
2988 - SMESH.ALL_NODES - include if all nodes are common,
2989 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2990 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2991 - SMEHS.MAJORITY - include if half of nodes or more are common.
2992 underlyingOnly: if *True* (default), an element is included to the
2993 new group provided that it is based on nodes of an element of *groups*;
2994 in this case the reference *groups* are supposed to be of higher dimension
2995 than *elemType*, which can be useful for example to get all faces lying on
2996 volumes of the reference *groups*.
2999 an instance of :class:`SMESH.SMESH_Group`
3002 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3004 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3006 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3008 Distribute all faces of the mesh among groups using sharp edges and optionally
3009 existing 1D elements as group boundaries.
3012 sharpAngle: edge is considered sharp if an angle between normals of
3013 adjacent faces is more than \a sharpAngle in degrees.
3014 createEdges (boolean): to create 1D elements for detected sharp edges.
3015 useExistingEdges (boolean): to use existing edges as group boundaries
3017 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3019 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3020 self.mesh.SetParameters(Parameters)
3021 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3023 def ConvertToStandalone(self, group):
3025 Convert group on geom into standalone group
3028 return self.mesh.ConvertToStandalone(group)
3030 # Get some info about mesh:
3031 # ------------------------
3033 def GetLog(self, clearAfterGet):
3035 Return the log of nodes and elements added or removed
3036 since the previous clear of the log.
3039 clearAfterGet: log is emptied after Get (safe if concurrents access)
3042 list of SMESH.log_block structures { commandType, number, coords, indexes }
3045 return self.mesh.GetLog(clearAfterGet)
3049 Clear the log of nodes and elements added or removed since the previous
3050 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3053 self.mesh.ClearLog()
3055 def SetAutoColor(self, theAutoColor):
3057 Toggle auto color mode on the object.
3058 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3061 theAutoColor (boolean): the flag which toggles auto color mode.
3064 self.mesh.SetAutoColor(theAutoColor)
3066 def GetAutoColor(self):
3068 Get flag of object auto color mode.
3074 return self.mesh.GetAutoColor()
3081 integer value, which is the internal Id of the mesh
3084 return self.mesh.GetId()
3086 def HasDuplicatedGroupNamesMED(self):
3088 Check the group names for duplications.
3089 Consider the maximum group name length stored in MED file.
3095 return self.mesh.HasDuplicatedGroupNamesMED()
3097 def GetMeshEditor(self):
3099 Obtain the mesh editor tool
3102 an instance of :class:`SMESH.SMESH_MeshEditor`
3107 def GetIDSource(self, ids, elemType = SMESH.ALL):
3109 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3110 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3114 elemType: type of elements; this parameter is used to distinguish
3115 IDs of nodes from IDs of elements; by default ids are treated as
3116 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3119 an instance of :class:`SMESH.SMESH_IDSource`
3122 call UnRegister() for the returned object as soon as it is no more useful::
3124 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3125 mesh.DoSomething( idSrc )
3129 if isinstance( ids, int ):
3131 return self.editor.MakeIDSource(ids, elemType)
3134 # Get information about mesh contents:
3135 # ------------------------------------
3137 def GetMeshInfo(self, obj = None):
3139 Get the mesh statistic.
3142 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3145 if not obj: obj = self.mesh
3146 return self.smeshpyD.GetMeshInfo(obj)
3150 Return the number of nodes in the mesh
3156 return self.mesh.NbNodes()
3158 def NbElements(self):
3160 Return the number of elements in the mesh
3166 return self.mesh.NbElements()
3168 def Nb0DElements(self):
3170 Return the number of 0d elements in the mesh
3176 return self.mesh.Nb0DElements()
3180 Return the number of ball discrete elements in the mesh
3186 return self.mesh.NbBalls()
3190 Return the number of edges in the mesh
3196 return self.mesh.NbEdges()
3198 def NbEdgesOfOrder(self, elementOrder):
3200 Return the number of edges with the given order in the mesh
3203 elementOrder: the order of elements
3204 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3210 return self.mesh.NbEdgesOfOrder(elementOrder)
3214 Return the number of faces in the mesh
3220 return self.mesh.NbFaces()
3222 def NbFacesOfOrder(self, elementOrder):
3224 Return the number of faces with the given order in the mesh
3227 elementOrder: the order of elements
3228 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3234 return self.mesh.NbFacesOfOrder(elementOrder)
3236 def NbTriangles(self):
3238 Return the number of triangles in the mesh
3244 return self.mesh.NbTriangles()
3246 def NbTrianglesOfOrder(self, elementOrder):
3248 Return the number of triangles with the given order in the mesh
3251 elementOrder: is the order of elements
3252 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3258 return self.mesh.NbTrianglesOfOrder(elementOrder)
3260 def NbBiQuadTriangles(self):
3262 Return the number of biquadratic triangles in the mesh
3268 return self.mesh.NbBiQuadTriangles()
3270 def NbQuadrangles(self):
3272 Return the number of quadrangles in the mesh
3278 return self.mesh.NbQuadrangles()
3280 def NbQuadranglesOfOrder(self, elementOrder):
3282 Return the number of quadrangles with the given order in the mesh
3285 elementOrder: the order of elements
3286 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3292 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3294 def NbBiQuadQuadrangles(self):
3296 Return the number of biquadratic quadrangles in the mesh
3302 return self.mesh.NbBiQuadQuadrangles()
3304 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3306 Return the number of polygons of given order in the mesh
3309 elementOrder: the order of elements
3310 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3316 return self.mesh.NbPolygonsOfOrder(elementOrder)
3318 def NbVolumes(self):
3320 Return the number of volumes in the mesh
3326 return self.mesh.NbVolumes()
3329 def NbVolumesOfOrder(self, elementOrder):
3331 Return the number of volumes with the given order in the mesh
3334 elementOrder: the order of elements
3335 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3341 return self.mesh.NbVolumesOfOrder(elementOrder)
3345 Return the number of tetrahedrons in the mesh
3351 return self.mesh.NbTetras()
3353 def NbTetrasOfOrder(self, elementOrder):
3355 Return the number of tetrahedrons with the given order in the mesh
3358 elementOrder: the order of elements
3359 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3365 return self.mesh.NbTetrasOfOrder(elementOrder)
3369 Return the number of hexahedrons in the mesh
3375 return self.mesh.NbHexas()
3377 def NbHexasOfOrder(self, elementOrder):
3379 Return the number of hexahedrons with the given order in the mesh
3382 elementOrder: the order of elements
3383 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3389 return self.mesh.NbHexasOfOrder(elementOrder)
3391 def NbTriQuadraticHexas(self):
3393 Return the number of triquadratic hexahedrons in the mesh
3399 return self.mesh.NbTriQuadraticHexas()
3401 def NbPyramids(self):
3403 Return the number of pyramids in the mesh
3409 return self.mesh.NbPyramids()
3411 def NbPyramidsOfOrder(self, elementOrder):
3413 Return the number of pyramids with the given order in the mesh
3416 elementOrder: the order of elements
3417 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3423 return self.mesh.NbPyramidsOfOrder(elementOrder)
3427 Return the number of prisms in the mesh
3433 return self.mesh.NbPrisms()
3435 def NbPrismsOfOrder(self, elementOrder):
3437 Return the number of prisms with the given order in the mesh
3440 elementOrder: the order of elements
3441 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3447 return self.mesh.NbPrismsOfOrder(elementOrder)
3449 def NbHexagonalPrisms(self):
3451 Return the number of hexagonal prisms in the mesh
3457 return self.mesh.NbHexagonalPrisms()
3459 def NbPolyhedrons(self):
3461 Return the number of polyhedrons in the mesh
3467 return self.mesh.NbPolyhedrons()
3469 def NbSubMesh(self):
3471 Return the number of submeshes in the mesh
3477 return self.mesh.NbSubMesh()
3479 def GetElementsId(self):
3481 Return the list of all mesh elements IDs
3484 the list of integer values
3487 :meth:`GetElementsByType`
3490 return self.mesh.GetElementsId()
3492 def GetElementsByType(self, elementType):
3494 Return the list of IDs of mesh elements with the given type
3497 elementType (SMESH.ElementType): the required type of elements
3500 list of integer values
3503 return self.mesh.GetElementsByType(elementType)
3505 def GetNodesId(self):
3507 Return the list of mesh nodes IDs
3510 the list of integer values
3513 return self.mesh.GetNodesId()
3515 # Get the information about mesh elements:
3516 # ------------------------------------
3518 def GetElementType(self, id, iselem=True):
3520 Return the type of mesh element or node
3523 the value from :class:`SMESH.ElementType` enumeration.
3524 Return SMESH.ALL if element or node with the given ID does not exist
3527 return self.mesh.GetElementType(id, iselem)
3529 def GetElementGeomType(self, id):
3531 Return the geometric type of mesh element
3534 the value from :class:`SMESH.EntityType` enumeration.
3537 return self.mesh.GetElementGeomType(id)
3539 def GetElementShape(self, id):
3541 Return the shape type of mesh element
3544 the value from :class:`SMESH.GeometryType` enumeration.
3547 return self.mesh.GetElementShape(id)
3549 def GetSubMeshElementsId(self, Shape):
3551 Return the list of sub-mesh elements IDs
3554 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3555 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3558 list of integer values
3561 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3562 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3565 return self.mesh.GetSubMeshElementsId(ShapeID)
3567 def GetSubMeshNodesId(self, Shape, all):
3569 Return the list of sub-mesh nodes IDs
3572 Shape: a geom object (sub-shape).
3573 *Shape* must be the sub-shape of a :meth:`GetShape`
3574 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3577 list of integer values
3580 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3581 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3584 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3586 def GetSubMeshElementType(self, Shape):
3588 Return type of elements on given shape
3591 Shape: a geom object (sub-shape).
3592 *Shape* must be a sub-shape of a ShapeToMesh()
3595 :class:`SMESH.ElementType`
3598 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3599 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3602 return self.mesh.GetSubMeshElementType(ShapeID)
3606 Get the mesh description
3612 return self.mesh.Dump()
3615 # Get the information about nodes and elements of a mesh by its IDs:
3616 # -----------------------------------------------------------
3618 def GetNodeXYZ(self, id):
3620 Get XYZ coordinates of a node.
3621 If there is no node for the given ID - return an empty list
3624 list of float values
3627 return self.mesh.GetNodeXYZ(id)
3629 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3631 Return list of IDs of inverse elements for the given node.
3632 If there is no node for the given ID - return an empty list
3636 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3639 list of integer values
3642 return self.mesh.GetNodeInverseElements(id,elemType)
3644 def GetNodePosition(self,NodeID):
3646 Return the position of a node on the shape
3649 :class:`SMESH.NodePosition`
3652 return self.mesh.GetNodePosition(NodeID)
3654 def GetElementPosition(self,ElemID):
3656 Return the position of an element on the shape
3659 :class:`SMESH.ElementPosition`
3662 return self.mesh.GetElementPosition(ElemID)
3664 def GetShapeID(self, id):
3666 Return the ID of the shape, on which the given node was generated.
3669 an integer value > 0 or -1 if there is no node for the given
3670 ID or the node is not assigned to any geometry
3673 return self.mesh.GetShapeID(id)
3675 def GetShapeIDForElem(self,id):
3677 Return the ID of the shape, on which the given element was generated.
3680 an integer value > 0 or -1 if there is no element for the given
3681 ID or the element is not assigned to any geometry
3684 return self.mesh.GetShapeIDForElem(id)
3686 def GetElemNbNodes(self, id):
3688 Return the number of nodes of the given element
3691 an integer value > 0 or -1 if there is no element for the given ID
3694 return self.mesh.GetElemNbNodes(id)
3696 def GetElemNode(self, id, index):
3698 Return the node ID the given (zero based) index for the given element.
3700 * If there is no element for the given ID - return -1.
3701 * If there is no node for the given index - return -2.
3704 id (int): element ID
3705 index (int): node index within the element
3708 an integer value (ID)
3711 :meth:`GetElemNodes`
3714 return self.mesh.GetElemNode(id, index)
3716 def GetElemNodes(self, id):
3718 Return the IDs of nodes of the given element
3721 a list of integer values
3724 return self.mesh.GetElemNodes(id)
3726 def IsMediumNode(self, elementID, nodeID):
3728 Return true if the given node is the medium node in the given quadratic element
3731 return self.mesh.IsMediumNode(elementID, nodeID)
3733 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3735 Return true if the given node is the medium node in one of quadratic elements
3738 nodeID: ID of the node
3739 elementType: the type of elements to check a state of the node, either of
3740 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3743 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3745 def ElemNbEdges(self, id):
3747 Return the number of edges for the given element
3750 return self.mesh.ElemNbEdges(id)
3752 def ElemNbFaces(self, id):
3754 Return the number of faces for the given element
3757 return self.mesh.ElemNbFaces(id)
3759 def GetElemFaceNodes(self,elemId, faceIndex):
3761 Return nodes of given face (counted from zero) for given volumic element.
3764 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3766 def GetFaceNormal(self, faceId, normalized=False):
3768 Return three components of normal of given mesh face
3769 (or an empty array in KO case)
3772 return self.mesh.GetFaceNormal(faceId,normalized)
3774 def FindElementByNodes(self, nodes):
3776 Return an element based on all given nodes.
3779 return self.mesh.FindElementByNodes(nodes)
3781 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3783 Return elements including all given nodes.
3786 return self.mesh.GetElementsByNodes( nodes, elemType )
3788 def IsPoly(self, id):
3790 Return true if the given element is a polygon
3793 return self.mesh.IsPoly(id)
3795 def IsQuadratic(self, id):
3797 Return true if the given element is quadratic
3800 return self.mesh.IsQuadratic(id)
3802 def GetBallDiameter(self, id):
3804 Return diameter of a ball discrete element or zero in case of an invalid *id*
3807 return self.mesh.GetBallDiameter(id)
3809 def BaryCenter(self, id):
3811 Return XYZ coordinates of the barycenter of the given element.
3812 If there is no element for the given ID - return an empty list
3815 a list of three double values
3818 :meth:`smeshBuilder.GetGravityCenter`
3821 return self.mesh.BaryCenter(id)
3823 def GetIdsFromFilter(self, filter, meshParts=[] ):
3825 Pass mesh elements through the given filter and return IDs of fitting elements
3828 filter: :class:`SMESH.Filter`
3829 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3835 :meth:`SMESH.Filter.GetIDs`
3836 :meth:`SMESH.Filter.GetElementsIdFromParts`
3839 filter.SetMesh( self.mesh )
3842 if isinstance( meshParts, Mesh ):
3843 filter.SetMesh( meshParts.GetMesh() )
3844 return theFilter.GetIDs()
3845 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3846 meshParts = [ meshParts ]
3847 return filter.GetElementsIdFromParts( meshParts )
3849 return filter.GetIDs()
3851 # Get mesh measurements information:
3852 # ------------------------------------
3854 def GetFreeBorders(self):
3856 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3857 Return a list of special structures (borders).
3860 a list of :class:`SMESH.FreeEdges.Border`
3863 aFilterMgr = self.smeshpyD.CreateFilterManager()
3864 aPredicate = aFilterMgr.CreateFreeEdges()
3865 aPredicate.SetMesh(self.mesh)
3866 aBorders = aPredicate.GetBorders()
3867 aFilterMgr.UnRegister()
3870 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3872 Get minimum distance between two nodes, elements or distance to the origin
3875 id1: first node/element id
3876 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3877 isElem1: *True* if *id1* is element id, *False* if it is node id
3878 isElem2: *True* if *id2* is element id, *False* if it is node id
3881 minimum distance value
3883 :meth:`GetMinDistance`
3886 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3887 return aMeasure.value
3889 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3891 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3894 id1: first node/element id
3895 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3896 isElem1: *True* if *id1* is element id, *False* if it is node id
3897 isElem2: *True* if *id2* is element id, *False* if it is node id
3900 :class:`SMESH.Measure` structure
3906 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3908 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3911 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3913 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3918 aMeasurements = self.smeshpyD.CreateMeasurements()
3919 aMeasure = aMeasurements.MinDistance(id1, id2)
3920 genObjUnRegister([aMeasurements,id1, id2])
3923 def BoundingBox(self, objects=None, isElem=False):
3925 Get bounding box of the specified object(s)
3928 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3929 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3930 *False* specifies that *objects* are nodes
3933 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3936 :meth:`GetBoundingBox()`
3939 result = self.GetBoundingBox(objects, isElem)
3943 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3946 def GetBoundingBox(self, objects=None, isElem=False):
3948 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3951 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3952 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3953 False means that *objects* are nodes
3956 :class:`SMESH.Measure` structure
3959 :meth:`BoundingBox()`
3963 objects = [self.mesh]
3964 elif isinstance(objects, tuple):
3965 objects = list(objects)
3966 if not isinstance(objects, list):
3968 if len(objects) > 0 and isinstance(objects[0], int):
3971 unRegister = genObjUnRegister()
3973 if isinstance(o, Mesh):
3974 srclist.append(o.mesh)
3975 elif hasattr(o, "_narrow"):
3976 src = o._narrow(SMESH.SMESH_IDSource)
3977 if src: srclist.append(src)
3979 elif isinstance(o, list):
3981 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3983 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3984 unRegister.set( srclist[-1] )
3987 aMeasurements = self.smeshpyD.CreateMeasurements()
3988 unRegister.set( aMeasurements )
3989 aMeasure = aMeasurements.BoundingBox(srclist)
3992 # Mesh edition (SMESH_MeshEditor functionality):
3993 # ---------------------------------------------
3995 def RemoveElements(self, IDsOfElements):
3997 Remove the elements from the mesh by ids
4000 IDsOfElements: is a list of ids of elements to remove
4006 This operation can create gaps in numeration of elements.
4007 Call :meth:`RenumberElements` to remove the gaps.
4010 return self.editor.RemoveElements(IDsOfElements)
4012 def RemoveNodes(self, IDsOfNodes):
4014 Remove nodes from mesh by ids
4017 IDsOfNodes: is a list of ids of nodes to remove
4023 This operation can create gaps in numeration of nodes.
4024 Call :meth:`RenumberElements` to remove the gaps.
4027 return self.editor.RemoveNodes(IDsOfNodes)
4029 def RemoveOrphanNodes(self):
4031 Remove all orphan (free) nodes from mesh
4034 number of the removed nodes
4037 This operation can create gaps in numeration of nodes.
4038 Call :meth:`RenumberElements` to remove the gaps.
4041 return self.editor.RemoveOrphanNodes()
4043 def AddNode(self, x, y, z):
4045 Add a node to the mesh by coordinates
4051 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4052 if hasVars: self.mesh.SetParameters(Parameters)
4053 return self.editor.AddNode( x, y, z)
4055 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4057 Create a 0D element on a node with given number.
4060 IDOfNode: the ID of node for creation of the element.
4061 DuplicateElements: to add one more 0D element to a node or not
4064 ID of the new 0D element
4067 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4069 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4071 Create 0D elements on all nodes of the given elements except those
4072 nodes on which a 0D element already exists.
4075 theObject: an object on whose nodes 0D elements will be created.
4076 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4077 theGroupName: optional name of a group to add 0D elements created
4078 and/or found on nodes of *theObject*.
4079 DuplicateElements: to add one more 0D element to a node or not
4082 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4083 IDs of new and/or found 0D elements. IDs of 0D elements
4084 can be retrieved from the returned object by
4085 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4088 unRegister = genObjUnRegister()
4089 if isinstance( theObject, Mesh ):
4090 theObject = theObject.GetMesh()
4091 elif isinstance( theObject, list ):
4092 theObject = self.GetIDSource( theObject, SMESH.ALL )
4093 unRegister.set( theObject )
4094 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4096 def AddBall(self, IDOfNode, diameter):
4098 Create a ball element on a node with given ID.
4101 IDOfNode: the ID of node for creation of the element.
4102 diameter: the bal diameter.
4105 ID of the new ball element
4108 return self.editor.AddBall( IDOfNode, diameter )
4110 def AddEdge(self, IDsOfNodes):
4112 Create a linear or quadratic edge (this is determined
4113 by the number of given nodes).
4116 IDsOfNodes: list of node IDs for creation of the element.
4117 The order of nodes in this list should correspond to
4118 the :ref:`connectivity convention <connectivity_page>`.
4124 return self.editor.AddEdge(IDsOfNodes)
4126 def AddFace(self, IDsOfNodes):
4128 Create a linear or quadratic face (this is determined
4129 by the number of given nodes).
4132 IDsOfNodes: list of node IDs for creation of the element.
4133 The order of nodes in this list should correspond to
4134 the :ref:`connectivity convention <connectivity_page>`.
4140 return self.editor.AddFace(IDsOfNodes)
4142 def AddPolygonalFace(self, IdsOfNodes):
4144 Add a polygonal face defined by a list of node IDs
4147 IdsOfNodes: the list of node IDs for creation of the element.
4153 return self.editor.AddPolygonalFace(IdsOfNodes)
4155 def AddQuadPolygonalFace(self, IdsOfNodes):
4157 Add a quadratic polygonal face defined by a list of node IDs
4160 IdsOfNodes: the list of node IDs for creation of the element;
4161 corner nodes follow first.
4167 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4169 def AddVolume(self, IDsOfNodes):
4171 Create both simple and quadratic volume (this is determined
4172 by the number of given nodes).
4175 IDsOfNodes: list of node IDs for creation of the element.
4176 The order of nodes in this list should correspond to
4177 the :ref:`connectivity convention <connectivity_page>`.
4180 ID of the new volumic element
4183 return self.editor.AddVolume(IDsOfNodes)
4185 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4187 Create a volume of many faces, giving nodes for each face.
4190 IdsOfNodes: list of node IDs for volume creation, face by face.
4191 Quantities: list of integer values, Quantities[i]
4192 gives the quantity of nodes in face number i.
4195 ID of the new volumic element
4198 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4200 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4202 Create a volume of many faces, giving the IDs of the existing faces.
4205 The created volume will refer only to the nodes
4206 of the given faces, not to the faces themselves.
4209 IdsOfFaces: the list of face IDs for volume creation.
4212 ID of the new volumic element
4215 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4218 def SetNodeOnVertex(self, NodeID, Vertex):
4220 Bind a node to a vertex
4224 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4227 True if succeed else raises an exception
4230 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4231 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4235 self.editor.SetNodeOnVertex(NodeID, VertexID)
4236 except SALOME.SALOME_Exception as inst:
4237 raise ValueError(inst.details.text)
4241 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4243 Store the node position on an edge
4247 Edge: an edge (GEOM.GEOM_Object) or edge ID
4248 paramOnEdge: a parameter on the edge where the node is located
4251 True if succeed else raises an exception
4254 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4255 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4259 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4260 except SALOME.SALOME_Exception as inst:
4261 raise ValueError(inst.details.text)
4264 def SetNodeOnFace(self, NodeID, Face, u, v):
4266 Store node position on a face
4270 Face: a face (GEOM.GEOM_Object) or face ID
4271 u: U parameter on the face where the node is located
4272 v: V parameter on the face where the node is located
4275 True if succeed else raises an exception
4278 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4279 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4283 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4284 except SALOME.SALOME_Exception as inst:
4285 raise ValueError(inst.details.text)
4288 def SetNodeInVolume(self, NodeID, Solid):
4290 Bind a node to a solid
4294 Solid: a solid (GEOM.GEOM_Object) or solid ID
4297 True if succeed else raises an exception
4300 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4301 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4305 self.editor.SetNodeInVolume(NodeID, SolidID)
4306 except SALOME.SALOME_Exception as inst:
4307 raise ValueError(inst.details.text)
4310 def SetMeshElementOnShape(self, ElementID, Shape):
4312 Bind an element to a shape
4315 ElementID: an element ID
4316 Shape: a shape (GEOM.GEOM_Object) or shape ID
4319 True if succeed else raises an exception
4322 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4323 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4327 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4328 except SALOME.SALOME_Exception as inst:
4329 raise ValueError(inst.details.text)
4333 def MoveNode(self, NodeID, x, y, z):
4335 Move the node with the given id
4338 NodeID: the id of the node
4339 x: a new X coordinate
4340 y: a new Y coordinate
4341 z: a new Z coordinate
4344 True if succeed else False
4347 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4348 if hasVars: self.mesh.SetParameters(Parameters)
4349 return self.editor.MoveNode(NodeID, x, y, z)
4351 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4353 Find the node closest to a point and moves it to a point location
4356 x: the X coordinate of a point
4357 y: the Y coordinate of a point
4358 z: the Z coordinate of a point
4359 NodeID: if specified (>0), the node with this ID is moved,
4360 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4363 the ID of a moved node
4366 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4367 if hasVars: self.mesh.SetParameters(Parameters)
4368 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4370 def FindNodeClosestTo(self, x, y, z):
4372 Find the node closest to a point
4375 x: the X coordinate of a point
4376 y: the Y coordinate of a point
4377 z: the Z coordinate of a point
4383 return self.editor.FindNodeClosestTo(x, y, z)
4385 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4387 Find the elements where a point lays IN or ON
4390 x,y,z (float): coordinates of the point
4391 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4392 means elements of any type excluding nodes, discrete and 0D elements.
4393 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4396 list of IDs of found elements
4399 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4401 return self.editor.FindElementsByPoint(x, y, z, elementType)
4403 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4405 Project a point to a mesh object.
4406 Return ID of an element of given type where the given point is projected
4407 and coordinates of the projection point.
4408 In the case if nothing found, return -1 and []
4410 if isinstance( meshObject, Mesh ):
4411 meshObject = meshObject.GetMesh()
4413 meshObject = self.GetMesh()
4414 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4416 def GetPointState(self, x, y, z):
4418 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4419 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4420 UNKNOWN state means that either mesh is wrong or the analysis fails.
4423 return self.editor.GetPointState(x, y, z)
4425 def IsManifold(self):
4427 Check if a 2D mesh is manifold
4430 return self.editor.IsManifold()
4432 def IsCoherentOrientation2D(self):
4434 Check if orientation of 2D elements is coherent
4437 return self.editor.IsCoherentOrientation2D()
4439 def Get1DBranches( self, edges, startNode = 0 ):
4441 Partition given 1D elements into groups of contiguous edges.
4442 A node where number of meeting edges != 2 is a group end.
4443 An optional startNode is used to orient groups it belongs to.
4446 A list of edge groups and a list of corresponding node groups,
4447 where the group is a list of IDs of edges or elements, like follows
4448 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4449 If a group is closed, the first and last nodes of the group are same.
4451 if isinstance( edges, Mesh ):
4452 edges = edges.GetMesh()
4453 unRegister = genObjUnRegister()
4454 if isinstance( edges, list ):
4455 edges = self.GetIDSource( edges, SMESH.EDGE )
4456 unRegister.set( edges )
4457 return self.editor.Get1DBranches( edges, startNode )
4459 def FindSharpEdges( self, angle, addExisting=False ):
4461 Return sharp edges of faces and non-manifold ones.
4462 Optionally add existing edges.
4465 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4466 addExisting: to return existing edges (1D elements) as well
4469 list of FaceEdge structures
4471 angle = ParseParameters( angle )[0]
4472 return self.editor.FindSharpEdges( angle, addExisting )
4474 def MeshToPassThroughAPoint(self, x, y, z):
4476 Find the node closest to a point and moves it to a point location
4479 x: the X coordinate of a point
4480 y: the Y coordinate of a point
4481 z: the Z coordinate of a point
4484 the ID of a moved node
4487 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4489 def InverseDiag(self, NodeID1, NodeID2):
4491 Replace two neighbour triangles sharing Node1-Node2 link
4492 with the triangles built on the same 4 nodes but having other common link.
4495 NodeID1: the ID of the first node
4496 NodeID2: the ID of the second node
4499 False if proper faces were not found
4501 return self.editor.InverseDiag(NodeID1, NodeID2)
4503 def DeleteDiag(self, NodeID1, NodeID2):
4505 Replace two neighbour triangles sharing *Node1-Node2* link
4506 with a quadrangle built on the same 4 nodes.
4509 NodeID1: ID of the first node
4510 NodeID2: ID of the second node
4513 False if proper faces were not found
4516 This operation can create gaps in numeration of elements.
4517 Call :meth:`RenumberElements` to remove the gaps.
4520 return self.editor.DeleteDiag(NodeID1, NodeID2)
4522 def Reorient(self, IDsOfElements=None):
4524 Reorient elements by ids
4527 IDsOfElements: if undefined reorients all mesh elements
4530 True if succeed else False
4533 if IDsOfElements == None:
4534 IDsOfElements = self.GetElementsId()
4535 return self.editor.Reorient(IDsOfElements)
4537 def ReorientObject(self, theObject):
4539 Reorient all elements of the object
4542 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4545 True if succeed else False
4548 if ( isinstance( theObject, Mesh )):
4549 theObject = theObject.GetMesh()
4550 return self.editor.ReorientObject(theObject)
4552 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4554 Reorient faces contained in *the2DObject*.
4557 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4558 theDirection: a desired direction of normal of *theFace*.
4559 It can be either a GEOM vector or a list of coordinates [x,y,z].
4560 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4561 compared with theDirection. It can be either ID of face or a point
4562 by which the face will be found. The point can be given as either
4563 a GEOM vertex or a list of point coordinates.
4566 number of reoriented faces
4569 unRegister = genObjUnRegister()
4571 if isinstance( the2DObject, Mesh ):
4572 the2DObject = the2DObject.GetMesh()
4573 if isinstance( the2DObject, list ):
4574 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4575 unRegister.set( the2DObject )
4576 # check theDirection
4577 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4578 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4579 if isinstance( theDirection, list ):
4580 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4581 # prepare theFace and thePoint
4582 theFace = theFaceOrPoint
4583 thePoint = PointStruct(0,0,0)
4584 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4585 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4587 if isinstance( theFaceOrPoint, list ):
4588 thePoint = PointStruct( *theFaceOrPoint )
4590 if isinstance( theFaceOrPoint, PointStruct ):
4591 thePoint = theFaceOrPoint
4593 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4595 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4597 Reorient faces according to adjacent volumes.
4600 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4601 either IDs of faces or face groups.
4602 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4603 theOutsideNormal: to orient faces to have their normals
4604 pointing either *outside* or *inside* the adjacent volumes.
4607 number of reoriented faces.
4610 unRegister = genObjUnRegister()
4612 if not isinstance( the2DObject, list ):
4613 the2DObject = [ the2DObject ]
4614 elif the2DObject and isinstance( the2DObject[0], int ):
4615 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4616 unRegister.set( the2DObject )
4617 the2DObject = [ the2DObject ]
4618 for i,obj2D in enumerate( the2DObject ):
4619 if isinstance( obj2D, Mesh ):
4620 the2DObject[i] = obj2D.GetMesh()
4621 if isinstance( obj2D, list ):
4622 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4623 unRegister.set( the2DObject[i] )
4625 if isinstance( the3DObject, Mesh ):
4626 the3DObject = the3DObject.GetMesh()
4627 if isinstance( the3DObject, list ):
4628 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4629 unRegister.set( the3DObject )
4630 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4632 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4634 Fuse the neighbouring triangles into quadrangles.
4637 IDsOfElements: The triangles to be fused.
4638 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4639 applied to possible quadrangles to choose a neighbour to fuse with.
4640 Note that not all items of :class:`SMESH.FunctorType` corresponds
4641 to numerical functors.
4642 MaxAngle: is the maximum angle between element normals at which the fusion
4643 is still performed; theMaxAngle is measured in radians.
4644 Also it could be a name of variable which defines angle in degrees.
4647 True in case of success, False otherwise.
4650 This operation can create gaps in numeration of elements.
4651 Call :meth:`RenumberElements` to remove the gaps.
4654 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4655 self.mesh.SetParameters(Parameters)
4656 if not IDsOfElements:
4657 IDsOfElements = self.GetElementsId()
4658 Functor = self.smeshpyD.GetFunctor(theCriterion)
4659 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4661 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4663 Fuse the neighbouring triangles of the object into quadrangles
4666 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4667 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4668 applied to possible quadrangles to choose a neighbour to fuse with.
4669 Note that not all items of :class:`SMESH.FunctorType` corresponds
4670 to numerical functors.
4671 MaxAngle: a max angle between element normals at which the fusion
4672 is still performed; theMaxAngle is measured in radians.
4675 True in case of success, False otherwise.
4678 This operation can create gaps in numeration of elements.
4679 Call :meth:`RenumberElements` to remove the gaps.
4682 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4683 self.mesh.SetParameters(Parameters)
4684 if isinstance( theObject, Mesh ):
4685 theObject = theObject.GetMesh()
4686 Functor = self.smeshpyD.GetFunctor(theCriterion)
4687 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4689 def QuadToTri (self, IDsOfElements, theCriterion = None):
4691 Split quadrangles into triangles.
4694 IDsOfElements: the faces to be splitted.
4695 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4696 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4697 value, then quadrangles will be split by the smallest diagonal.
4698 Note that not all items of :class:`SMESH.FunctorType` corresponds
4699 to numerical functors.
4702 True in case of success, False otherwise.
4705 This operation can create gaps in numeration of elements.
4706 Call :meth:`RenumberElements` to remove the gaps.
4708 if IDsOfElements == []:
4709 IDsOfElements = self.GetElementsId()
4710 if theCriterion is None:
4711 theCriterion = FT_MaxElementLength2D
4712 Functor = self.smeshpyD.GetFunctor(theCriterion)
4713 return self.editor.QuadToTri(IDsOfElements, Functor)
4715 def QuadToTriObject (self, theObject, theCriterion = None):
4717 Split quadrangles into triangles.
4720 theObject: the object from which the list of elements is taken,
4721 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4722 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4723 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4724 value, then quadrangles will be split by the smallest diagonal.
4725 Note that not all items of :class:`SMESH.FunctorType` corresponds
4726 to numerical functors.
4729 True in case of success, False otherwise.
4732 This operation can create gaps in numeration of elements.
4733 Call :meth:`RenumberElements` to remove the gaps.
4735 if ( isinstance( theObject, Mesh )):
4736 theObject = theObject.GetMesh()
4737 if theCriterion is None:
4738 theCriterion = FT_MaxElementLength2D
4739 Functor = self.smeshpyD.GetFunctor(theCriterion)
4740 return self.editor.QuadToTriObject(theObject, Functor)
4742 def QuadTo4Tri (self, theElements=[]):
4744 Split each of given quadrangles into 4 triangles. A node is added at the center of
4748 theElements: the faces to be splitted. This can be either
4749 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4750 or a list of face IDs. By default all quadrangles are split
4753 This operation can create gaps in numeration of elements.
4754 Call :meth:`RenumberElements` to remove the gaps.
4756 unRegister = genObjUnRegister()
4757 if isinstance( theElements, Mesh ):
4758 theElements = theElements.mesh
4759 elif not theElements:
4760 theElements = self.mesh
4761 elif isinstance( theElements, list ):
4762 theElements = self.GetIDSource( theElements, SMESH.FACE )
4763 unRegister.set( theElements )
4764 return self.editor.QuadTo4Tri( theElements )
4766 def SplitQuad (self, IDsOfElements, Diag13):
4768 Split quadrangles into triangles.
4771 IDsOfElements: the faces to be splitted
4772 Diag13 (boolean): is used to choose a diagonal for splitting.
4775 True in case of success, False otherwise.
4778 This operation can create gaps in numeration of elements.
4779 Call :meth:`RenumberElements` to remove the gaps.
4781 if IDsOfElements == []:
4782 IDsOfElements = self.GetElementsId()
4783 return self.editor.SplitQuad(IDsOfElements, Diag13)
4785 def SplitQuadObject (self, theObject, Diag13):
4787 Split quadrangles into triangles.
4790 theObject: the object from which the list of elements is taken,
4791 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4792 Diag13 (boolean): is used to choose a diagonal for splitting.
4795 True in case of success, False otherwise.
4798 This operation can create gaps in numeration of elements.
4799 Call :meth:`RenumberElements` to remove the gaps.
4801 if ( isinstance( theObject, Mesh )):
4802 theObject = theObject.GetMesh()
4803 return self.editor.SplitQuadObject(theObject, Diag13)
4805 def BestSplit (self, IDOfQuad, theCriterion):
4807 Find a better splitting of the given quadrangle.
4810 IDOfQuad: the ID of the quadrangle to be splitted.
4811 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4812 choose a diagonal for splitting.
4813 Note that not all items of :class:`SMESH.FunctorType` corresponds
4814 to numerical functors.
4817 * 1 if 1-3 diagonal is better,
4818 * 2 if 2-4 diagonal is better,
4819 * 0 if error occurs.
4822 This operation can create gaps in numeration of elements.
4823 Call :meth:`RenumberElements` to remove the gaps.
4825 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4827 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4829 Split volumic elements into tetrahedrons
4832 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4833 method: flags passing splitting method:
4834 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4835 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4838 This operation can create gaps in numeration of elements.
4839 Call :meth:`RenumberElements` to remove the gaps.
4841 unRegister = genObjUnRegister()
4842 if isinstance( elems, Mesh ):
4843 elems = elems.GetMesh()
4844 if ( isinstance( elems, list )):
4845 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4846 unRegister.set( elems )
4847 self.editor.SplitVolumesIntoTetra(elems, method)
4850 def SplitBiQuadraticIntoLinear(self, elems=None):
4852 Split bi-quadratic elements into linear ones without creation of additional nodes:
4854 - bi-quadratic triangle will be split into 3 linear quadrangles;
4855 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4856 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4858 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4859 will be split in order to keep the mesh conformal.
4862 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4863 if None (default), all bi-quadratic elements will be split
4866 This operation can create gaps in numeration of elements.
4867 Call :meth:`RenumberElements` to remove the gaps.
4869 unRegister = genObjUnRegister()
4870 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4871 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4872 unRegister.set( elems )
4874 elems = [ self.GetMesh() ]
4875 if isinstance( elems, Mesh ):
4876 elems = [ elems.GetMesh() ]
4877 if not isinstance( elems, list ):
4879 self.editor.SplitBiQuadraticIntoLinear( elems )
4881 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4882 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4884 Split hexahedra into prisms
4887 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4888 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4889 gives a normal vector defining facets to split into triangles.
4890 *startHexPoint* can be either a triple of coordinates or a vertex.
4891 facetNormal: a normal to a facet to split into triangles of a
4892 hexahedron found by *startHexPoint*.
4893 *facetNormal* can be either a triple of coordinates or an edge.
4894 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4895 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4896 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4897 to *startHexPoint* are split, else *startHexPoint*
4898 is used to find the facet to split in all domains present in *elems*.
4901 This operation can create gaps in numeration of elements.
4902 Call :meth:`RenumberElements` to remove the gaps.
4905 unRegister = genObjUnRegister()
4906 if isinstance( elems, Mesh ):
4907 elems = elems.GetMesh()
4908 if ( isinstance( elems, list )):
4909 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4910 unRegister.set( elems )
4913 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4914 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4915 elif isinstance( startHexPoint, list ):
4916 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4919 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4920 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4921 elif isinstance( facetNormal, list ):
4922 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4925 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4927 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4929 def SplitQuadsNearTriangularFacets(self):
4931 Split quadrangle faces near triangular facets of volumes
4934 This operation can create gaps in numeration of elements.
4935 Call :meth:`RenumberElements` to remove the gaps.
4937 faces_array = self.GetElementsByType(SMESH.FACE)
4938 for face_id in faces_array:
4939 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4940 quad_nodes = self.mesh.GetElemNodes(face_id)
4941 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4942 isVolumeFound = False
4943 for node1_elem in node1_elems:
4944 if not isVolumeFound:
4945 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4946 nb_nodes = self.GetElemNbNodes(node1_elem)
4947 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4948 volume_elem = node1_elem
4949 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4950 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4951 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4952 isVolumeFound = True
4953 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4954 self.SplitQuad([face_id], False) # diagonal 2-4
4955 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4956 isVolumeFound = True
4957 self.SplitQuad([face_id], True) # diagonal 1-3
4958 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4959 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4960 isVolumeFound = True
4961 self.SplitQuad([face_id], True) # diagonal 1-3
4963 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4965 Split hexahedrons into tetrahedrons.
4967 This operation uses :doc:`pattern_mapping` functionality for splitting.
4970 theObject: the object from which the list of hexahedrons is taken;
4971 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4972 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4973 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4974 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4975 key-point will be mapped into *theNode001*-th node of each volume.
4976 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4979 True in case of success, False otherwise.
4982 This operation can create gaps in numeration of elements.
4983 Call :meth:`RenumberElements` to remove the gaps.
4991 # (0,0,1) 4.---------.7 * |
4998 # (0,0,0) 0.---------.3
4999 pattern_tetra = "!!! Nb of points: \n 8 \n\
5009 !!! Indices of points of 6 tetras: \n\
5017 pattern = self.smeshpyD.GetPattern()
5018 isDone = pattern.LoadFromFile(pattern_tetra)
5020 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5023 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5024 isDone = pattern.MakeMesh(self.mesh, False, False)
5025 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5027 # split quafrangle faces near triangular facets of volumes
5028 self.SplitQuadsNearTriangularFacets()
5032 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5034 Split hexahedrons into prisms.
5036 Uses the :doc:`pattern_mapping` functionality for splitting.
5039 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5040 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5041 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5042 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5043 will be mapped into the *theNode001* -th node of each volume.
5044 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5047 True in case of success, False otherwise.
5050 This operation can create gaps in numeration of elements.
5051 Call :meth:`RenumberElements` to remove the gaps.
5053 # Pattern: 5.---------.6
5058 # (0,0,1) 4.---------.7 |
5065 # (0,0,0) 0.---------.3
5066 pattern_prism = "!!! Nb of points: \n 8 \n\
5076 !!! Indices of points of 2 prisms: \n\
5080 pattern = self.smeshpyD.GetPattern()
5081 isDone = pattern.LoadFromFile(pattern_prism)
5083 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5086 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5087 isDone = pattern.MakeMesh(self.mesh, False, False)
5088 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5090 # Split quafrangle faces near triangular facets of volumes
5091 self.SplitQuadsNearTriangularFacets()
5095 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5096 MaxNbOfIterations, MaxAspectRatio, Method):
5101 IDsOfElements: the list if ids of elements to smooth
5102 IDsOfFixedNodes: the list of ids of fixed nodes.
5103 Note that nodes built on edges and boundary nodes are always fixed.
5104 MaxNbOfIterations: the maximum number of iterations
5105 MaxAspectRatio: varies in range [1.0, inf]
5106 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5107 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5110 True in case of success, False otherwise.
5113 if IDsOfElements == []:
5114 IDsOfElements = self.GetElementsId()
5115 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5116 self.mesh.SetParameters(Parameters)
5117 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5118 MaxNbOfIterations, MaxAspectRatio, Method)
5120 def SmoothObject(self, theObject, IDsOfFixedNodes,
5121 MaxNbOfIterations, MaxAspectRatio, Method):
5123 Smooth elements which belong to the given object
5126 theObject: the object to smooth
5127 IDsOfFixedNodes: the list of ids of fixed nodes.
5128 Note that nodes built on edges and boundary nodes are always fixed.
5129 MaxNbOfIterations: the maximum number of iterations
5130 MaxAspectRatio: varies in range [1.0, inf]
5131 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5132 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5135 True in case of success, False otherwise.
5138 if ( isinstance( theObject, Mesh )):
5139 theObject = theObject.GetMesh()
5140 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5141 MaxNbOfIterations, MaxAspectRatio, Method)
5143 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5144 MaxNbOfIterations, MaxAspectRatio, Method):
5146 Parametrically smooth the given elements
5149 IDsOfElements: the list if ids of elements to smooth
5150 IDsOfFixedNodes: the list of ids of fixed nodes.
5151 Note that nodes built on edges and boundary nodes are always fixed.
5152 MaxNbOfIterations: the maximum number of iterations
5153 MaxAspectRatio: varies in range [1.0, inf]
5154 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5155 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5158 True in case of success, False otherwise.
5161 if IDsOfElements == []:
5162 IDsOfElements = self.GetElementsId()
5163 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5164 self.mesh.SetParameters(Parameters)
5165 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5166 MaxNbOfIterations, MaxAspectRatio, Method)
5168 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5169 MaxNbOfIterations, MaxAspectRatio, Method):
5171 Parametrically smooth the elements which belong to the given object
5174 theObject: the object to smooth
5175 IDsOfFixedNodes: the list of ids of fixed nodes.
5176 Note that nodes built on edges and boundary nodes are always fixed.
5177 MaxNbOfIterations: the maximum number of iterations
5178 MaxAspectRatio: varies in range [1.0, inf]
5179 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5180 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5183 True in case of success, False otherwise.
5186 if ( isinstance( theObject, Mesh )):
5187 theObject = theObject.GetMesh()
5188 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5189 MaxNbOfIterations, MaxAspectRatio, Method)
5191 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5193 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5194 them with quadratic with the same id.
5197 theForce3d: method of new node creation:
5199 * False - the medium node lies at the geometrical entity from which the mesh element is built
5200 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5201 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5202 theToBiQuad: If True, converts the mesh to bi-quadratic
5205 :class:`SMESH.ComputeError` which can hold a warning
5208 If *theSubMesh* is provided, the mesh can become non-conformal
5211 This operation can create gaps in numeration of nodes or elements.
5212 Call :meth:`RenumberElements` to remove the gaps.
5215 if isinstance( theSubMesh, Mesh ):
5216 theSubMesh = theSubMesh.mesh
5218 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5221 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5223 self.editor.ConvertToQuadratic(theForce3d)
5224 error = self.editor.GetLastError()
5225 if error and error.comment:
5226 print(error.comment)
5229 def ConvertFromQuadratic(self, theSubMesh=None):
5231 Convert the mesh from quadratic to ordinary,
5232 deletes old quadratic elements,
5233 replacing them with ordinary mesh elements with the same id.
5236 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5239 If *theSubMesh* is provided, the mesh can become non-conformal
5242 This operation can create gaps in numeration of nodes or elements.
5243 Call :meth:`RenumberElements` to remove the gaps.
5247 self.editor.ConvertFromQuadraticObject(theSubMesh)
5249 return self.editor.ConvertFromQuadratic()
5251 def Make2DMeshFrom3D(self):
5253 Create 2D mesh as skin on boundary faces of a 3D mesh
5256 True if operation has been completed successfully, False otherwise
5259 return self.editor.Make2DMeshFrom3D()
5261 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5262 toCopyElements=False, toCopyExistingBondary=False):
5264 Create missing boundary elements
5267 elements: elements whose boundary is to be checked:
5268 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5269 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5270 dimension: defines type of boundary elements to create, either of
5271 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5272 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5273 groupName: a name of group to store created boundary elements in,
5274 "" means not to create the group
5275 meshName: a name of new mesh to store created boundary elements in,
5276 "" means not to create the new mesh
5277 toCopyElements: if True, the checked elements will be copied into
5278 the new mesh else only boundary elements will be copied into the new mesh
5279 toCopyExistingBondary: if True, not only new but also pre-existing
5280 boundary elements will be copied into the new mesh
5283 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5286 unRegister = genObjUnRegister()
5287 if isinstance( elements, Mesh ):
5288 elements = elements.GetMesh()
5289 if ( isinstance( elements, list )):
5290 elemType = SMESH.ALL
5291 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5292 elements = self.editor.MakeIDSource(elements, elemType)
5293 unRegister.set( elements )
5294 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5295 toCopyElements,toCopyExistingBondary)
5296 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5299 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5300 toCopyAll=False, groups=[]):
5302 Create missing boundary elements around either the whole mesh or
5306 dimension: defines type of boundary elements to create, either of
5307 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5308 groupName: a name of group to store all boundary elements in,
5309 "" means not to create the group
5310 meshName: a name of a new mesh, which is a copy of the initial
5311 mesh + created boundary elements; "" means not to create the new mesh
5312 toCopyAll: if True, the whole initial mesh will be copied into
5313 the new mesh else only boundary elements will be copied into the new mesh
5314 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5317 tuple( long, mesh, group )
5318 - long - number of added boundary elements
5319 - mesh - the :class:`Mesh` where elements were added to
5320 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5323 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5325 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5326 return nb, mesh, group
5328 def RenumberNodes(self):
5330 Renumber mesh nodes to remove unused node IDs
5332 self.editor.RenumberNodes()
5334 def RenumberElements(self):
5336 Renumber mesh elements to remove unused element IDs
5338 self.editor.RenumberElements()
5340 def _getIdSourceList(self, arg, idType, unRegister):
5342 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5344 if arg and isinstance( arg, list ):
5345 if isinstance( arg[0], int ):
5346 arg = self.GetIDSource( arg, idType )
5347 unRegister.set( arg )
5348 elif isinstance( arg[0], Mesh ):
5349 arg[0] = arg[0].GetMesh()
5350 elif isinstance( arg, Mesh ):
5352 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5356 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5357 MakeGroups=False, TotalAngle=False):
5359 Generate new elements by rotation of the given elements and nodes around the axis
5362 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5363 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5364 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5365 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5366 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5367 which defines angle in degrees
5368 NbOfSteps: the number of steps
5369 Tolerance: tolerance
5370 MakeGroups: forces the generation of new groups from existing ones
5371 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5372 of all steps, else - size of each step
5375 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5378 unRegister = genObjUnRegister()
5379 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5380 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5381 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5383 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5384 Axis = self.smeshpyD.GetAxisStruct( Axis )
5385 if isinstance( Axis, list ):
5386 Axis = SMESH.AxisStruct( *Axis )
5388 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5389 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5390 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5391 self.mesh.SetParameters(Parameters)
5392 if TotalAngle and NbOfSteps:
5393 AngleInRadians /= NbOfSteps
5394 return self.editor.RotationSweepObjects( nodes, edges, faces,
5395 Axis, AngleInRadians,
5396 NbOfSteps, Tolerance, MakeGroups)
5398 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5399 MakeGroups=False, TotalAngle=False):
5401 Generate new elements by rotation of the elements around the axis
5404 IDsOfElements: the list of ids of elements to sweep
5405 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5406 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5407 NbOfSteps: the number of steps
5408 Tolerance: tolerance
5409 MakeGroups: forces the generation of new groups from existing ones
5410 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5411 of all steps, else - size of each step
5414 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5417 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5418 AngleInRadians, NbOfSteps, Tolerance,
5419 MakeGroups, TotalAngle)
5421 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5422 MakeGroups=False, TotalAngle=False):
5424 Generate new elements by rotation of the elements of object around the axis
5425 theObject object which elements should be sweeped.
5426 It can be a mesh, a sub mesh or a group.
5429 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5430 AngleInRadians: the angle of Rotation
5431 NbOfSteps: number of steps
5432 Tolerance: tolerance
5433 MakeGroups: forces the generation of new groups from existing ones
5434 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5435 of all steps, else - size of each step
5438 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5441 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5442 AngleInRadians, NbOfSteps, Tolerance,
5443 MakeGroups, TotalAngle )
5445 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5446 MakeGroups=False, TotalAngle=False):
5448 Generate new elements by rotation of the elements of object around the axis
5449 theObject object which elements should be sweeped.
5450 It can be a mesh, a sub mesh or a group.
5453 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5454 AngleInRadians: the angle of Rotation
5455 NbOfSteps: number of steps
5456 Tolerance: tolerance
5457 MakeGroups: forces the generation of new groups from existing ones
5458 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5459 of all steps, else - size of each step
5462 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5463 empty list otherwise
5466 return self.RotationSweepObjects([],theObject,[], Axis,
5467 AngleInRadians, NbOfSteps, Tolerance,
5468 MakeGroups, TotalAngle)
5470 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5471 MakeGroups=False, TotalAngle=False):
5473 Generate new elements by rotation of the elements of object around the axis
5474 theObject object which elements should be sweeped.
5475 It can be a mesh, a sub mesh or a group.
5478 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5479 AngleInRadians: the angle of Rotation
5480 NbOfSteps: number of steps
5481 Tolerance: tolerance
5482 MakeGroups: forces the generation of new groups from existing ones
5483 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5484 of all steps, else - size of each step
5487 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5490 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5491 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5493 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5494 scaleFactors=[], linearVariation=False, basePoint=[],
5495 angles=[], anglesVariation=False):
5497 Generate new elements by extrusion of the given elements and nodes
5500 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5501 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5502 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5503 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5504 the direction and value of extrusion for one step (the total extrusion
5505 length will be NbOfSteps * ||StepVector||)
5506 NbOfSteps: the number of steps
5507 MakeGroups: forces the generation of new groups from existing ones
5508 scaleFactors: optional scale factors to apply during extrusion
5509 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5510 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5511 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5512 nodes and elements being extruded is used as the scaling center.
5515 - a list of tree components of the point or
5518 angles: list of angles in radians. Nodes at each extrusion step are rotated
5519 around *basePoint*, additionally to previous steps.
5520 anglesVariation: forces the computation of rotation angles as linear
5521 variation of the given *angles* along path steps
5523 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5525 Example: :ref:`tui_extrusion`
5527 unRegister = genObjUnRegister()
5528 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5529 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5530 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5532 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5533 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5534 if isinstance( StepVector, list ):
5535 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5537 if isinstance( basePoint, int):
5538 xyz = self.GetNodeXYZ( basePoint )
5540 raise RuntimeError("Invalid node ID: %s" % basePoint)
5542 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5543 basePoint = self.geompyD.PointCoordinates( basePoint )
5545 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5546 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5547 angles,angleParameters,hasVars = ParseAngles(angles)
5548 Parameters = StepVector.PS.parameters + var_separator + \
5549 Parameters + var_separator + \
5550 scaleParameters + var_separator + angleParameters
5551 self.mesh.SetParameters(Parameters)
5553 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5554 StepVector, NbOfSteps, MakeGroups,
5555 scaleFactors, linearVariation, basePoint,
5556 angles, anglesVariation )
5559 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5561 Generate new elements by extrusion of the elements with given ids
5564 IDsOfElements: the list of ids of elements or nodes for extrusion
5565 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5566 the direction and value of extrusion for one step (the total extrusion
5567 length will be NbOfSteps * ||StepVector||)
5568 NbOfSteps: the number of steps
5569 MakeGroups: forces the generation of new groups from existing ones
5570 IsNodes: is True if elements with given ids are nodes
5573 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5575 Example: :ref:`tui_extrusion`
5578 if IsNodes: n = IDsOfElements
5579 else : e,f, = IDsOfElements,IDsOfElements
5580 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5582 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5583 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5585 Generate new elements by extrusion along the normal to a discretized surface or wire
5588 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5589 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5590 StepSize: length of one extrusion step (the total extrusion
5591 length will be *NbOfSteps* *StepSize*).
5592 NbOfSteps: number of extrusion steps.
5593 ByAverageNormal: if True each node is translated by *StepSize*
5594 along the average of the normal vectors to the faces sharing the node;
5595 else each node is translated along the same average normal till
5596 intersection with the plane got by translation of the face sharing
5597 the node along its own normal by *StepSize*.
5598 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5599 for every node of *Elements*.
5600 MakeGroups: forces generation of new groups from existing ones.
5601 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5602 is not yet implemented. This parameter is used if *Elements* contains
5603 both faces and edges, i.e. *Elements* is a Mesh.
5606 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5607 empty list otherwise.
5608 Example: :ref:`tui_extrusion`
5611 unRegister = genObjUnRegister()
5612 if isinstance( Elements, Mesh ):
5613 Elements = [ Elements.GetMesh() ]
5614 if isinstance( Elements, list ):
5616 raise RuntimeError("Elements empty!")
5617 if isinstance( Elements[0], Mesh ):
5618 Elements = [ Elements[0].GetMesh() ]
5619 if isinstance( Elements[0], int ):
5620 Elements = self.GetIDSource( Elements, SMESH.ALL )
5621 unRegister.set( Elements )
5622 if not isinstance( Elements, list ):
5623 Elements = [ Elements ]
5624 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5625 self.mesh.SetParameters(Parameters)
5626 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5627 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5629 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5631 Generate new elements by extrusion of the elements or nodes which belong to the object
5634 theObject: the object whose elements or nodes should be processed.
5635 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5636 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5637 the direction and value of extrusion for one step (the total extrusion
5638 length will be NbOfSteps * ||StepVector||)
5639 NbOfSteps: the number of steps
5640 MakeGroups: forces the generation of new groups from existing ones
5641 IsNodes: is True if elements to extrude are nodes
5644 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5645 Example: :ref:`tui_extrusion`
5649 if IsNodes: n = theObject
5650 else : e,f, = theObject,theObject
5651 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5653 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5655 Generate new elements by extrusion of edges which belong to the object
5658 theObject: object whose 1D elements should be processed.
5659 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5660 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5661 the direction and value of extrusion for one step (the total extrusion
5662 length will be NbOfSteps * ||StepVector||)
5663 NbOfSteps: the number of steps
5664 MakeGroups: to generate new groups from existing ones
5667 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5668 Example: :ref:`tui_extrusion`
5671 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5673 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5675 Generate new elements by extrusion of faces which belong to the object
5678 theObject: object whose 2D elements should be processed.
5679 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5680 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5681 the direction and value of extrusion for one step (the total extrusion
5682 length will be NbOfSteps * ||StepVector||)
5683 NbOfSteps: the number of steps
5684 MakeGroups: forces the generation of new groups from existing ones
5687 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5688 Example: :ref:`tui_extrusion`
5691 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5693 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5694 ExtrFlags, SewTolerance, MakeGroups=False):
5696 Generate new elements by extrusion of the elements with given ids
5699 IDsOfElements: is ids of elements
5700 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5701 the direction and value of extrusion for one step (the total extrusion
5702 length will be NbOfSteps * ||StepVector||)
5703 NbOfSteps: the number of steps
5704 ExtrFlags: sets flags for extrusion
5705 SewTolerance: uses for comparing locations of nodes if flag
5706 EXTRUSION_FLAG_SEW is set
5707 MakeGroups: forces the generation of new groups from existing ones
5710 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5713 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5714 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5715 if isinstance( StepVector, list ):
5716 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5717 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5718 ExtrFlags, SewTolerance, MakeGroups)
5720 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5721 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5722 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5723 ScaleFactors=[], ScalesVariation=False):
5725 Generate new elements by extrusion of the given elements and nodes along the path.
5726 The path of extrusion must be a meshed edge.
5729 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5730 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5731 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5732 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5733 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
5734 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5735 HasAngles: not used obsolete
5736 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5737 around *basePoint*, additionally to previous steps.
5738 LinearVariation: forces the computation of rotation angles as linear
5739 variation of the given Angles along path steps
5740 HasRefPoint: allows using the reference point
5741 RefPoint: optional scaling and rotation center (mass center of the extruded
5742 elements by default). The User can specify any point as the Reference Point.
5743 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5744 MakeGroups: forces the generation of new groups from existing ones
5745 ScaleFactors: optional scale factors to apply during extrusion
5746 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5747 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5750 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5751 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5752 Example: :ref:`tui_extrusion_along_path`
5755 unRegister = genObjUnRegister()
5756 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5757 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5758 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5760 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5761 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5762 if isinstance( RefPoint, list ):
5763 if not RefPoint: RefPoint = [0,0,0]
5764 RefPoint = SMESH.PointStruct( *RefPoint )
5765 if isinstance( PathObject, Mesh ):
5766 PathObject = PathObject.GetMesh()
5767 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5768 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5769 Parameters = AnglesParameters + var_separator + \
5770 RefPoint.parameters + var_separator + ScalesParameters
5771 self.mesh.SetParameters(Parameters)
5772 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5773 PathObject, PathShape, NodeStart,
5774 HasAngles, Angles, LinearVariation,
5775 HasRefPoint, RefPoint, MakeGroups,
5776 ScaleFactors, ScalesVariation)
5778 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5779 HasAngles=False, Angles=[], LinearVariation=False,
5780 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5781 ElemType=SMESH.FACE):
5783 Generate new elements by extrusion of the given elements.
5784 The path of extrusion must be a meshed edge.
5787 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5788 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5789 NodeStart: the start node from Path. Defines the direction of extrusion
5790 HasAngles: not used obsolete
5791 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5792 around *basePoint*, additionally to previous steps.
5793 LinearVariation: forces the computation of rotation angles as linear
5794 variation of the given Angles along path steps
5795 HasRefPoint: allows using the reference point
5796 RefPoint: the reference point around which the elements are rotated (the mass
5797 center of the elements by default).
5798 The User can specify any point as the Reference Point.
5799 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5800 MakeGroups: forces the generation of new groups from existing ones
5801 ElemType: type of elements for extrusion (if param Base is a mesh)
5804 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5805 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5806 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5808 Example: :ref:`tui_extrusion_along_path`
5812 if ElemType == SMESH.NODE: n = Base
5813 if ElemType == SMESH.EDGE: e = Base
5814 if ElemType == SMESH.FACE: f = Base
5815 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5816 HasAngles, Angles, LinearVariation,
5817 HasRefPoint, RefPoint, MakeGroups)
5818 if MakeGroups: return gr,er
5821 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5822 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5823 MakeGroups=False, LinearVariation=False):
5825 Generate new elements by extrusion of the given elements.
5826 The path of extrusion must be a meshed edge.
5829 IDsOfElements: ids of elements
5830 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5831 PathShape: shape (edge) defines the sub-mesh for the path
5832 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5833 HasAngles: not used obsolete
5834 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5835 around *basePoint*, additionally to previous steps.
5836 HasRefPoint: allows using the reference point
5837 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5838 The User can specify any point as the Reference Point.
5839 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5840 MakeGroups: forces the generation of new groups from existing ones
5841 LinearVariation: forces the computation of rotation angles as linear
5842 variation of the given Angles along path steps
5845 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5846 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5847 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5848 Example: :ref:`tui_extrusion_along_path`
5851 if not IDsOfElements:
5852 IDsOfElements = [ self.GetMesh() ]
5853 n,e,f = [],IDsOfElements,IDsOfElements
5854 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5855 NodeStart, HasAngles, Angles,
5857 HasRefPoint, RefPoint, MakeGroups)
5858 if MakeGroups: return gr,er
5861 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5862 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5863 MakeGroups=False, LinearVariation=False):
5865 Generate new elements by extrusion of the elements which belong to the object.
5866 The path of extrusion must be a meshed edge.
5869 theObject: the object whose elements should be processed.
5870 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5871 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5872 PathShape: shape (edge) defines the sub-mesh for the path
5873 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5874 HasAngles: not used obsolete
5875 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5876 around *basePoint*, additionally to previous steps.
5877 HasRefPoint: allows using the reference point
5878 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5879 The User can specify any point as the Reference Point.
5880 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5881 MakeGroups: forces the generation of new groups from existing ones
5882 LinearVariation: forces the computation of rotation angles as linear
5883 variation of the given Angles along path steps
5886 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5887 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5888 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5889 Example: :ref:`tui_extrusion_along_path`
5892 n,e,f = [],theObject,theObject
5893 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5894 HasAngles, Angles, LinearVariation,
5895 HasRefPoint, RefPoint, MakeGroups)
5896 if MakeGroups: return gr,er
5899 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5900 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5901 MakeGroups=False, LinearVariation=False):
5903 Generate new elements by extrusion of mesh segments which belong to the object.
5904 The path of extrusion must be a meshed edge.
5907 theObject: the object whose 1D elements should be processed.
5908 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5909 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5910 PathShape: shape (edge) defines the sub-mesh for the path
5911 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5912 HasAngles: not used obsolete
5913 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5914 around *basePoint*, additionally to previous steps.
5915 HasRefPoint: allows using the reference point
5916 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5917 The User can specify any point as the Reference Point.
5918 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5919 MakeGroups: forces the generation of new groups from existing ones
5920 LinearVariation: forces the computation of rotation angles as linear
5921 variation of the given Angles along path steps
5924 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5925 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5926 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5927 Example: :ref:`tui_extrusion_along_path`
5930 n,e,f = [],theObject,[]
5931 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5932 HasAngles, Angles, LinearVariation,
5933 HasRefPoint, RefPoint, MakeGroups)
5934 if MakeGroups: return gr,er
5937 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5938 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5939 MakeGroups=False, LinearVariation=False):
5941 Generate new elements by extrusion of faces which belong to the object.
5942 The path of extrusion must be a meshed edge.
5945 theObject: the object whose 2D elements should be processed.
5946 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5947 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5948 PathShape: shape (edge) defines the sub-mesh for the path
5949 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5950 HasAngles: not used obsolete
5951 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5952 around *basePoint*, additionally to previous steps.
5953 HasRefPoint: allows using the reference point
5954 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5955 The User can specify any point as the Reference Point.
5956 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5957 MakeGroups: forces the generation of new groups from existing ones
5958 LinearVariation: forces the computation of rotation angles as linear
5959 variation of the given Angles along path steps
5962 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5963 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5964 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5965 Example: :ref:`tui_extrusion_along_path`
5968 n,e,f = [],[],theObject
5969 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5970 HasAngles, Angles, LinearVariation,
5971 HasRefPoint, RefPoint, MakeGroups)
5972 if MakeGroups: return gr,er
5975 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5977 Create a symmetrical copy of mesh elements
5980 IDsOfElements: list of elements ids
5981 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5982 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5983 If the *Mirror* is a geom object this parameter is unnecessary
5984 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5985 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5988 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5991 if IDsOfElements == []:
5992 IDsOfElements = self.GetElementsId()
5993 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5994 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5995 theMirrorType = Mirror._mirrorType
5997 self.mesh.SetParameters(Mirror.parameters)
5998 if Copy and MakeGroups:
5999 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6000 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6003 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6005 Create a new mesh by a symmetrical copy of mesh elements
6008 IDsOfElements: the list of elements ids
6009 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6010 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6011 If the *Mirror* is a geom object this parameter is unnecessary
6012 MakeGroups: to generate new groups from existing ones
6013 NewMeshName: a name of the new mesh to create
6016 instance of class :class:`Mesh`
6019 if IDsOfElements == []:
6020 IDsOfElements = self.GetElementsId()
6021 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6022 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6023 theMirrorType = Mirror._mirrorType
6025 self.mesh.SetParameters(Mirror.parameters)
6026 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6027 MakeGroups, NewMeshName)
6028 return Mesh(self.smeshpyD,self.geompyD,mesh)
6030 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6032 Create a symmetrical copy of the object
6035 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6036 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6037 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6038 If the *Mirror* is a geom object this parameter is unnecessary
6039 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6040 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6043 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6046 if ( isinstance( theObject, Mesh )):
6047 theObject = theObject.GetMesh()
6048 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6049 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6050 theMirrorType = Mirror._mirrorType
6052 self.mesh.SetParameters(Mirror.parameters)
6053 if Copy and MakeGroups:
6054 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6055 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6058 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6060 Create a new mesh by a symmetrical copy of the object
6063 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6064 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6065 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6066 If the *Mirror* is a geom object this parameter is unnecessary
6067 MakeGroups: forces the generation of new groups from existing ones
6068 NewMeshName: the name of the new mesh to create
6071 instance of class :class:`Mesh`
6074 if ( isinstance( theObject, Mesh )):
6075 theObject = theObject.GetMesh()
6076 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6077 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6078 theMirrorType = Mirror._mirrorType
6080 self.mesh.SetParameters(Mirror.parameters)
6081 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6082 MakeGroups, NewMeshName)
6083 return Mesh( self.smeshpyD,self.geompyD,mesh )
6085 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6087 Translate the elements
6090 IDsOfElements: list of elements ids
6091 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6092 Copy: allows copying the translated elements
6093 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6096 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6099 if IDsOfElements == []:
6100 IDsOfElements = self.GetElementsId()
6101 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6102 Vector = self.smeshpyD.GetDirStruct(Vector)
6103 if isinstance( Vector, list ):
6104 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6105 self.mesh.SetParameters(Vector.PS.parameters)
6106 if Copy and MakeGroups:
6107 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6108 self.editor.Translate(IDsOfElements, Vector, Copy)
6111 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6113 Create a new mesh of translated elements
6116 IDsOfElements: list of elements ids
6117 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6118 MakeGroups: forces the generation of new groups from existing ones
6119 NewMeshName: the name of the newly created mesh
6122 instance of class :class:`Mesh`
6125 if IDsOfElements == []:
6126 IDsOfElements = self.GetElementsId()
6127 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6128 Vector = self.smeshpyD.GetDirStruct(Vector)
6129 if isinstance( Vector, list ):
6130 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6131 self.mesh.SetParameters(Vector.PS.parameters)
6132 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6133 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6135 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6137 Translate the object
6140 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6141 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6142 Copy: allows copying the translated elements
6143 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6146 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6149 if ( isinstance( theObject, Mesh )):
6150 theObject = theObject.GetMesh()
6151 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6152 Vector = self.smeshpyD.GetDirStruct(Vector)
6153 if isinstance( Vector, list ):
6154 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6155 self.mesh.SetParameters(Vector.PS.parameters)
6156 if Copy and MakeGroups:
6157 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6158 self.editor.TranslateObject(theObject, Vector, Copy)
6161 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6163 Create a new mesh from the translated object
6166 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6167 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6168 MakeGroups: forces the generation of new groups from existing ones
6169 NewMeshName: the name of the newly created mesh
6172 instance of class :class:`Mesh`
6175 if isinstance( theObject, Mesh ):
6176 theObject = theObject.GetMesh()
6177 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6178 Vector = self.smeshpyD.GetDirStruct(Vector)
6179 if isinstance( Vector, list ):
6180 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6181 self.mesh.SetParameters(Vector.PS.parameters)
6182 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6183 return Mesh( self.smeshpyD, self.geompyD, mesh )
6187 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6192 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6193 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6194 theScaleFact: list of 1-3 scale factors for axises
6195 Copy: allows copying the translated elements
6196 MakeGroups: forces the generation of new groups from existing
6200 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6201 empty list otherwise
6203 unRegister = genObjUnRegister()
6204 if ( isinstance( theObject, Mesh )):
6205 theObject = theObject.GetMesh()
6206 if ( isinstance( theObject, list )):
6207 theObject = self.GetIDSource(theObject, SMESH.ALL)
6208 unRegister.set( theObject )
6209 if ( isinstance( thePoint, list )):
6210 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6211 if ( isinstance( theScaleFact, float )):
6212 theScaleFact = [theScaleFact]
6213 if ( isinstance( theScaleFact, int )):
6214 theScaleFact = [ float(theScaleFact)]
6216 self.mesh.SetParameters(thePoint.parameters)
6218 if Copy and MakeGroups:
6219 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6220 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6223 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6225 Create a new mesh from the translated object
6228 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6229 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6230 theScaleFact: list of 1-3 scale factors for axises
6231 MakeGroups: forces the generation of new groups from existing ones
6232 NewMeshName: the name of the newly created mesh
6235 instance of class :class:`Mesh`
6237 unRegister = genObjUnRegister()
6238 if (isinstance(theObject, Mesh)):
6239 theObject = theObject.GetMesh()
6240 if ( isinstance( theObject, list )):
6241 theObject = self.GetIDSource(theObject,SMESH.ALL)
6242 unRegister.set( theObject )
6243 if ( isinstance( thePoint, list )):
6244 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6245 if ( isinstance( theScaleFact, float )):
6246 theScaleFact = [theScaleFact]
6247 if ( isinstance( theScaleFact, int )):
6248 theScaleFact = [ float(theScaleFact)]
6250 self.mesh.SetParameters(thePoint.parameters)
6251 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6252 MakeGroups, NewMeshName)
6253 return Mesh( self.smeshpyD, self.geompyD, mesh )
6257 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6262 IDsOfElements: list of elements ids
6263 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6264 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6265 Copy: allows copying the rotated elements
6266 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6269 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6273 if IDsOfElements == []:
6274 IDsOfElements = self.GetElementsId()
6275 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6276 Axis = self.smeshpyD.GetAxisStruct(Axis)
6277 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6278 Parameters = Axis.parameters + var_separator + Parameters
6279 self.mesh.SetParameters(Parameters)
6280 if Copy and MakeGroups:
6281 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6282 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6285 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6287 Create a new mesh of rotated elements
6290 IDsOfElements: list of element ids
6291 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6292 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6293 MakeGroups: forces the generation of new groups from existing ones
6294 NewMeshName: the name of the newly created mesh
6297 instance of class :class:`Mesh`
6300 if IDsOfElements == []:
6301 IDsOfElements = self.GetElementsId()
6302 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6303 Axis = self.smeshpyD.GetAxisStruct(Axis)
6304 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6305 Parameters = Axis.parameters + var_separator + Parameters
6306 self.mesh.SetParameters(Parameters)
6307 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6308 MakeGroups, NewMeshName)
6309 return Mesh( self.smeshpyD, self.geompyD, mesh )
6311 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6316 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6317 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6318 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6319 Copy: allows copying the rotated elements
6320 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6323 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6326 if (isinstance(theObject, Mesh)):
6327 theObject = theObject.GetMesh()
6328 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6329 Axis = self.smeshpyD.GetAxisStruct(Axis)
6330 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6331 Parameters = Axis.parameters + ":" + Parameters
6332 self.mesh.SetParameters(Parameters)
6333 if Copy and MakeGroups:
6334 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6335 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6338 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6340 Create a new mesh from the rotated object
6343 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6344 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6345 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6346 MakeGroups: forces the generation of new groups from existing ones
6347 NewMeshName: the name of the newly created mesh
6350 instance of class :class:`Mesh`
6353 if (isinstance( theObject, Mesh )):
6354 theObject = theObject.GetMesh()
6355 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6356 Axis = self.smeshpyD.GetAxisStruct(Axis)
6357 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6358 Parameters = Axis.parameters + ":" + Parameters
6359 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6360 MakeGroups, NewMeshName)
6361 self.mesh.SetParameters(Parameters)
6362 return Mesh( self.smeshpyD, self.geompyD, mesh )
6364 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6366 Create an offset mesh from the given 2D object
6369 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6370 theValue (float): signed offset size
6371 MakeGroups (boolean): forces the generation of new groups from existing ones
6372 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6373 False means to remove original elements.
6374 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6377 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6380 if isinstance( theObject, Mesh ):
6381 theObject = theObject.GetMesh()
6382 theValue,Parameters,hasVars = ParseParameters(Value)
6383 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6384 self.mesh.SetParameters(Parameters)
6386 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6389 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6391 Find groups of adjacent nodes within Tolerance.
6394 Tolerance (float): the value of tolerance
6395 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6396 corner and medium nodes in separate groups thus preventing
6397 their further merge.
6400 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6403 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6405 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6406 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6408 Find groups of adjacent nodes within Tolerance.
6411 Tolerance: the value of tolerance
6412 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6413 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6414 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6415 corner and medium nodes in separate groups thus preventing
6416 their further merge.
6419 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6422 unRegister = genObjUnRegister()
6423 if not isinstance( SubMeshOrGroup, list ):
6424 SubMeshOrGroup = [ SubMeshOrGroup ]
6425 for i,obj in enumerate( SubMeshOrGroup ):
6426 if isinstance( obj, Mesh ):
6427 SubMeshOrGroup = [ obj.GetMesh() ]
6429 if isinstance( obj, int ):
6430 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6431 unRegister.set( SubMeshOrGroup )
6434 if not isinstance( exceptNodes, list ):
6435 exceptNodes = [ exceptNodes ]
6436 if exceptNodes and isinstance( exceptNodes[0], int ):
6437 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6438 unRegister.set( exceptNodes )
6440 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6441 exceptNodes, SeparateCornerAndMediumNodes)
6443 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6448 GroupsOfNodes: a list of groups of nodes IDs for merging.
6449 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6450 in all elements and mesh groups by nodes 1 and 25 correspondingly
6451 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6452 If *NodesToKeep* does not include a node to keep for some group to merge,
6453 then the first node in the group is kept.
6454 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6458 This operation can create gaps in numeration of nodes or elements.
6459 Call :meth:`RenumberElements` to remove the gaps.
6461 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6463 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6465 Find the elements built on the same nodes.
6468 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6469 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6473 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6476 unRegister = genObjUnRegister()
6477 if MeshOrSubMeshOrGroup is None:
6478 MeshOrSubMeshOrGroup = [ self.mesh ]
6479 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6480 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6481 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6482 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6483 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6484 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6485 unRegister.set( MeshOrSubMeshOrGroup )
6486 for item in MeshOrSubMeshOrGroup:
6487 if isinstance( item, Mesh ):
6488 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6490 if not isinstance( exceptElements, list ):
6491 exceptElements = [ exceptElements ]
6492 if exceptElements and isinstance( exceptElements[0], int ):
6493 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6494 unRegister.set( exceptElements )
6496 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6498 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6500 Merge elements in each given group.
6503 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6504 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6505 replaced in all mesh groups by elements 1 and 25)
6506 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6507 If *ElementsToKeep* does not include an element to keep for some group to merge,
6508 then the first element in the group is kept.
6511 This operation can create gaps in numeration of elements.
6512 Call :meth:`RenumberElements` to remove the gaps.
6515 unRegister = genObjUnRegister()
6517 if not isinstance( ElementsToKeep, list ):
6518 ElementsToKeep = [ ElementsToKeep ]
6519 if isinstance( ElementsToKeep[0], int ):
6520 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6521 unRegister.set( ElementsToKeep )
6523 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6525 def MergeEqualElements(self):
6527 Leave one element and remove all other elements built on the same nodes.
6530 This operation can create gaps in numeration of elements.
6531 Call :meth:`RenumberElements` to remove the gaps.
6534 self.editor.MergeEqualElements()
6536 def FindFreeBorders(self, ClosedOnly=True):
6538 Returns all or only closed free borders
6541 list of SMESH.FreeBorder's
6544 return self.editor.FindFreeBorders( ClosedOnly )
6546 def FillHole(self, holeNodes, groupName=""):
6548 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6551 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6552 must describe all sequential nodes of the hole border. The first and the last
6553 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6554 groupName (string): name of a group to add new faces
6556 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6560 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6561 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6562 if not isinstance( holeNodes, SMESH.FreeBorder ):
6563 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6564 return self.editor.FillHole( holeNodes, groupName )
6566 def FindCoincidentFreeBorders (self, tolerance=0.):
6568 Return groups of FreeBorder's coincident within the given tolerance.
6571 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6572 size of elements adjacent to free borders being compared is used.
6575 SMESH.CoincidentFreeBorders structure
6578 return self.editor.FindCoincidentFreeBorders( tolerance )
6580 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6582 Sew FreeBorder's of each group
6585 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6586 where each enclosed list contains node IDs of a group of coincident free
6587 borders such that each consequent triple of IDs within a group describes
6588 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6589 last node of a border.
6590 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6591 groups of coincident free borders, each group including two borders.
6592 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6593 polygons if a node of opposite border falls on a face edge, else such
6594 faces are split into several ones.
6595 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6596 polyhedra if a node of opposite border falls on a volume edge, else such
6597 volumes, if any, remain intact and the mesh becomes non-conformal.
6600 a number of successfully sewed groups
6603 This operation can create gaps in numeration of nodes or elements.
6604 Call :meth:`RenumberElements` to remove the gaps.
6607 if freeBorders and isinstance( freeBorders, list ):
6608 # construct SMESH.CoincidentFreeBorders
6609 if isinstance( freeBorders[0], int ):
6610 freeBorders = [freeBorders]
6612 coincidentGroups = []
6613 for nodeList in freeBorders:
6614 if not nodeList or len( nodeList ) % 3:
6615 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6618 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6619 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6620 nodeList = nodeList[3:]
6622 coincidentGroups.append( group )
6624 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6626 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6628 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6629 FirstNodeID2, SecondNodeID2, LastNodeID2,
6630 CreatePolygons, CreatePolyedrs):
6635 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6638 This operation can create gaps in numeration of nodes or elements.
6639 Call :meth:`RenumberElements` to remove the gaps.
6642 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6643 FirstNodeID2, SecondNodeID2, LastNodeID2,
6644 CreatePolygons, CreatePolyedrs)
6646 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6647 FirstNodeID2, SecondNodeID2):
6649 Sew conform free borders
6652 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6655 This operation can create gaps in numeration of elements.
6656 Call :meth:`RenumberElements` to remove the gaps.
6659 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6660 FirstNodeID2, SecondNodeID2)
6662 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6663 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6668 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6671 This operation can create gaps in numeration of elements.
6672 Call :meth:`RenumberElements` to remove the gaps.
6675 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6676 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6678 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6679 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6680 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6682 Sew two sides of a mesh. The nodes belonging to Side1 are
6683 merged with the nodes of elements of Side2.
6684 The number of elements in theSide1 and in theSide2 must be
6685 equal and they should have similar nodal connectivity.
6686 The nodes to merge should belong to side borders and
6687 the first node should be linked to the second.
6690 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6693 This operation can create gaps in numeration of nodes.
6694 Call :meth:`RenumberElements` to remove the gaps.
6697 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6698 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6699 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6701 def ChangeElemNodes(self, ide, newIDs):
6703 Set new nodes for the given element. Number of nodes should be kept.
6710 False if the number of nodes does not correspond to the type of element
6713 return self.editor.ChangeElemNodes(ide, newIDs)
6715 def GetLastCreatedNodes(self):
6717 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6718 created, this method return the list of their IDs.
6719 If new nodes were not created - return empty list
6722 the list of integer values (can be empty)
6725 return self.editor.GetLastCreatedNodes()
6727 def GetLastCreatedElems(self):
6729 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6730 created this method return the list of their IDs.
6731 If new elements were not created - return empty list
6734 the list of integer values (can be empty)
6737 return self.editor.GetLastCreatedElems()
6739 def ClearLastCreated(self):
6741 Forget what nodes and elements were created by the last mesh edition operation
6744 self.editor.ClearLastCreated()
6746 def DoubleElements(self, theElements, theGroupName=""):
6748 Create duplicates of given elements, i.e. create new elements based on the
6749 same nodes as the given ones.
6752 theElements: container of elements to duplicate. It can be a
6753 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6754 or a list of element IDs. If *theElements* is
6755 a :class:`Mesh`, elements of highest dimension are duplicated
6756 theGroupName: a name of group to contain the generated elements.
6757 If a group with such a name already exists, the new elements
6758 are added to the existing group, else a new group is created.
6759 If *theGroupName* is empty, new elements are not added
6763 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6764 None if *theGroupName* == "".
6767 unRegister = genObjUnRegister()
6768 if isinstance( theElements, Mesh ):
6769 theElements = theElements.mesh
6770 elif isinstance( theElements, list ):
6771 theElements = self.GetIDSource( theElements, SMESH.ALL )
6772 unRegister.set( theElements )
6773 return self.editor.DoubleElements(theElements, theGroupName)
6775 def DoubleNodes(self, theNodes, theModifiedElems):
6777 Create a hole in a mesh by doubling the nodes of some particular elements
6780 theNodes: IDs of nodes to be doubled
6781 theModifiedElems: IDs of elements to be updated by the new (doubled)
6782 nodes. If list of element identifiers is empty then nodes are doubled but
6783 they not assigned to elements
6786 True if operation has been completed successfully, False otherwise
6789 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6791 def DoubleNode(self, theNodeId, theModifiedElems):
6793 Create a hole in a mesh by doubling the nodes of some particular elements.
6794 This method provided for convenience works as :meth:`DoubleNodes`.
6797 theNodeId: IDs of node to double
6798 theModifiedElems: IDs of elements to update
6801 True if operation has been completed successfully, False otherwise
6804 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6806 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6808 Create a hole in a mesh by doubling the nodes of some particular elements.
6809 This method provided for convenience works as :meth:`DoubleNodes`.
6812 theNodes: group of nodes to double.
6813 theModifiedElems: group of elements to update.
6814 theMakeGroup: forces the generation of a group containing new nodes.
6817 True or a created group if operation has been completed successfully,
6818 False or None otherwise
6822 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6823 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6825 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6827 Create a hole in a mesh by doubling the nodes of some particular elements.
6828 This method provided for convenience works as :meth:`DoubleNodes`.
6831 theNodes: list of groups of nodes to double.
6832 theModifiedElems: list of groups of elements to update.
6833 theMakeGroup: forces the generation of a group containing new nodes.
6836 True if operation has been completed successfully, False otherwise
6840 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6841 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6843 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6845 Create a hole in a mesh by doubling the nodes of some particular elements
6848 theElems: the list of elements (edges or faces) to replicate.
6849 The nodes for duplication could be found from these elements
6850 theNodesNot: list of nodes NOT to replicate
6851 theAffectedElems: the list of elements (cells and edges) to which the
6852 replicated nodes should be associated to
6855 True if operation has been completed successfully, False otherwise
6858 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6860 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6862 Create a hole in a mesh by doubling the nodes of some particular elements
6865 theElems: the list of elements (edges or faces) to replicate.
6866 The nodes for duplication could be found from these elements
6867 theNodesNot: list of nodes NOT to replicate
6868 theShape: shape to detect affected elements (element which geometric center
6869 located on or inside shape).
6870 The replicated nodes should be associated to affected elements.
6873 True if operation has been completed successfully, False otherwise
6876 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6878 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6879 theMakeGroup=False, theMakeNodeGroup=False):
6881 Create a hole in a mesh by doubling the nodes of some particular elements.
6882 This method provided for convenience works as :meth:`DoubleNodes`.
6885 theElems: group of of elements (edges or faces) to replicate.
6886 theNodesNot: group of nodes NOT to replicate.
6887 theAffectedElems: group of elements to which the replicated nodes
6888 should be associated to.
6889 theMakeGroup: forces the generation of a group containing new elements.
6890 theMakeNodeGroup: forces the generation of a group containing new nodes.
6893 True or created groups (one or two) if operation has been completed successfully,
6894 False or None otherwise
6897 if theMakeGroup or theMakeNodeGroup:
6898 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6900 theMakeGroup, theMakeNodeGroup)
6901 if theMakeGroup and theMakeNodeGroup:
6904 return twoGroups[ int(theMakeNodeGroup) ]
6905 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6907 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6909 Create a hole in a mesh by doubling the nodes of some particular elements.
6910 This method provided for convenience works as :meth:`DoubleNodes`.
6913 theElems: group of of elements (edges or faces) to replicate
6914 theNodesNot: group of nodes not to replicate
6915 theShape: shape to detect affected elements (element which geometric center
6916 located on or inside shape).
6917 The replicated nodes should be associated to affected elements
6920 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6922 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6923 theMakeGroup=False, theMakeNodeGroup=False):
6925 Create a hole in a mesh by doubling the nodes of some particular elements.
6926 This method provided for convenience works as :meth:`DoubleNodes`.
6929 theElems: list of groups of elements (edges or faces) to replicate
6930 theNodesNot: list of groups of nodes NOT to replicate
6931 theAffectedElems: group of elements to which the replicated nodes
6932 should be associated to
6933 theMakeGroup: forces generation of a group containing new elements.
6934 theMakeNodeGroup: forces generation of a group containing new nodes
6937 True or created groups (one or two) if operation has been completed successfully,
6938 False or None otherwise
6941 if theMakeGroup or theMakeNodeGroup:
6942 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6944 theMakeGroup, theMakeNodeGroup)
6945 if theMakeGroup and theMakeNodeGroup:
6948 return twoGroups[ int(theMakeNodeGroup) ]
6949 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6951 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6953 Create a hole in a mesh by doubling the nodes of some particular elements.
6954 This method provided for convenience works as :meth:`DoubleNodes`.
6957 theElems: list of groups of elements (edges or faces) to replicate
6958 theNodesNot: list of groups of nodes NOT to replicate
6959 theShape: shape to detect affected elements (element which geometric center
6960 located on or inside shape).
6961 The replicated nodes should be associated to affected elements
6964 True if operation has been completed successfully, False otherwise
6967 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6969 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6971 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6972 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6975 theElems: list of groups of nodes or elements (edges or faces) to replicate
6976 theNodesNot: list of groups of nodes NOT to replicate
6977 theShape: shape to detect affected elements (element which geometric center
6978 located on or inside shape).
6979 The replicated nodes should be associated to affected elements
6982 groups of affected elements in order: volumes, faces, edges
6985 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6987 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6990 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6991 The list of groups must describe a partition of the mesh volumes.
6992 The nodes of the internal faces at the boundaries of the groups are doubled.
6993 In option, the internal faces are replaced by flat elements.
6994 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6997 theDomains: list of groups of volumes
6998 createJointElems: if True, create the elements
6999 onAllBoundaries: if True, the nodes and elements are also created on
7000 the boundary between *theDomains* and the rest mesh
7003 True if operation has been completed successfully, False otherwise
7006 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7008 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7010 Double nodes on some external faces and create flat elements.
7011 Flat elements are mainly used by some types of mechanic calculations.
7013 Each group of the list must be constituted of faces.
7014 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7017 theGroupsOfFaces: list of groups of faces
7020 True if operation has been completed successfully, False otherwise
7023 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7025 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7027 Identify all the elements around a geom shape, get the faces delimiting the hole
7029 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7031 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7033 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7034 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7035 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7036 If there are several paths connecting a pair of points, the shortest path is
7037 selected by the module. Position of the cutting plane is defined by the two
7038 points and an optional vector lying on the plane specified by a PolySegment.
7039 By default the vector is defined by Mesh module as following. A middle point
7040 of the two given points is computed. The middle point is projected to the mesh.
7041 The vector goes from the middle point to the projection point. In case of planar
7042 mesh, the vector is normal to the mesh.
7044 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7047 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7048 groupName: optional name of a group where created mesh segments will be added.
7051 editor = self.editor
7053 editor = self.mesh.GetMeshEditPreviewer()
7054 segmentsRes = editor.MakePolyLine( segments, groupName )
7055 for i, seg in enumerate( segmentsRes ):
7056 segments[i].vector = seg.vector
7058 return editor.GetPreviewData()
7061 def MakeSlot(self, segmentGroup, width ):
7063 Create a slot of given width around given 1D elements lying on a triangle mesh.
7064 The slot is constructed by cutting faces by cylindrical surfaces made
7065 around each segment. Segments are expected to be created by MakePolyLine().
7068 FaceEdge's located at the slot boundary
7070 return self.editor.MakeSlot( segmentGroup, width )
7072 def GetFunctor(self, funcType ):
7074 Return a cached numerical functor by its type.
7077 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7078 Note that not all items correspond to numerical functors.
7081 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7084 fn = self.functors[ funcType._v ]
7086 fn = self.smeshpyD.GetFunctor(funcType)
7087 fn.SetMesh(self.mesh)
7088 self.functors[ funcType._v ] = fn
7091 def FunctorValue(self, funcType, elemId, isElem=True):
7093 Return value of a functor for a given element
7096 funcType: an item of :class:`SMESH.FunctorType` enum.
7097 elemId: element or node ID
7098 isElem: *elemId* is ID of element or node
7101 the functor value or zero in case of invalid arguments
7104 fn = self.GetFunctor( funcType )
7105 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7106 val = fn.GetValue(elemId)
7111 def GetLength(self, elemId=None):
7113 Get length of given 1D elements or of all 1D mesh elements
7116 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.
7119 Sum of lengths of given elements
7124 length = self.smeshpyD.GetLength(self)
7125 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7126 length = self.smeshpyD.GetLength(elemId)
7129 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7131 length += self.smeshpyD.GetLength(obj)
7132 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7133 unRegister = genObjUnRegister()
7134 obj = self.GetIDSource( elemId )
7135 unRegister.set( obj )
7136 length = self.smeshpyD.GetLength( obj )
7138 length = self.FunctorValue(SMESH.FT_Length, elemId)
7141 def GetArea(self, elemId=None):
7143 Get area of given 2D elements or of all 2D mesh elements
7146 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.
7149 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7154 area = self.smeshpyD.GetArea(self)
7155 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7156 area = self.smeshpyD.GetArea(elemId)
7159 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7161 area += self.smeshpyD.GetArea(obj)
7162 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7163 unRegister = genObjUnRegister()
7164 obj = self.GetIDSource( elemId )
7165 unRegister.set( obj )
7166 area = self.smeshpyD.GetArea( obj )
7168 area = self.FunctorValue(SMESH.FT_Area, elemId)
7171 def GetVolume(self, elemId=None):
7173 Get volume of given 3D elements or of all 3D mesh elements
7176 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.
7179 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7184 volume= self.smeshpyD.GetVolume(self)
7185 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7186 volume= self.smeshpyD.GetVolume(elemId)
7189 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7191 volume+= self.smeshpyD.GetVolume(obj)
7192 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7193 unRegister = genObjUnRegister()
7194 obj = self.GetIDSource( elemId )
7195 unRegister.set( obj )
7196 volume= self.smeshpyD.GetVolume( obj )
7198 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7201 def GetAngle(self, node1, node2, node3 ):
7203 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7206 node1,node2,node3: IDs of the three nodes
7209 Angle in radians [0,PI]. -1 if failure case.
7211 p1 = self.GetNodeXYZ( node1 )
7212 p2 = self.GetNodeXYZ( node2 )
7213 p3 = self.GetNodeXYZ( node3 )
7214 if p1 and p2 and p3:
7215 return self.smeshpyD.GetAngle( p1,p2,p3 )
7219 def GetMaxElementLength(self, elemId):
7221 Get maximum element length.
7224 elemId: mesh element ID
7227 element's maximum length value
7230 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7231 ftype = SMESH.FT_MaxElementLength3D
7233 ftype = SMESH.FT_MaxElementLength2D
7234 return self.FunctorValue(ftype, elemId)
7236 def GetAspectRatio(self, elemId):
7238 Get aspect ratio of 2D or 3D element.
7241 elemId: mesh element ID
7244 element's aspect ratio value
7247 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7248 ftype = SMESH.FT_AspectRatio3D
7250 ftype = SMESH.FT_AspectRatio
7251 return self.FunctorValue(ftype, elemId)
7253 def GetWarping(self, elemId):
7255 Get warping angle of 2D element.
7258 elemId: mesh element ID
7261 element's warping angle value
7264 return self.FunctorValue(SMESH.FT_Warping, elemId)
7266 def GetMinimumAngle(self, elemId):
7268 Get minimum angle of 2D element.
7271 elemId: mesh element ID
7274 element's minimum angle value
7277 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7279 def GetTaper(self, elemId):
7281 Get taper of 2D element.
7284 elemId: mesh element ID
7287 element's taper value
7290 return self.FunctorValue(SMESH.FT_Taper, elemId)
7292 def GetSkew(self, elemId):
7294 Get skew of 2D element.
7297 elemId: mesh element ID
7300 element's skew value
7303 return self.FunctorValue(SMESH.FT_Skew, elemId)
7305 def GetMinMax(self, funType, meshPart=None):
7307 Return minimal and maximal value of a given functor.
7310 funType (SMESH.FunctorType): a functor type.
7311 Note that not all items of :class:`SMESH.FunctorType` corresponds
7312 to numerical functors.
7313 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7319 unRegister = genObjUnRegister()
7320 if isinstance( meshPart, list ):
7321 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7322 unRegister.set( meshPart )
7323 if isinstance( meshPart, Mesh ):
7324 meshPart = meshPart.mesh
7325 fun = self.GetFunctor( funType )
7328 if hasattr( meshPart, "SetMesh" ):
7329 meshPart.SetMesh( self.mesh ) # set mesh to filter
7330 hist = fun.GetLocalHistogram( 1, False, meshPart )
7332 hist = fun.GetHistogram( 1, False )
7334 return hist[0].min, hist[0].max
7337 pass # end of Mesh class
7340 class meshProxy(SMESH._objref_SMESH_Mesh):
7342 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7343 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7345 def __init__(self,*args):
7346 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7347 def __deepcopy__(self, memo=None):
7348 new = self.__class__(self)
7350 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7351 if len( args ) == 3:
7352 args += SMESH.ALL_NODES, True
7353 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7354 def ExportToMEDX(self, *args): # function removed
7355 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7356 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7357 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7358 def ExportToMED(self, *args): # function removed
7359 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7360 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7362 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7364 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7365 def ExportPartToMED(self, *args): # 'version' parameter removed
7366 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7367 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7368 def ExportMED(self, *args): # signature of method changed
7369 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7371 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7373 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7375 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7378 class submeshProxy(SMESH._objref_SMESH_subMesh):
7381 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7383 def __init__(self,*args):
7384 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7386 def __deepcopy__(self, memo=None):
7387 new = self.__class__(self)
7390 def Compute(self,refresh=False):
7392 Compute the sub-mesh and return the status of the computation
7395 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7400 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7401 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7405 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7407 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7409 if salome.sg.hasDesktop():
7410 if refresh: salome.sg.updateObjBrowser()
7415 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7418 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7420 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7421 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7424 def __init__(self,*args):
7425 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7427 def __getattr__(self, name ): # method called if an attribute not found
7428 if not self.mesh: # look for name() method in Mesh class
7429 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7430 if hasattr( self.mesh, name ):
7431 return getattr( self.mesh, name )
7432 if name == "ExtrusionAlongPathObjX":
7433 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7434 print("meshEditor: attribute '%s' NOT FOUND" % name)
7436 def __deepcopy__(self, memo=None):
7437 new = self.__class__(self)
7439 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7440 if len( args ) == 1: args += False,
7441 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7442 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7443 if len( args ) == 2: args += False,
7444 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7445 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7446 if len( args ) == 1:
7447 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7448 NodesToKeep = args[1]
7449 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7450 unRegister = genObjUnRegister()
7452 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7453 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7454 if not isinstance( NodesToKeep, list ):
7455 NodesToKeep = [ NodesToKeep ]
7456 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7458 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7460 class Pattern(SMESH._objref_SMESH_Pattern):
7462 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7463 variables in some methods
7466 def LoadFromFile(self, patternTextOrFile ):
7467 text = patternTextOrFile
7468 if os.path.exists( text ):
7469 text = open( patternTextOrFile ).read()
7471 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7473 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7474 decrFun = lambda i: i-1
7475 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7476 theMesh.SetParameters(Parameters)
7477 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7479 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7480 decrFun = lambda i: i-1
7481 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7482 theMesh.SetParameters(Parameters)
7483 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7485 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7486 if isinstance( mesh, Mesh ):
7487 mesh = mesh.GetMesh()
7488 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7490 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7492 Registering the new proxy for Pattern
7497 Private class used to bind methods creating algorithms to the class Mesh
7500 def __init__(self, method):
7502 self.defaultAlgoType = ""
7503 self.algoTypeToClass = {}
7504 self.method = method
7506 def add(self, algoClass):
7508 Store a python class of algorithm
7510 if inspect.isclass(algoClass) and \
7511 hasattr( algoClass, "algoType"):
7512 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7513 if not self.defaultAlgoType and \
7514 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7515 self.defaultAlgoType = algoClass.algoType
7516 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7518 def copy(self, mesh):
7520 Create a copy of self and assign mesh to the copy
7523 other = algoCreator( self.method )
7524 other.defaultAlgoType = self.defaultAlgoType
7525 other.algoTypeToClass = self.algoTypeToClass
7529 def __call__(self,algo="",geom=0,*args):
7531 Create an instance of algorithm
7535 if isinstance( algo, str ):
7537 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7538 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7543 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7545 elif not algoType and isinstance( geom, str ):
7550 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7552 elif isinstance( arg, str ) and not algoType:
7555 import traceback, sys
7556 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7557 sys.stderr.write( msg + '\n' )
7558 tb = traceback.extract_stack(None,2)
7559 traceback.print_list( [tb[0]] )
7561 algoType = self.defaultAlgoType
7562 if not algoType and self.algoTypeToClass:
7563 algoType = sorted( self.algoTypeToClass.keys() )[0]
7564 if algoType in self.algoTypeToClass:
7565 #print("Create algo",algoType)
7566 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7567 raise RuntimeError( "No class found for algo type %s" % algoType)
7570 class hypMethodWrapper:
7572 Private class used to substitute and store variable parameters of hypotheses.
7575 def __init__(self, hyp, method):
7577 self.method = method
7578 #print("REBIND:", method.__name__)
7581 def __call__(self,*args):
7583 call a method of hypothesis with calling SetVarParameter() before
7587 return self.method( self.hyp, *args ) # hypothesis method with no args
7589 #print("MethWrapper.__call__", self.method.__name__, args)
7591 parsed = ParseParameters(*args) # replace variables with their values
7592 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7593 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7594 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7595 # maybe there is a replaced string arg which is not variable
7596 result = self.method( self.hyp, *args )
7597 except ValueError as detail: # raised by ParseParameters()
7599 result = self.method( self.hyp, *args )
7600 except omniORB.CORBA.BAD_PARAM:
7601 raise ValueError(detail) # wrong variable name
7606 class genObjUnRegister:
7608 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7611 def __init__(self, genObj=None):
7612 self.genObjList = []
7616 def set(self, genObj):
7617 "Store one or a list of of SALOME.GenericObj'es"
7618 if isinstance( genObj, list ):
7619 self.genObjList.extend( genObj )
7621 self.genObjList.append( genObj )
7625 for genObj in self.genObjList:
7626 if genObj and hasattr( genObj, "UnRegister" ):
7629 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7631 Bind methods creating mesher plug-ins to the Mesh class
7634 # print("pluginName: ", pluginName)
7635 pluginBuilderName = pluginName + "Builder"
7637 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7638 except Exception as e:
7639 from salome_utils import verbose
7640 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7642 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7643 plugin = eval( pluginBuilderName )
7644 # print(" plugin:" , str(plugin))
7646 # add methods creating algorithms to Mesh
7647 for k in dir( plugin ):
7648 if k[0] == '_': continue
7649 algo = getattr( plugin, k )
7650 #print(" algo:", str(algo))
7651 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7652 #print(" meshMethod:" , str(algo.meshMethod))
7653 if not hasattr( Mesh, algo.meshMethod ):
7654 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7656 _mmethod = getattr( Mesh, algo.meshMethod )
7657 if hasattr( _mmethod, "add" ):