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>`
2096 return self.mesh.SetMeshOrder(submeshes)
2098 def Clear(self, refresh=False):
2100 Remove all nodes and elements generated on geometry. Imported elements remain.
2103 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2107 if ( salome.sg.hasDesktop() ):
2108 if refresh: salome.sg.updateObjBrowser()
2110 def ClearSubMesh(self, geomId, refresh=False):
2112 Remove all nodes and elements of indicated shape
2115 geomId: the ID of a sub-shape to remove elements on
2116 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2119 self.mesh.ClearSubMesh(geomId)
2120 if salome.sg.hasDesktop():
2121 if refresh: salome.sg.updateObjBrowser()
2123 def AutomaticTetrahedralization(self, fineness=0):
2125 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2128 fineness: [0.0,1.0] defines mesh fineness
2134 dim = self.MeshDimension()
2136 self.RemoveGlobalHypotheses()
2137 self.Segment().AutomaticLength(fineness)
2139 self.Triangle().LengthFromEdges()
2144 return self.Compute()
2146 def AutomaticHexahedralization(self, fineness=0):
2148 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2151 fineness: [0.0, 1.0] defines mesh fineness
2157 dim = self.MeshDimension()
2158 # assign the hypotheses
2159 self.RemoveGlobalHypotheses()
2160 self.Segment().AutomaticLength(fineness)
2167 return self.Compute()
2169 def AddHypothesis(self, hyp, geom=0):
2174 hyp: a hypothesis to assign
2175 geom: a subhape of mesh geometry
2178 :class:`SMESH.Hypothesis_Status`
2181 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2182 hyp, geom = geom, hyp
2183 if isinstance( hyp, Mesh_Algorithm ):
2184 hyp = hyp.GetAlgorithm()
2189 geom = self.mesh.GetShapeToMesh()
2192 if self.mesh.HasShapeToMesh():
2193 hyp_type = hyp.GetName()
2194 lib_name = hyp.GetLibName()
2195 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2196 # if checkAll and geom:
2197 # checkAll = geom.GetType() == 37
2199 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2201 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2202 status = self.mesh.AddHypothesis(geom, hyp)
2204 status = HYP_BAD_GEOMETRY, ""
2205 hyp_name = GetName( hyp )
2208 geom_name = geom.GetName()
2209 isAlgo = hyp._narrow( SMESH_Algo )
2210 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2213 def IsUsedHypothesis(self, hyp, geom):
2215 Return True if an algorithm or hypothesis is assigned to a given shape
2218 hyp: an algorithm or hypothesis to check
2219 geom: a subhape of mesh geometry
2225 if not hyp: # or not geom
2227 if isinstance( hyp, Mesh_Algorithm ):
2228 hyp = hyp.GetAlgorithm()
2230 hyps = self.GetHypothesisList(geom)
2232 if h.GetId() == hyp.GetId():
2236 def RemoveHypothesis(self, hyp, geom=0):
2238 Unassign a hypothesis
2241 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2242 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2245 :class:`SMESH.Hypothesis_Status`
2250 if isinstance( hyp, Mesh_Algorithm ):
2251 hyp = hyp.GetAlgorithm()
2257 if self.IsUsedHypothesis( hyp, shape ):
2258 return self.mesh.RemoveHypothesis( shape, hyp )
2259 hypName = GetName( hyp )
2260 geoName = GetName( shape )
2261 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2264 def GetHypothesisList(self, geom):
2266 Get the list of hypotheses added on a geometry
2269 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2272 the sequence of :class:`SMESH.SMESH_Hypothesis`
2275 return self.mesh.GetHypothesisList( geom )
2277 def RemoveGlobalHypotheses(self):
2279 Remove all global hypotheses
2282 current_hyps = self.mesh.GetHypothesisList( self.geom )
2283 for hyp in current_hyps:
2284 self.mesh.RemoveHypothesis( self.geom, hyp )
2287 def ExportMED(self, *args, **kwargs):
2289 Export the mesh in a file in MED format
2290 allowing to overwrite the file if it exists or add the exported data to its contents
2293 fileName: is the file name
2294 auto_groups (boolean): parameter for creating/not creating
2295 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2296 the typical use is auto_groups=False.
2297 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2298 The minor must be between 0 and the current minor version of MED file library.
2299 If minor is equal to -1, the minor version is not changed (default).
2300 The major version (x, where version is x.y.z) cannot be changed.
2301 overwrite (boolean): parameter for overwriting/not overwriting the file
2302 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2303 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2305 - 1D if all mesh nodes lie on OX coordinate axis, or
2306 - 2D if all mesh nodes lie on XOY coordinate plane, or
2307 - 3D in the rest cases.
2309 If *autoDimension* is *False*, the space dimension is always 3.
2310 fields: list of GEOM fields defined on the shape to mesh.
2311 geomAssocFields: each character of this string means a need to export a
2312 corresponding field; correspondence between fields and characters
2315 - 'v' stands for "_vertices_" field;
2316 - 'e' stands for "_edges_" field;
2317 - 'f' stands for "_faces_" field;
2318 - 's' stands for "_solids_" field.
2320 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2321 close to zero within a given tolerance, the coordinate is set to zero.
2322 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2324 # process positional arguments
2325 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2327 auto_groups = args[1] if len(args) > 1 else False
2328 minor = args[2] if len(args) > 2 else -1
2329 overwrite = args[3] if len(args) > 3 else True
2330 meshPart = args[4] if len(args) > 4 else None
2331 autoDimension = args[5] if len(args) > 5 else True
2332 fields = args[6] if len(args) > 6 else []
2333 geomAssocFields = args[7] if len(args) > 7 else ''
2334 z_tolerance = args[8] if len(args) > 8 else -1.
2335 # process keywords arguments
2336 auto_groups = kwargs.get("auto_groups", auto_groups)
2337 minor = kwargs.get("minor", minor)
2338 overwrite = kwargs.get("overwrite", overwrite)
2339 meshPart = kwargs.get("meshPart", meshPart)
2340 autoDimension = kwargs.get("autoDimension", autoDimension)
2341 fields = kwargs.get("fields", fields)
2342 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2343 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2345 # invoke engine's function
2346 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2347 unRegister = genObjUnRegister()
2348 if isinstance( meshPart, list ):
2349 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2350 unRegister.set( meshPart )
2352 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2353 self.mesh.SetParameters(Parameters)
2355 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2356 fields, geomAssocFields, z_tolerance)
2358 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2360 def ExportSAUV(self, f, auto_groups=0):
2362 Export the mesh in a file in SAUV format
2367 auto_groups: boolean parameter for creating/not creating
2368 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2369 the typical use is auto_groups=False.
2372 self.mesh.ExportSAUV(f, auto_groups)
2374 def ExportDAT(self, f, meshPart=None):
2376 Export the mesh in a file in DAT format
2380 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2384 unRegister = genObjUnRegister()
2385 if isinstance( meshPart, list ):
2386 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2387 unRegister.set( meshPart )
2388 self.mesh.ExportPartToDAT( meshPart, f )
2390 self.mesh.ExportDAT(f)
2392 def ExportUNV(self, f, meshPart=None):
2394 Export the mesh in a file in UNV format
2398 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2402 unRegister = genObjUnRegister()
2403 if isinstance( meshPart, list ):
2404 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2405 unRegister.set( meshPart )
2406 self.mesh.ExportPartToUNV( meshPart, f )
2408 self.mesh.ExportUNV(f)
2410 def ExportSTL(self, f, ascii=1, meshPart=None):
2412 Export the mesh in a file in STL format
2416 ascii: defines the file encoding
2417 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2421 unRegister = genObjUnRegister()
2422 if isinstance( meshPart, list ):
2423 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2424 unRegister.set( meshPart )
2425 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2427 self.mesh.ExportSTL(f, ascii)
2429 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2431 Export the mesh in a file in CGNS format
2435 overwrite: boolean parameter for overwriting/not overwriting the file
2436 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2437 groupElemsByType: if True all elements of same entity type are exported at ones,
2438 else elements are exported in order of their IDs which can cause creation
2439 of multiple cgns sections
2442 unRegister = genObjUnRegister()
2443 if isinstance( meshPart, list ):
2444 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2445 unRegister.set( meshPart )
2446 if isinstance( meshPart, Mesh ):
2447 meshPart = meshPart.mesh
2449 meshPart = self.mesh
2450 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2452 def ExportGMF(self, f, meshPart=None):
2454 Export the mesh in a file in GMF format.
2455 GMF files must have .mesh extension for the ASCII format and .meshb for
2456 the bynary format. Other extensions are not allowed.
2460 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2463 unRegister = genObjUnRegister()
2464 if isinstance( meshPart, list ):
2465 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2466 unRegister.set( meshPart )
2467 if isinstance( meshPart, Mesh ):
2468 meshPart = meshPart.mesh
2470 meshPart = self.mesh
2471 self.mesh.ExportGMF(meshPart, f, True)
2473 def ExportToMED(self, *args, **kwargs):
2475 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2476 Export the mesh in a file in MED format
2477 allowing to overwrite the file if it exists or add the exported data to its contents
2480 fileName: the file name
2481 opt (boolean): parameter for creating/not creating
2482 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2483 overwrite: boolean parameter for overwriting/not overwriting the file
2484 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2486 - 1D if all mesh nodes lie on OX coordinate axis, or
2487 - 2D if all mesh nodes lie on XOY coordinate plane, or
2488 - 3D in the rest cases.
2490 If **autoDimension** is *False*, the space dimension is always 3.
2493 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2494 # process positional arguments
2495 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2497 auto_groups = args[1] if len(args) > 1 else False
2498 overwrite = args[2] if len(args) > 2 else True
2499 autoDimension = args[3] if len(args) > 3 else True
2500 # process keywords arguments
2501 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2502 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2503 overwrite = kwargs.get("overwrite", overwrite)
2504 autoDimension = kwargs.get("autoDimension", autoDimension)
2506 # invoke engine's function
2507 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2509 def ExportToMEDX(self, *args, **kwargs):
2511 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2512 Export the mesh in a file in MED format
2515 fileName: the file name
2516 opt (boolean): parameter for creating/not creating
2517 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2518 overwrite: boolean parameter for overwriting/not overwriting the file
2519 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2521 - 1D if all mesh nodes lie on OX coordinate axis, or
2522 - 2D if all mesh nodes lie on XOY coordinate plane, or
2523 - 3D in the rest cases.
2525 If **autoDimension** is *False*, the space dimension is always 3.
2528 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2529 # process positional arguments
2530 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2532 auto_groups = args[1] if len(args) > 1 else False
2533 overwrite = args[2] if len(args) > 2 else True
2534 autoDimension = args[3] if len(args) > 3 else True
2535 # process keywords arguments
2536 auto_groups = kwargs.get("auto_groups", auto_groups)
2537 overwrite = kwargs.get("overwrite", overwrite)
2538 autoDimension = kwargs.get("autoDimension", autoDimension)
2540 # invoke engine's function
2541 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2545 def Append(self, meshes, uniteIdenticalGroups = True,
2546 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2548 Append given meshes into this mesh.
2549 All groups of input meshes will be created in this mesh.
2552 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2553 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2554 mergeNodesAndElements: if True, equal nodes and elements are merged
2555 mergeTolerance: tolerance for merging nodes
2556 allGroups: forces creation of groups corresponding to every input mesh
2558 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2559 mergeNodesAndElements, mergeTolerance, allGroups,
2560 meshToAppendTo = self.GetMesh() )
2562 # Operations with groups:
2563 # ----------------------
2564 def CreateEmptyGroup(self, elementType, name):
2566 Create an empty standalone mesh group
2569 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2570 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2571 name: the name of the mesh group
2574 :class:`SMESH.SMESH_Group`
2577 return self.mesh.CreateGroup(elementType, name)
2579 def Group(self, grp, name=""):
2581 Create a mesh group based on the geometric object *grp*
2582 and give it a *name*.
2583 If *name* is not defined the name of the geometric group is used
2586 Works like :meth:`GroupOnGeom`.
2589 grp: a geometric group, a vertex, an edge, a face or a solid
2590 name: the name of the mesh group
2593 :class:`SMESH.SMESH_GroupOnGeom`
2596 return self.GroupOnGeom(grp, name)
2598 def GroupOnGeom(self, grp, name="", typ=None):
2600 Create a mesh group based on the geometrical object *grp*
2601 and give it a *name*.
2602 if *name* is not defined the name of the geometric group is used
2605 grp: a geometrical group, a vertex, an edge, a face or a solid
2606 name: the name of the mesh group
2607 typ: the type of elements in the group; either of
2608 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2609 automatically detected by the type of the geometry
2612 :class:`SMESH.SMESH_GroupOnGeom`
2615 AssureGeomPublished( self, grp, name )
2617 name = grp.GetName()
2619 typ = self._groupTypeFromShape( grp )
2620 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2622 def _groupTypeFromShape( self, shape ):
2624 Pivate method to get a type of group on geometry
2626 tgeo = str(shape.GetShapeType())
2627 if tgeo == "VERTEX":
2629 elif tgeo == "EDGE" or tgeo == "WIRE":
2631 elif tgeo == "FACE" or tgeo == "SHELL":
2633 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2635 elif tgeo == "COMPOUND":
2636 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2638 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2639 return self._groupTypeFromShape( sub[0] )
2641 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2644 def GroupOnFilter(self, typ, name, filter):
2646 Create a mesh group with given *name* based on the *filter*.
2647 It is a special type of group dynamically updating it's contents during
2651 typ: the type of elements in the group; either of
2652 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2653 name: the name of the mesh group
2654 filter (SMESH.Filter): the filter defining group contents
2657 :class:`SMESH.SMESH_GroupOnFilter`
2660 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2662 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2664 Create a mesh group by the given ids of elements
2667 groupName: the name of the mesh group
2668 elementType: the type of elements in the group; either of
2669 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2670 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2673 :class:`SMESH.SMESH_Group`
2676 group = self.mesh.CreateGroup(elementType, groupName)
2677 if isinstance( elemIDs, Mesh ):
2678 elemIDs = elemIDs.GetMesh()
2679 if hasattr( elemIDs, "GetIDs" ):
2680 if hasattr( elemIDs, "SetMesh" ):
2681 elemIDs.SetMesh( self.GetMesh() )
2682 group.AddFrom( elemIDs )
2690 CritType=FT_Undefined,
2693 UnaryOp=FT_Undefined,
2696 Create a mesh group by the given conditions
2699 groupName: the name of the mesh group
2700 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2701 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2702 Note that the items starting from FT_LessThan are not suitable for CritType.
2703 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2704 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2705 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2706 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2707 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2710 :class:`SMESH.SMESH_GroupOnFilter`
2713 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2714 group = self.MakeGroupByCriterion(groupName, aCriterion)
2717 def MakeGroupByCriterion(self, groupName, Criterion):
2719 Create a mesh group by the given criterion
2722 groupName: the name of the mesh group
2723 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2726 :class:`SMESH.SMESH_GroupOnFilter`
2729 :meth:`smeshBuilder.GetCriterion`
2732 return self.MakeGroupByCriteria( groupName, [Criterion] )
2734 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2736 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2739 groupName: the name of the mesh group
2740 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2741 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2744 :class:`SMESH.SMESH_GroupOnFilter`
2747 :meth:`smeshBuilder.GetCriterion`
2750 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2751 group = self.MakeGroupByFilter(groupName, aFilter)
2754 def MakeGroupByFilter(self, groupName, theFilter):
2756 Create a mesh group by the given filter
2759 groupName (string): the name of the mesh group
2760 theFilter (SMESH.Filter): the filter
2763 :class:`SMESH.SMESH_GroupOnFilter`
2766 :meth:`smeshBuilder.GetFilter`
2769 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2770 #theFilter.SetMesh( self.mesh )
2771 #group.AddFrom( theFilter )
2772 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2775 def RemoveGroup(self, group):
2780 group (SMESH.SMESH_GroupBase): group to remove
2783 self.mesh.RemoveGroup(group)
2785 def RemoveGroupWithContents(self, group):
2787 Remove a group with its contents
2790 group (SMESH.SMESH_GroupBase): group to remove
2793 This operation can create gaps in numeration of nodes or elements.
2794 Call :meth:`RenumberElements` to remove the gaps.
2797 self.mesh.RemoveGroupWithContents(group)
2799 def GetGroups(self, elemType = SMESH.ALL):
2801 Get the list of groups existing in the mesh in the order of creation
2802 (starting from the oldest one)
2805 elemType (SMESH.ElementType): type of elements the groups contain;
2806 by default groups of elements of all types are returned
2809 a list of :class:`SMESH.SMESH_GroupBase`
2812 groups = self.mesh.GetGroups()
2813 if elemType == SMESH.ALL:
2817 if g.GetType() == elemType:
2818 typedGroups.append( g )
2825 Get the number of groups existing in the mesh
2828 the quantity of groups as an integer value
2831 return self.mesh.NbGroups()
2833 def GetGroupNames(self):
2835 Get the list of names of groups existing in the mesh
2841 groups = self.GetGroups()
2843 for group in groups:
2844 names.append(group.GetName())
2847 def GetGroupByName(self, name, elemType = None):
2849 Find groups by name and type
2852 name (string): name of the group of interest
2853 elemType (SMESH.ElementType): type of elements the groups contain;
2854 by default one group of any type is returned;
2855 if elemType == SMESH.ALL then all groups of any type are returned
2858 a list of :class:`SMESH.SMESH_GroupBase`
2862 for group in self.GetGroups():
2863 if group.GetName() == name:
2864 if elemType is None:
2866 if ( elemType == SMESH.ALL or
2867 group.GetType() == elemType ):
2868 groups.append( group )
2871 def UnionGroups(self, group1, group2, name):
2873 Produce a union of two groups.
2874 A new group is created. All mesh elements that are
2875 present in the initial groups are added to the new one
2878 group1 (SMESH.SMESH_GroupBase): a group
2879 group2 (SMESH.SMESH_GroupBase): another group
2882 instance of :class:`SMESH.SMESH_Group`
2885 return self.mesh.UnionGroups(group1, group2, name)
2887 def UnionListOfGroups(self, groups, name):
2889 Produce a union list of groups.
2890 New group is created. All mesh elements that are present in
2891 initial groups are added to the new one
2894 groups: list of :class:`SMESH.SMESH_GroupBase`
2897 instance of :class:`SMESH.SMESH_Group`
2899 return self.mesh.UnionListOfGroups(groups, name)
2901 def IntersectGroups(self, group1, group2, name):
2903 Prodice an intersection of two groups.
2904 A new group is created. All mesh elements that are common
2905 for the two initial groups are added to the new one.
2908 group1 (SMESH.SMESH_GroupBase): a group
2909 group2 (SMESH.SMESH_GroupBase): another group
2912 instance of :class:`SMESH.SMESH_Group`
2915 return self.mesh.IntersectGroups(group1, group2, name)
2917 def IntersectListOfGroups(self, groups, name):
2919 Produce an intersection of groups.
2920 New group is created. All mesh elements that are present in all
2921 initial groups simultaneously are added to the new one
2924 groups: a list of :class:`SMESH.SMESH_GroupBase`
2927 instance of :class:`SMESH.SMESH_Group`
2929 return self.mesh.IntersectListOfGroups(groups, name)
2931 def CutGroups(self, main_group, tool_group, name):
2933 Produce a cut of two groups.
2934 A new group is created. All mesh elements that are present in
2935 the main group but are not present in the tool group are added to the new one
2938 main_group (SMESH.SMESH_GroupBase): a group to cut from
2939 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2942 an instance of :class:`SMESH.SMESH_Group`
2945 return self.mesh.CutGroups(main_group, tool_group, name)
2947 def CutListOfGroups(self, main_groups, tool_groups, name):
2949 Produce a cut of groups.
2950 A new group is created. All mesh elements that are present in main groups
2951 but do not present in tool groups are added to the new one
2954 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2955 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2958 an instance of :class:`SMESH.SMESH_Group`
2961 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2963 def CreateDimGroup(self, groups, elemType, name,
2964 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2966 Create a standalone group of entities basing on nodes of other groups.
2969 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2970 elemType: a type of elements to include to the new group; either of
2971 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2972 name: a name of the new group.
2973 nbCommonNodes: a criterion of inclusion of an element to the new group
2974 basing on number of element nodes common with reference *groups*.
2975 Meaning of possible values are:
2977 - SMESH.ALL_NODES - include if all nodes are common,
2978 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2979 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2980 - SMEHS.MAJORITY - include if half of nodes or more are common.
2981 underlyingOnly: if *True* (default), an element is included to the
2982 new group provided that it is based on nodes of an element of *groups*;
2983 in this case the reference *groups* are supposed to be of higher dimension
2984 than *elemType*, which can be useful for example to get all faces lying on
2985 volumes of the reference *groups*.
2988 an instance of :class:`SMESH.SMESH_Group`
2991 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2993 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2995 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
2997 Distribute all faces of the mesh among groups using sharp edges and optionally
2998 existing 1D elements as group boundaries.
3001 sharpAngle: edge is considered sharp if an angle between normals of
3002 adjacent faces is more than \a sharpAngle in degrees.
3003 createEdges (boolean): to create 1D elements for detected sharp edges.
3004 useExistingEdges (boolean): to use existing edges as group boundaries
3006 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3008 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3009 self.mesh.SetParameters(Parameters)
3010 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3012 def ConvertToStandalone(self, group):
3014 Convert group on geom into standalone group
3017 return self.mesh.ConvertToStandalone(group)
3019 # Get some info about mesh:
3020 # ------------------------
3022 def GetLog(self, clearAfterGet):
3024 Return the log of nodes and elements added or removed
3025 since the previous clear of the log.
3028 clearAfterGet: log is emptied after Get (safe if concurrents access)
3031 list of SMESH.log_block structures { commandType, number, coords, indexes }
3034 return self.mesh.GetLog(clearAfterGet)
3038 Clear the log of nodes and elements added or removed since the previous
3039 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3042 self.mesh.ClearLog()
3044 def SetAutoColor(self, theAutoColor):
3046 Toggle auto color mode on the object.
3047 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3050 theAutoColor (boolean): the flag which toggles auto color mode.
3053 self.mesh.SetAutoColor(theAutoColor)
3055 def GetAutoColor(self):
3057 Get flag of object auto color mode.
3063 return self.mesh.GetAutoColor()
3070 integer value, which is the internal Id of the mesh
3073 return self.mesh.GetId()
3075 def HasDuplicatedGroupNamesMED(self):
3077 Check the group names for duplications.
3078 Consider the maximum group name length stored in MED file.
3084 return self.mesh.HasDuplicatedGroupNamesMED()
3086 def GetMeshEditor(self):
3088 Obtain the mesh editor tool
3091 an instance of :class:`SMESH.SMESH_MeshEditor`
3096 def GetIDSource(self, ids, elemType = SMESH.ALL):
3098 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3099 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3103 elemType: type of elements; this parameter is used to distinguish
3104 IDs of nodes from IDs of elements; by default ids are treated as
3105 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3108 an instance of :class:`SMESH.SMESH_IDSource`
3111 call UnRegister() for the returned object as soon as it is no more useful::
3113 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3114 mesh.DoSomething( idSrc )
3118 if isinstance( ids, int ):
3120 return self.editor.MakeIDSource(ids, elemType)
3123 # Get information about mesh contents:
3124 # ------------------------------------
3126 def GetMeshInfo(self, obj = None):
3128 Get the mesh statistic.
3131 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3134 if not obj: obj = self.mesh
3135 return self.smeshpyD.GetMeshInfo(obj)
3139 Return the number of nodes in the mesh
3145 return self.mesh.NbNodes()
3147 def NbElements(self):
3149 Return the number of elements in the mesh
3155 return self.mesh.NbElements()
3157 def Nb0DElements(self):
3159 Return the number of 0d elements in the mesh
3165 return self.mesh.Nb0DElements()
3169 Return the number of ball discrete elements in the mesh
3175 return self.mesh.NbBalls()
3179 Return the number of edges in the mesh
3185 return self.mesh.NbEdges()
3187 def NbEdgesOfOrder(self, elementOrder):
3189 Return the number of edges with the given order in the mesh
3192 elementOrder: the order of elements
3193 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3199 return self.mesh.NbEdgesOfOrder(elementOrder)
3203 Return the number of faces in the mesh
3209 return self.mesh.NbFaces()
3211 def NbFacesOfOrder(self, elementOrder):
3213 Return the number of faces with the given order in the mesh
3216 elementOrder: the order of elements
3217 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3223 return self.mesh.NbFacesOfOrder(elementOrder)
3225 def NbTriangles(self):
3227 Return the number of triangles in the mesh
3233 return self.mesh.NbTriangles()
3235 def NbTrianglesOfOrder(self, elementOrder):
3237 Return the number of triangles with the given order in the mesh
3240 elementOrder: is the order of elements
3241 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3247 return self.mesh.NbTrianglesOfOrder(elementOrder)
3249 def NbBiQuadTriangles(self):
3251 Return the number of biquadratic triangles in the mesh
3257 return self.mesh.NbBiQuadTriangles()
3259 def NbQuadrangles(self):
3261 Return the number of quadrangles in the mesh
3267 return self.mesh.NbQuadrangles()
3269 def NbQuadranglesOfOrder(self, elementOrder):
3271 Return the number of quadrangles with the given order in the mesh
3274 elementOrder: the order of elements
3275 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3281 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3283 def NbBiQuadQuadrangles(self):
3285 Return the number of biquadratic quadrangles in the mesh
3291 return self.mesh.NbBiQuadQuadrangles()
3293 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3295 Return the number of polygons of given order in the mesh
3298 elementOrder: the order of elements
3299 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3305 return self.mesh.NbPolygonsOfOrder(elementOrder)
3307 def NbVolumes(self):
3309 Return the number of volumes in the mesh
3315 return self.mesh.NbVolumes()
3318 def NbVolumesOfOrder(self, elementOrder):
3320 Return the number of volumes with the given order in the mesh
3323 elementOrder: the order of elements
3324 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3330 return self.mesh.NbVolumesOfOrder(elementOrder)
3334 Return the number of tetrahedrons in the mesh
3340 return self.mesh.NbTetras()
3342 def NbTetrasOfOrder(self, elementOrder):
3344 Return the number of tetrahedrons with the given order in the mesh
3347 elementOrder: the order of elements
3348 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3354 return self.mesh.NbTetrasOfOrder(elementOrder)
3358 Return the number of hexahedrons in the mesh
3364 return self.mesh.NbHexas()
3366 def NbHexasOfOrder(self, elementOrder):
3368 Return the number of hexahedrons with the given order in the mesh
3371 elementOrder: the order of elements
3372 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3378 return self.mesh.NbHexasOfOrder(elementOrder)
3380 def NbTriQuadraticHexas(self):
3382 Return the number of triquadratic hexahedrons in the mesh
3388 return self.mesh.NbTriQuadraticHexas()
3390 def NbPyramids(self):
3392 Return the number of pyramids in the mesh
3398 return self.mesh.NbPyramids()
3400 def NbPyramidsOfOrder(self, elementOrder):
3402 Return the number of pyramids with the given order in the mesh
3405 elementOrder: the order of elements
3406 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3412 return self.mesh.NbPyramidsOfOrder(elementOrder)
3416 Return the number of prisms in the mesh
3422 return self.mesh.NbPrisms()
3424 def NbPrismsOfOrder(self, elementOrder):
3426 Return the number of prisms with the given order in the mesh
3429 elementOrder: the order of elements
3430 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3436 return self.mesh.NbPrismsOfOrder(elementOrder)
3438 def NbHexagonalPrisms(self):
3440 Return the number of hexagonal prisms in the mesh
3446 return self.mesh.NbHexagonalPrisms()
3448 def NbPolyhedrons(self):
3450 Return the number of polyhedrons in the mesh
3456 return self.mesh.NbPolyhedrons()
3458 def NbSubMesh(self):
3460 Return the number of submeshes in the mesh
3466 return self.mesh.NbSubMesh()
3468 def GetElementsId(self):
3470 Return the list of all mesh elements IDs
3473 the list of integer values
3476 :meth:`GetElementsByType`
3479 return self.mesh.GetElementsId()
3481 def GetElementsByType(self, elementType):
3483 Return the list of IDs of mesh elements with the given type
3486 elementType (SMESH.ElementType): the required type of elements
3489 list of integer values
3492 return self.mesh.GetElementsByType(elementType)
3494 def GetNodesId(self):
3496 Return the list of mesh nodes IDs
3499 the list of integer values
3502 return self.mesh.GetNodesId()
3504 # Get the information about mesh elements:
3505 # ------------------------------------
3507 def GetElementType(self, id, iselem=True):
3509 Return the type of mesh element or node
3512 the value from :class:`SMESH.ElementType` enumeration.
3513 Return SMESH.ALL if element or node with the given ID does not exist
3516 return self.mesh.GetElementType(id, iselem)
3518 def GetElementGeomType(self, id):
3520 Return the geometric type of mesh element
3523 the value from :class:`SMESH.EntityType` enumeration.
3526 return self.mesh.GetElementGeomType(id)
3528 def GetElementShape(self, id):
3530 Return the shape type of mesh element
3533 the value from :class:`SMESH.GeometryType` enumeration.
3536 return self.mesh.GetElementShape(id)
3538 def GetSubMeshElementsId(self, Shape):
3540 Return the list of sub-mesh elements IDs
3543 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3544 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3547 list of integer values
3550 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3551 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3554 return self.mesh.GetSubMeshElementsId(ShapeID)
3556 def GetSubMeshNodesId(self, Shape, all):
3558 Return the list of sub-mesh nodes IDs
3561 Shape: a geom object (sub-shape).
3562 *Shape* must be the sub-shape of a :meth:`GetShape`
3563 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3566 list of integer values
3569 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3570 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3573 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3575 def GetSubMeshElementType(self, Shape):
3577 Return type of elements on given shape
3580 Shape: a geom object (sub-shape).
3581 *Shape* must be a sub-shape of a ShapeToMesh()
3584 :class:`SMESH.ElementType`
3587 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3588 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3591 return self.mesh.GetSubMeshElementType(ShapeID)
3595 Get the mesh description
3601 return self.mesh.Dump()
3604 # Get the information about nodes and elements of a mesh by its IDs:
3605 # -----------------------------------------------------------
3607 def GetNodeXYZ(self, id):
3609 Get XYZ coordinates of a node.
3610 If there is no node for the given ID - return an empty list
3613 list of float values
3616 return self.mesh.GetNodeXYZ(id)
3618 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3620 Return list of IDs of inverse elements for the given node.
3621 If there is no node for the given ID - return an empty list
3625 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3628 list of integer values
3631 return self.mesh.GetNodeInverseElements(id,elemType)
3633 def GetNodePosition(self,NodeID):
3635 Return the position of a node on the shape
3638 :class:`SMESH.NodePosition`
3641 return self.mesh.GetNodePosition(NodeID)
3643 def GetElementPosition(self,ElemID):
3645 Return the position of an element on the shape
3648 :class:`SMESH.ElementPosition`
3651 return self.mesh.GetElementPosition(ElemID)
3653 def GetShapeID(self, id):
3655 Return the ID of the shape, on which the given node was generated.
3658 an integer value > 0 or -1 if there is no node for the given
3659 ID or the node is not assigned to any geometry
3662 return self.mesh.GetShapeID(id)
3664 def GetShapeIDForElem(self,id):
3666 Return the ID of the shape, on which the given element was generated.
3669 an integer value > 0 or -1 if there is no element for the given
3670 ID or the element is not assigned to any geometry
3673 return self.mesh.GetShapeIDForElem(id)
3675 def GetElemNbNodes(self, id):
3677 Return the number of nodes of the given element
3680 an integer value > 0 or -1 if there is no element for the given ID
3683 return self.mesh.GetElemNbNodes(id)
3685 def GetElemNode(self, id, index):
3687 Return the node ID the given (zero based) index for the given element.
3689 * If there is no element for the given ID - return -1.
3690 * If there is no node for the given index - return -2.
3693 id (int): element ID
3694 index (int): node index within the element
3697 an integer value (ID)
3700 :meth:`GetElemNodes`
3703 return self.mesh.GetElemNode(id, index)
3705 def GetElemNodes(self, id):
3707 Return the IDs of nodes of the given element
3710 a list of integer values
3713 return self.mesh.GetElemNodes(id)
3715 def IsMediumNode(self, elementID, nodeID):
3717 Return true if the given node is the medium node in the given quadratic element
3720 return self.mesh.IsMediumNode(elementID, nodeID)
3722 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3724 Return true if the given node is the medium node in one of quadratic elements
3727 nodeID: ID of the node
3728 elementType: the type of elements to check a state of the node, either of
3729 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3732 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3734 def ElemNbEdges(self, id):
3736 Return the number of edges for the given element
3739 return self.mesh.ElemNbEdges(id)
3741 def ElemNbFaces(self, id):
3743 Return the number of faces for the given element
3746 return self.mesh.ElemNbFaces(id)
3748 def GetElemFaceNodes(self,elemId, faceIndex):
3750 Return nodes of given face (counted from zero) for given volumic element.
3753 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3755 def GetFaceNormal(self, faceId, normalized=False):
3757 Return three components of normal of given mesh face
3758 (or an empty array in KO case)
3761 return self.mesh.GetFaceNormal(faceId,normalized)
3763 def FindElementByNodes(self, nodes):
3765 Return an element based on all given nodes.
3768 return self.mesh.FindElementByNodes(nodes)
3770 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3772 Return elements including all given nodes.
3775 return self.mesh.GetElementsByNodes( nodes, elemType )
3777 def IsPoly(self, id):
3779 Return true if the given element is a polygon
3782 return self.mesh.IsPoly(id)
3784 def IsQuadratic(self, id):
3786 Return true if the given element is quadratic
3789 return self.mesh.IsQuadratic(id)
3791 def GetBallDiameter(self, id):
3793 Return diameter of a ball discrete element or zero in case of an invalid *id*
3796 return self.mesh.GetBallDiameter(id)
3798 def BaryCenter(self, id):
3800 Return XYZ coordinates of the barycenter of the given element.
3801 If there is no element for the given ID - return an empty list
3804 a list of three double values
3807 :meth:`smeshBuilder.GetGravityCenter`
3810 return self.mesh.BaryCenter(id)
3812 def GetIdsFromFilter(self, filter, meshParts=[] ):
3814 Pass mesh elements through the given filter and return IDs of fitting elements
3817 filter: :class:`SMESH.Filter`
3818 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3824 :meth:`SMESH.Filter.GetIDs`
3825 :meth:`SMESH.Filter.GetElementsIdFromParts`
3828 filter.SetMesh( self.mesh )
3831 if isinstance( meshParts, Mesh ):
3832 filter.SetMesh( meshParts.GetMesh() )
3833 return theFilter.GetIDs()
3834 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3835 meshParts = [ meshParts ]
3836 return filter.GetElementsIdFromParts( meshParts )
3838 return filter.GetIDs()
3840 # Get mesh measurements information:
3841 # ------------------------------------
3843 def GetFreeBorders(self):
3845 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3846 Return a list of special structures (borders).
3849 a list of :class:`SMESH.FreeEdges.Border`
3852 aFilterMgr = self.smeshpyD.CreateFilterManager()
3853 aPredicate = aFilterMgr.CreateFreeEdges()
3854 aPredicate.SetMesh(self.mesh)
3855 aBorders = aPredicate.GetBorders()
3856 aFilterMgr.UnRegister()
3859 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3861 Get minimum distance between two nodes, elements or distance to the origin
3864 id1: first node/element id
3865 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3866 isElem1: *True* if *id1* is element id, *False* if it is node id
3867 isElem2: *True* if *id2* is element id, *False* if it is node id
3870 minimum distance value
3872 :meth:`GetMinDistance`
3875 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3876 return aMeasure.value
3878 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3880 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3883 id1: first node/element id
3884 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3885 isElem1: *True* if *id1* is element id, *False* if it is node id
3886 isElem2: *True* if *id2* is element id, *False* if it is node id
3889 :class:`SMESH.Measure` structure
3895 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3897 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3900 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3902 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3907 aMeasurements = self.smeshpyD.CreateMeasurements()
3908 aMeasure = aMeasurements.MinDistance(id1, id2)
3909 genObjUnRegister([aMeasurements,id1, id2])
3912 def BoundingBox(self, objects=None, isElem=False):
3914 Get bounding box of the specified object(s)
3917 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3918 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3919 *False* specifies that *objects* are nodes
3922 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3925 :meth:`GetBoundingBox()`
3928 result = self.GetBoundingBox(objects, isElem)
3932 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3935 def GetBoundingBox(self, objects=None, isElem=False):
3937 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3940 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3941 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3942 False means that *objects* are nodes
3945 :class:`SMESH.Measure` structure
3948 :meth:`BoundingBox()`
3952 objects = [self.mesh]
3953 elif isinstance(objects, tuple):
3954 objects = list(objects)
3955 if not isinstance(objects, list):
3957 if len(objects) > 0 and isinstance(objects[0], int):
3960 unRegister = genObjUnRegister()
3962 if isinstance(o, Mesh):
3963 srclist.append(o.mesh)
3964 elif hasattr(o, "_narrow"):
3965 src = o._narrow(SMESH.SMESH_IDSource)
3966 if src: srclist.append(src)
3968 elif isinstance(o, list):
3970 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3972 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3973 unRegister.set( srclist[-1] )
3976 aMeasurements = self.smeshpyD.CreateMeasurements()
3977 unRegister.set( aMeasurements )
3978 aMeasure = aMeasurements.BoundingBox(srclist)
3981 # Mesh edition (SMESH_MeshEditor functionality):
3982 # ---------------------------------------------
3984 def RemoveElements(self, IDsOfElements):
3986 Remove the elements from the mesh by ids
3989 IDsOfElements: is a list of ids of elements to remove
3995 This operation can create gaps in numeration of elements.
3996 Call :meth:`RenumberElements` to remove the gaps.
3999 return self.editor.RemoveElements(IDsOfElements)
4001 def RemoveNodes(self, IDsOfNodes):
4003 Remove nodes from mesh by ids
4006 IDsOfNodes: is a list of ids of nodes to remove
4012 This operation can create gaps in numeration of nodes.
4013 Call :meth:`RenumberElements` to remove the gaps.
4016 return self.editor.RemoveNodes(IDsOfNodes)
4018 def RemoveOrphanNodes(self):
4020 Remove all orphan (free) nodes from mesh
4023 number of the removed nodes
4026 This operation can create gaps in numeration of nodes.
4027 Call :meth:`RenumberElements` to remove the gaps.
4030 return self.editor.RemoveOrphanNodes()
4032 def AddNode(self, x, y, z):
4034 Add a node to the mesh by coordinates
4040 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4041 if hasVars: self.mesh.SetParameters(Parameters)
4042 return self.editor.AddNode( x, y, z)
4044 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4046 Create a 0D element on a node with given number.
4049 IDOfNode: the ID of node for creation of the element.
4050 DuplicateElements: to add one more 0D element to a node or not
4053 ID of the new 0D element
4056 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4058 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4060 Create 0D elements on all nodes of the given elements except those
4061 nodes on which a 0D element already exists.
4064 theObject: an object on whose nodes 0D elements will be created.
4065 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4066 theGroupName: optional name of a group to add 0D elements created
4067 and/or found on nodes of *theObject*.
4068 DuplicateElements: to add one more 0D element to a node or not
4071 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4072 IDs of new and/or found 0D elements. IDs of 0D elements
4073 can be retrieved from the returned object by
4074 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4077 unRegister = genObjUnRegister()
4078 if isinstance( theObject, Mesh ):
4079 theObject = theObject.GetMesh()
4080 elif isinstance( theObject, list ):
4081 theObject = self.GetIDSource( theObject, SMESH.ALL )
4082 unRegister.set( theObject )
4083 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4085 def AddBall(self, IDOfNode, diameter):
4087 Create a ball element on a node with given ID.
4090 IDOfNode: the ID of node for creation of the element.
4091 diameter: the bal diameter.
4094 ID of the new ball element
4097 return self.editor.AddBall( IDOfNode, diameter )
4099 def AddEdge(self, IDsOfNodes):
4101 Create a linear or quadratic edge (this is determined
4102 by the number of given nodes).
4105 IDsOfNodes: list of node IDs for creation of the element.
4106 The order of nodes in this list should correspond to
4107 the :ref:`connectivity convention <connectivity_page>`.
4113 return self.editor.AddEdge(IDsOfNodes)
4115 def AddFace(self, IDsOfNodes):
4117 Create a linear or quadratic face (this is determined
4118 by the number of given nodes).
4121 IDsOfNodes: list of node IDs for creation of the element.
4122 The order of nodes in this list should correspond to
4123 the :ref:`connectivity convention <connectivity_page>`.
4129 return self.editor.AddFace(IDsOfNodes)
4131 def AddPolygonalFace(self, IdsOfNodes):
4133 Add a polygonal face defined by a list of node IDs
4136 IdsOfNodes: the list of node IDs for creation of the element.
4142 return self.editor.AddPolygonalFace(IdsOfNodes)
4144 def AddQuadPolygonalFace(self, IdsOfNodes):
4146 Add a quadratic polygonal face defined by a list of node IDs
4149 IdsOfNodes: the list of node IDs for creation of the element;
4150 corner nodes follow first.
4156 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4158 def AddVolume(self, IDsOfNodes):
4160 Create both simple and quadratic volume (this is determined
4161 by the number of given nodes).
4164 IDsOfNodes: list of node IDs for creation of the element.
4165 The order of nodes in this list should correspond to
4166 the :ref:`connectivity convention <connectivity_page>`.
4169 ID of the new volumic element
4172 return self.editor.AddVolume(IDsOfNodes)
4174 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4176 Create a volume of many faces, giving nodes for each face.
4179 IdsOfNodes: list of node IDs for volume creation, face by face.
4180 Quantities: list of integer values, Quantities[i]
4181 gives the quantity of nodes in face number i.
4184 ID of the new volumic element
4187 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4189 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4191 Create a volume of many faces, giving the IDs of the existing faces.
4194 The created volume will refer only to the nodes
4195 of the given faces, not to the faces themselves.
4198 IdsOfFaces: the list of face IDs for volume creation.
4201 ID of the new volumic element
4204 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4207 def SetNodeOnVertex(self, NodeID, Vertex):
4209 Bind a node to a vertex
4213 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4216 True if succeed else raises an exception
4219 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4220 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4224 self.editor.SetNodeOnVertex(NodeID, VertexID)
4225 except SALOME.SALOME_Exception as inst:
4226 raise ValueError(inst.details.text)
4230 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4232 Store the node position on an edge
4236 Edge: an edge (GEOM.GEOM_Object) or edge ID
4237 paramOnEdge: a parameter on the edge where the node is located
4240 True if succeed else raises an exception
4243 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4244 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4248 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4249 except SALOME.SALOME_Exception as inst:
4250 raise ValueError(inst.details.text)
4253 def SetNodeOnFace(self, NodeID, Face, u, v):
4255 Store node position on a face
4259 Face: a face (GEOM.GEOM_Object) or face ID
4260 u: U parameter on the face where the node is located
4261 v: V parameter on the face where the node is located
4264 True if succeed else raises an exception
4267 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4268 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4272 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4273 except SALOME.SALOME_Exception as inst:
4274 raise ValueError(inst.details.text)
4277 def SetNodeInVolume(self, NodeID, Solid):
4279 Bind a node to a solid
4283 Solid: a solid (GEOM.GEOM_Object) or solid ID
4286 True if succeed else raises an exception
4289 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4290 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4294 self.editor.SetNodeInVolume(NodeID, SolidID)
4295 except SALOME.SALOME_Exception as inst:
4296 raise ValueError(inst.details.text)
4299 def SetMeshElementOnShape(self, ElementID, Shape):
4301 Bind an element to a shape
4304 ElementID: an element ID
4305 Shape: a shape (GEOM.GEOM_Object) or shape ID
4308 True if succeed else raises an exception
4311 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4312 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4316 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4317 except SALOME.SALOME_Exception as inst:
4318 raise ValueError(inst.details.text)
4322 def MoveNode(self, NodeID, x, y, z):
4324 Move the node with the given id
4327 NodeID: the id of the node
4328 x: a new X coordinate
4329 y: a new Y coordinate
4330 z: a new Z coordinate
4333 True if succeed else False
4336 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4337 if hasVars: self.mesh.SetParameters(Parameters)
4338 return self.editor.MoveNode(NodeID, x, y, z)
4340 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4342 Find the node closest to a point and moves it to a point location
4345 x: the X coordinate of a point
4346 y: the Y coordinate of a point
4347 z: the Z coordinate of a point
4348 NodeID: if specified (>0), the node with this ID is moved,
4349 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4352 the ID of a moved node
4355 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4356 if hasVars: self.mesh.SetParameters(Parameters)
4357 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4359 def FindNodeClosestTo(self, x, y, z):
4361 Find the node closest to a point
4364 x: the X coordinate of a point
4365 y: the Y coordinate of a point
4366 z: the Z coordinate of a point
4372 return self.editor.FindNodeClosestTo(x, y, z)
4374 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4376 Find the elements where a point lays IN or ON
4379 x,y,z (float): coordinates of the point
4380 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4381 means elements of any type excluding nodes, discrete and 0D elements.
4382 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4385 list of IDs of found elements
4388 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4390 return self.editor.FindElementsByPoint(x, y, z, elementType)
4392 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4394 Project a point to a mesh object.
4395 Return ID of an element of given type where the given point is projected
4396 and coordinates of the projection point.
4397 In the case if nothing found, return -1 and []
4399 if isinstance( meshObject, Mesh ):
4400 meshObject = meshObject.GetMesh()
4402 meshObject = self.GetMesh()
4403 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4405 def GetPointState(self, x, y, z):
4407 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4408 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4409 UNKNOWN state means that either mesh is wrong or the analysis fails.
4412 return self.editor.GetPointState(x, y, z)
4414 def IsManifold(self):
4416 Check if a 2D mesh is manifold
4419 return self.editor.IsManifold()
4421 def IsCoherentOrientation2D(self):
4423 Check if orientation of 2D elements is coherent
4426 return self.editor.IsCoherentOrientation2D()
4428 def Get1DBranches( self, edges, startNode = 0 ):
4430 Partition given 1D elements into groups of contiguous edges.
4431 A node where number of meeting edges != 2 is a group end.
4432 An optional startNode is used to orient groups it belongs to.
4435 A list of edge groups and a list of corresponding node groups,
4436 where the group is a list of IDs of edges or elements, like follows
4437 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4438 If a group is closed, the first and last nodes of the group are same.
4440 if isinstance( edges, Mesh ):
4441 edges = edges.GetMesh()
4442 unRegister = genObjUnRegister()
4443 if isinstance( edges, list ):
4444 edges = self.GetIDSource( edges, SMESH.EDGE )
4445 unRegister.set( edges )
4446 return self.editor.Get1DBranches( edges, startNode )
4448 def FindSharpEdges( self, angle, addExisting=False ):
4450 Return sharp edges of faces and non-manifold ones.
4451 Optionally add existing edges.
4454 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4455 addExisting: to return existing edges (1D elements) as well
4458 list of FaceEdge structures
4460 angle = ParseParameters( angle )[0]
4461 return self.editor.FindSharpEdges( angle, addExisting )
4463 def MeshToPassThroughAPoint(self, x, y, z):
4465 Find the node closest to a point and moves it to a point location
4468 x: the X coordinate of a point
4469 y: the Y coordinate of a point
4470 z: the Z coordinate of a point
4473 the ID of a moved node
4476 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4478 def InverseDiag(self, NodeID1, NodeID2):
4480 Replace two neighbour triangles sharing Node1-Node2 link
4481 with the triangles built on the same 4 nodes but having other common link.
4484 NodeID1: the ID of the first node
4485 NodeID2: the ID of the second node
4488 False if proper faces were not found
4490 return self.editor.InverseDiag(NodeID1, NodeID2)
4492 def DeleteDiag(self, NodeID1, NodeID2):
4494 Replace two neighbour triangles sharing *Node1-Node2* link
4495 with a quadrangle built on the same 4 nodes.
4498 NodeID1: ID of the first node
4499 NodeID2: ID of the second node
4502 False if proper faces were not found
4505 This operation can create gaps in numeration of elements.
4506 Call :meth:`RenumberElements` to remove the gaps.
4509 return self.editor.DeleteDiag(NodeID1, NodeID2)
4511 def Reorient(self, IDsOfElements=None):
4513 Reorient elements by ids
4516 IDsOfElements: if undefined reorients all mesh elements
4519 True if succeed else False
4522 if IDsOfElements == None:
4523 IDsOfElements = self.GetElementsId()
4524 return self.editor.Reorient(IDsOfElements)
4526 def ReorientObject(self, theObject):
4528 Reorient all elements of the object
4531 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4534 True if succeed else False
4537 if ( isinstance( theObject, Mesh )):
4538 theObject = theObject.GetMesh()
4539 return self.editor.ReorientObject(theObject)
4541 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4543 Reorient faces contained in *the2DObject*.
4546 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4547 theDirection: a desired direction of normal of *theFace*.
4548 It can be either a GEOM vector or a list of coordinates [x,y,z].
4549 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4550 compared with theDirection. It can be either ID of face or a point
4551 by which the face will be found. The point can be given as either
4552 a GEOM vertex or a list of point coordinates.
4555 number of reoriented faces
4558 unRegister = genObjUnRegister()
4560 if isinstance( the2DObject, Mesh ):
4561 the2DObject = the2DObject.GetMesh()
4562 if isinstance( the2DObject, list ):
4563 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4564 unRegister.set( the2DObject )
4565 # check theDirection
4566 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4567 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4568 if isinstance( theDirection, list ):
4569 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4570 # prepare theFace and thePoint
4571 theFace = theFaceOrPoint
4572 thePoint = PointStruct(0,0,0)
4573 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4574 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4576 if isinstance( theFaceOrPoint, list ):
4577 thePoint = PointStruct( *theFaceOrPoint )
4579 if isinstance( theFaceOrPoint, PointStruct ):
4580 thePoint = theFaceOrPoint
4582 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4584 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4586 Reorient faces according to adjacent volumes.
4589 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4590 either IDs of faces or face groups.
4591 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4592 theOutsideNormal: to orient faces to have their normals
4593 pointing either *outside* or *inside* the adjacent volumes.
4596 number of reoriented faces.
4599 unRegister = genObjUnRegister()
4601 if not isinstance( the2DObject, list ):
4602 the2DObject = [ the2DObject ]
4603 elif the2DObject and isinstance( the2DObject[0], int ):
4604 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4605 unRegister.set( the2DObject )
4606 the2DObject = [ the2DObject ]
4607 for i,obj2D in enumerate( the2DObject ):
4608 if isinstance( obj2D, Mesh ):
4609 the2DObject[i] = obj2D.GetMesh()
4610 if isinstance( obj2D, list ):
4611 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4612 unRegister.set( the2DObject[i] )
4614 if isinstance( the3DObject, Mesh ):
4615 the3DObject = the3DObject.GetMesh()
4616 if isinstance( the3DObject, list ):
4617 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4618 unRegister.set( the3DObject )
4619 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4621 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4623 Fuse the neighbouring triangles into quadrangles.
4626 IDsOfElements: The triangles to be fused.
4627 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4628 applied to possible quadrangles to choose a neighbour to fuse with.
4629 Note that not all items of :class:`SMESH.FunctorType` corresponds
4630 to numerical functors.
4631 MaxAngle: is the maximum angle between element normals at which the fusion
4632 is still performed; theMaxAngle is measured in radians.
4633 Also it could be a name of variable which defines angle in degrees.
4636 True in case of success, False otherwise.
4639 This operation can create gaps in numeration of elements.
4640 Call :meth:`RenumberElements` to remove the gaps.
4643 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4644 self.mesh.SetParameters(Parameters)
4645 if not IDsOfElements:
4646 IDsOfElements = self.GetElementsId()
4647 Functor = self.smeshpyD.GetFunctor(theCriterion)
4648 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4650 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4652 Fuse the neighbouring triangles of the object into quadrangles
4655 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4656 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4657 applied to possible quadrangles to choose a neighbour to fuse with.
4658 Note that not all items of :class:`SMESH.FunctorType` corresponds
4659 to numerical functors.
4660 MaxAngle: a max angle between element normals at which the fusion
4661 is still performed; theMaxAngle is measured in radians.
4664 True in case of success, False otherwise.
4667 This operation can create gaps in numeration of elements.
4668 Call :meth:`RenumberElements` to remove the gaps.
4671 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4672 self.mesh.SetParameters(Parameters)
4673 if isinstance( theObject, Mesh ):
4674 theObject = theObject.GetMesh()
4675 Functor = self.smeshpyD.GetFunctor(theCriterion)
4676 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4678 def QuadToTri (self, IDsOfElements, theCriterion = None):
4680 Split quadrangles into triangles.
4683 IDsOfElements: the faces to be splitted.
4684 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4685 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4686 value, then quadrangles will be split by the smallest diagonal.
4687 Note that not all items of :class:`SMESH.FunctorType` corresponds
4688 to numerical functors.
4691 True in case of success, False otherwise.
4694 This operation can create gaps in numeration of elements.
4695 Call :meth:`RenumberElements` to remove the gaps.
4697 if IDsOfElements == []:
4698 IDsOfElements = self.GetElementsId()
4699 if theCriterion is None:
4700 theCriterion = FT_MaxElementLength2D
4701 Functor = self.smeshpyD.GetFunctor(theCriterion)
4702 return self.editor.QuadToTri(IDsOfElements, Functor)
4704 def QuadToTriObject (self, theObject, theCriterion = None):
4706 Split quadrangles into triangles.
4709 theObject: the object from which the list of elements is taken,
4710 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4711 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4712 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4713 value, then quadrangles will be split by the smallest diagonal.
4714 Note that not all items of :class:`SMESH.FunctorType` corresponds
4715 to numerical functors.
4718 True in case of success, False otherwise.
4721 This operation can create gaps in numeration of elements.
4722 Call :meth:`RenumberElements` to remove the gaps.
4724 if ( isinstance( theObject, Mesh )):
4725 theObject = theObject.GetMesh()
4726 if theCriterion is None:
4727 theCriterion = FT_MaxElementLength2D
4728 Functor = self.smeshpyD.GetFunctor(theCriterion)
4729 return self.editor.QuadToTriObject(theObject, Functor)
4731 def QuadTo4Tri (self, theElements=[]):
4733 Split each of given quadrangles into 4 triangles. A node is added at the center of
4737 theElements: the faces to be splitted. This can be either
4738 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4739 or a list of face IDs. By default all quadrangles are split
4742 This operation can create gaps in numeration of elements.
4743 Call :meth:`RenumberElements` to remove the gaps.
4745 unRegister = genObjUnRegister()
4746 if isinstance( theElements, Mesh ):
4747 theElements = theElements.mesh
4748 elif not theElements:
4749 theElements = self.mesh
4750 elif isinstance( theElements, list ):
4751 theElements = self.GetIDSource( theElements, SMESH.FACE )
4752 unRegister.set( theElements )
4753 return self.editor.QuadTo4Tri( theElements )
4755 def SplitQuad (self, IDsOfElements, Diag13):
4757 Split quadrangles into triangles.
4760 IDsOfElements: the faces to be splitted
4761 Diag13 (boolean): is used to choose a diagonal for splitting.
4764 True in case of success, False otherwise.
4767 This operation can create gaps in numeration of elements.
4768 Call :meth:`RenumberElements` to remove the gaps.
4770 if IDsOfElements == []:
4771 IDsOfElements = self.GetElementsId()
4772 return self.editor.SplitQuad(IDsOfElements, Diag13)
4774 def SplitQuadObject (self, theObject, Diag13):
4776 Split quadrangles into triangles.
4779 theObject: the object from which the list of elements is taken,
4780 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4781 Diag13 (boolean): is used to choose a diagonal for splitting.
4784 True in case of success, False otherwise.
4787 This operation can create gaps in numeration of elements.
4788 Call :meth:`RenumberElements` to remove the gaps.
4790 if ( isinstance( theObject, Mesh )):
4791 theObject = theObject.GetMesh()
4792 return self.editor.SplitQuadObject(theObject, Diag13)
4794 def BestSplit (self, IDOfQuad, theCriterion):
4796 Find a better splitting of the given quadrangle.
4799 IDOfQuad: the ID of the quadrangle to be splitted.
4800 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4801 choose a diagonal for splitting.
4802 Note that not all items of :class:`SMESH.FunctorType` corresponds
4803 to numerical functors.
4806 * 1 if 1-3 diagonal is better,
4807 * 2 if 2-4 diagonal is better,
4808 * 0 if error occurs.
4811 This operation can create gaps in numeration of elements.
4812 Call :meth:`RenumberElements` to remove the gaps.
4814 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4816 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4818 Split volumic elements into tetrahedrons
4821 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4822 method: flags passing splitting method:
4823 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4824 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4827 This operation can create gaps in numeration of elements.
4828 Call :meth:`RenumberElements` to remove the gaps.
4830 unRegister = genObjUnRegister()
4831 if isinstance( elems, Mesh ):
4832 elems = elems.GetMesh()
4833 if ( isinstance( elems, list )):
4834 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4835 unRegister.set( elems )
4836 self.editor.SplitVolumesIntoTetra(elems, method)
4839 def SplitBiQuadraticIntoLinear(self, elems=None):
4841 Split bi-quadratic elements into linear ones without creation of additional nodes:
4843 - bi-quadratic triangle will be split into 3 linear quadrangles;
4844 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4845 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4847 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4848 will be split in order to keep the mesh conformal.
4851 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4852 if None (default), all bi-quadratic elements will be split
4855 This operation can create gaps in numeration of elements.
4856 Call :meth:`RenumberElements` to remove the gaps.
4858 unRegister = genObjUnRegister()
4859 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4860 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4861 unRegister.set( elems )
4863 elems = [ self.GetMesh() ]
4864 if isinstance( elems, Mesh ):
4865 elems = [ elems.GetMesh() ]
4866 if not isinstance( elems, list ):
4868 self.editor.SplitBiQuadraticIntoLinear( elems )
4870 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4871 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4873 Split hexahedra into prisms
4876 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4877 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4878 gives a normal vector defining facets to split into triangles.
4879 *startHexPoint* can be either a triple of coordinates or a vertex.
4880 facetNormal: a normal to a facet to split into triangles of a
4881 hexahedron found by *startHexPoint*.
4882 *facetNormal* can be either a triple of coordinates or an edge.
4883 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4884 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4885 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4886 to *startHexPoint* are split, else *startHexPoint*
4887 is used to find the facet to split in all domains present in *elems*.
4890 This operation can create gaps in numeration of elements.
4891 Call :meth:`RenumberElements` to remove the gaps.
4894 unRegister = genObjUnRegister()
4895 if isinstance( elems, Mesh ):
4896 elems = elems.GetMesh()
4897 if ( isinstance( elems, list )):
4898 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4899 unRegister.set( elems )
4902 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4903 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4904 elif isinstance( startHexPoint, list ):
4905 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4908 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4909 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4910 elif isinstance( facetNormal, list ):
4911 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4914 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4916 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4918 def SplitQuadsNearTriangularFacets(self):
4920 Split quadrangle faces near triangular facets of volumes
4923 This operation can create gaps in numeration of elements.
4924 Call :meth:`RenumberElements` to remove the gaps.
4926 faces_array = self.GetElementsByType(SMESH.FACE)
4927 for face_id in faces_array:
4928 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4929 quad_nodes = self.mesh.GetElemNodes(face_id)
4930 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4931 isVolumeFound = False
4932 for node1_elem in node1_elems:
4933 if not isVolumeFound:
4934 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4935 nb_nodes = self.GetElemNbNodes(node1_elem)
4936 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4937 volume_elem = node1_elem
4938 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4939 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4940 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4941 isVolumeFound = True
4942 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4943 self.SplitQuad([face_id], False) # diagonal 2-4
4944 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4945 isVolumeFound = True
4946 self.SplitQuad([face_id], True) # diagonal 1-3
4947 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4948 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4949 isVolumeFound = True
4950 self.SplitQuad([face_id], True) # diagonal 1-3
4952 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4954 Split hexahedrons into tetrahedrons.
4956 This operation uses :doc:`pattern_mapping` functionality for splitting.
4959 theObject: the object from which the list of hexahedrons is taken;
4960 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4961 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4962 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4963 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4964 key-point will be mapped into *theNode001*-th node of each volume.
4965 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4968 True in case of success, False otherwise.
4971 This operation can create gaps in numeration of elements.
4972 Call :meth:`RenumberElements` to remove the gaps.
4980 # (0,0,1) 4.---------.7 * |
4987 # (0,0,0) 0.---------.3
4988 pattern_tetra = "!!! Nb of points: \n 8 \n\
4998 !!! Indices of points of 6 tetras: \n\
5006 pattern = self.smeshpyD.GetPattern()
5007 isDone = pattern.LoadFromFile(pattern_tetra)
5009 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5012 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5013 isDone = pattern.MakeMesh(self.mesh, False, False)
5014 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5016 # split quafrangle faces near triangular facets of volumes
5017 self.SplitQuadsNearTriangularFacets()
5021 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5023 Split hexahedrons into prisms.
5025 Uses the :doc:`pattern_mapping` functionality for splitting.
5028 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5029 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5030 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5031 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5032 will be mapped into the *theNode001* -th node of each volume.
5033 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5036 True in case of success, False otherwise.
5039 This operation can create gaps in numeration of elements.
5040 Call :meth:`RenumberElements` to remove the gaps.
5042 # Pattern: 5.---------.6
5047 # (0,0,1) 4.---------.7 |
5054 # (0,0,0) 0.---------.3
5055 pattern_prism = "!!! Nb of points: \n 8 \n\
5065 !!! Indices of points of 2 prisms: \n\
5069 pattern = self.smeshpyD.GetPattern()
5070 isDone = pattern.LoadFromFile(pattern_prism)
5072 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5075 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5076 isDone = pattern.MakeMesh(self.mesh, False, False)
5077 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5079 # Split quafrangle faces near triangular facets of volumes
5080 self.SplitQuadsNearTriangularFacets()
5084 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5085 MaxNbOfIterations, MaxAspectRatio, Method):
5090 IDsOfElements: the list if ids of elements to smooth
5091 IDsOfFixedNodes: the list of ids of fixed nodes.
5092 Note that nodes built on edges and boundary nodes are always fixed.
5093 MaxNbOfIterations: the maximum number of iterations
5094 MaxAspectRatio: varies in range [1.0, inf]
5095 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5096 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5099 True in case of success, False otherwise.
5102 if IDsOfElements == []:
5103 IDsOfElements = self.GetElementsId()
5104 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5105 self.mesh.SetParameters(Parameters)
5106 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5107 MaxNbOfIterations, MaxAspectRatio, Method)
5109 def SmoothObject(self, theObject, IDsOfFixedNodes,
5110 MaxNbOfIterations, MaxAspectRatio, Method):
5112 Smooth elements which belong to the given object
5115 theObject: the object to smooth
5116 IDsOfFixedNodes: the list of ids of fixed nodes.
5117 Note that nodes built on edges and boundary nodes are always fixed.
5118 MaxNbOfIterations: the maximum number of iterations
5119 MaxAspectRatio: varies in range [1.0, inf]
5120 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5121 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5124 True in case of success, False otherwise.
5127 if ( isinstance( theObject, Mesh )):
5128 theObject = theObject.GetMesh()
5129 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5130 MaxNbOfIterations, MaxAspectRatio, Method)
5132 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5133 MaxNbOfIterations, MaxAspectRatio, Method):
5135 Parametrically smooth the given elements
5138 IDsOfElements: the list if ids of elements to smooth
5139 IDsOfFixedNodes: the list of ids of fixed nodes.
5140 Note that nodes built on edges and boundary nodes are always fixed.
5141 MaxNbOfIterations: the maximum number of iterations
5142 MaxAspectRatio: varies in range [1.0, inf]
5143 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5144 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5147 True in case of success, False otherwise.
5150 if IDsOfElements == []:
5151 IDsOfElements = self.GetElementsId()
5152 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5153 self.mesh.SetParameters(Parameters)
5154 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5155 MaxNbOfIterations, MaxAspectRatio, Method)
5157 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5158 MaxNbOfIterations, MaxAspectRatio, Method):
5160 Parametrically smooth the elements which belong to the given object
5163 theObject: the object to smooth
5164 IDsOfFixedNodes: the list of ids of fixed nodes.
5165 Note that nodes built on edges and boundary nodes are always fixed.
5166 MaxNbOfIterations: the maximum number of iterations
5167 MaxAspectRatio: varies in range [1.0, inf]
5168 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5169 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5172 True in case of success, False otherwise.
5175 if ( isinstance( theObject, Mesh )):
5176 theObject = theObject.GetMesh()
5177 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5178 MaxNbOfIterations, MaxAspectRatio, Method)
5180 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5182 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5183 them with quadratic with the same id.
5186 theForce3d: method of new node creation:
5188 * False - the medium node lies at the geometrical entity from which the mesh element is built
5189 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5190 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5191 theToBiQuad: If True, converts the mesh to bi-quadratic
5194 :class:`SMESH.ComputeError` which can hold a warning
5197 If *theSubMesh* is provided, the mesh can become non-conformal
5200 This operation can create gaps in numeration of nodes or elements.
5201 Call :meth:`RenumberElements` to remove the gaps.
5204 if isinstance( theSubMesh, Mesh ):
5205 theSubMesh = theSubMesh.mesh
5207 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5210 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5212 self.editor.ConvertToQuadratic(theForce3d)
5213 error = self.editor.GetLastError()
5214 if error and error.comment:
5215 print(error.comment)
5218 def ConvertFromQuadratic(self, theSubMesh=None):
5220 Convert the mesh from quadratic to ordinary,
5221 deletes old quadratic elements,
5222 replacing them with ordinary mesh elements with the same id.
5225 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5228 If *theSubMesh* is provided, the mesh can become non-conformal
5231 This operation can create gaps in numeration of nodes or elements.
5232 Call :meth:`RenumberElements` to remove the gaps.
5236 self.editor.ConvertFromQuadraticObject(theSubMesh)
5238 return self.editor.ConvertFromQuadratic()
5240 def Make2DMeshFrom3D(self):
5242 Create 2D mesh as skin on boundary faces of a 3D mesh
5245 True if operation has been completed successfully, False otherwise
5248 return self.editor.Make2DMeshFrom3D()
5250 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5251 toCopyElements=False, toCopyExistingBondary=False):
5253 Create missing boundary elements
5256 elements: elements whose boundary is to be checked:
5257 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5258 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5259 dimension: defines type of boundary elements to create, either of
5260 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5261 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5262 groupName: a name of group to store created boundary elements in,
5263 "" means not to create the group
5264 meshName: a name of new mesh to store created boundary elements in,
5265 "" means not to create the new mesh
5266 toCopyElements: if True, the checked elements will be copied into
5267 the new mesh else only boundary elements will be copied into the new mesh
5268 toCopyExistingBondary: if True, not only new but also pre-existing
5269 boundary elements will be copied into the new mesh
5272 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5275 unRegister = genObjUnRegister()
5276 if isinstance( elements, Mesh ):
5277 elements = elements.GetMesh()
5278 if ( isinstance( elements, list )):
5279 elemType = SMESH.ALL
5280 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5281 elements = self.editor.MakeIDSource(elements, elemType)
5282 unRegister.set( elements )
5283 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5284 toCopyElements,toCopyExistingBondary)
5285 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5288 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5289 toCopyAll=False, groups=[]):
5291 Create missing boundary elements around either the whole mesh or
5295 dimension: defines type of boundary elements to create, either of
5296 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5297 groupName: a name of group to store all boundary elements in,
5298 "" means not to create the group
5299 meshName: a name of a new mesh, which is a copy of the initial
5300 mesh + created boundary elements; "" means not to create the new mesh
5301 toCopyAll: if True, the whole initial mesh will be copied into
5302 the new mesh else only boundary elements will be copied into the new mesh
5303 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5306 tuple( long, mesh, group )
5307 - long - number of added boundary elements
5308 - mesh - the :class:`Mesh` where elements were added to
5309 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5312 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5314 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5315 return nb, mesh, group
5317 def RenumberNodes(self):
5319 Renumber mesh nodes to remove unused node IDs
5321 self.editor.RenumberNodes()
5323 def RenumberElements(self):
5325 Renumber mesh elements to remove unused element IDs
5327 self.editor.RenumberElements()
5329 def _getIdSourceList(self, arg, idType, unRegister):
5331 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5333 if arg and isinstance( arg, list ):
5334 if isinstance( arg[0], int ):
5335 arg = self.GetIDSource( arg, idType )
5336 unRegister.set( arg )
5337 elif isinstance( arg[0], Mesh ):
5338 arg[0] = arg[0].GetMesh()
5339 elif isinstance( arg, Mesh ):
5341 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5345 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5346 MakeGroups=False, TotalAngle=False):
5348 Generate new elements by rotation of the given elements and nodes around the axis
5351 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5352 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5353 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5354 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5355 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5356 which defines angle in degrees
5357 NbOfSteps: the number of steps
5358 Tolerance: tolerance
5359 MakeGroups: forces the generation of new groups from existing ones
5360 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5361 of all steps, else - size of each step
5364 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5367 unRegister = genObjUnRegister()
5368 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5369 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5370 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5372 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5373 Axis = self.smeshpyD.GetAxisStruct( Axis )
5374 if isinstance( Axis, list ):
5375 Axis = SMESH.AxisStruct( *Axis )
5377 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5378 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5379 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5380 self.mesh.SetParameters(Parameters)
5381 if TotalAngle and NbOfSteps:
5382 AngleInRadians /= NbOfSteps
5383 return self.editor.RotationSweepObjects( nodes, edges, faces,
5384 Axis, AngleInRadians,
5385 NbOfSteps, Tolerance, MakeGroups)
5387 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5388 MakeGroups=False, TotalAngle=False):
5390 Generate new elements by rotation of the elements around the axis
5393 IDsOfElements: the list of ids of elements to sweep
5394 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5395 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5396 NbOfSteps: the number of steps
5397 Tolerance: tolerance
5398 MakeGroups: forces the generation of new groups from existing ones
5399 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5400 of all steps, else - size of each step
5403 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5406 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5407 AngleInRadians, NbOfSteps, Tolerance,
5408 MakeGroups, TotalAngle)
5410 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5411 MakeGroups=False, TotalAngle=False):
5413 Generate new elements by rotation of the elements of object around the axis
5414 theObject object which elements should be sweeped.
5415 It can be a mesh, a sub mesh or a group.
5418 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5419 AngleInRadians: the angle of Rotation
5420 NbOfSteps: number of steps
5421 Tolerance: tolerance
5422 MakeGroups: forces the generation of new groups from existing ones
5423 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5424 of all steps, else - size of each step
5427 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5430 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5431 AngleInRadians, NbOfSteps, Tolerance,
5432 MakeGroups, TotalAngle )
5434 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5435 MakeGroups=False, TotalAngle=False):
5437 Generate new elements by rotation of the elements of object around the axis
5438 theObject object which elements should be sweeped.
5439 It can be a mesh, a sub mesh or a group.
5442 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5443 AngleInRadians: the angle of Rotation
5444 NbOfSteps: number of steps
5445 Tolerance: tolerance
5446 MakeGroups: forces the generation of new groups from existing ones
5447 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5448 of all steps, else - size of each step
5451 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5452 empty list otherwise
5455 return self.RotationSweepObjects([],theObject,[], Axis,
5456 AngleInRadians, NbOfSteps, Tolerance,
5457 MakeGroups, TotalAngle)
5459 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5460 MakeGroups=False, TotalAngle=False):
5462 Generate new elements by rotation of the elements of object around the axis
5463 theObject object which elements should be sweeped.
5464 It can be a mesh, a sub mesh or a group.
5467 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5468 AngleInRadians: the angle of Rotation
5469 NbOfSteps: number of steps
5470 Tolerance: tolerance
5471 MakeGroups: forces the generation of new groups from existing ones
5472 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5473 of all steps, else - size of each step
5476 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5479 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5480 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5482 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5483 scaleFactors=[], linearVariation=False, basePoint=[],
5484 angles=[], anglesVariation=False):
5486 Generate new elements by extrusion of the given elements and nodes
5489 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5490 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5491 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5492 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5493 the direction and value of extrusion for one step (the total extrusion
5494 length will be NbOfSteps * ||StepVector||)
5495 NbOfSteps: the number of steps
5496 MakeGroups: forces the generation of new groups from existing ones
5497 scaleFactors: optional scale factors to apply during extrusion
5498 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5499 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5500 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5501 nodes and elements being extruded is used as the scaling center.
5504 - a list of tree components of the point or
5507 angles: list of angles in radians. Nodes at each extrusion step are rotated
5508 around *basePoint*, additionally to previous steps.
5509 anglesVariation: forces the computation of rotation angles as linear
5510 variation of the given *angles* along path steps
5512 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5514 Example: :ref:`tui_extrusion`
5516 unRegister = genObjUnRegister()
5517 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5518 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5519 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5521 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5522 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5523 if isinstance( StepVector, list ):
5524 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5526 if isinstance( basePoint, int):
5527 xyz = self.GetNodeXYZ( basePoint )
5529 raise RuntimeError("Invalid node ID: %s" % basePoint)
5531 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5532 basePoint = self.geompyD.PointCoordinates( basePoint )
5534 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5535 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5536 angles,angleParameters,hasVars = ParseAngles(angles)
5537 Parameters = StepVector.PS.parameters + var_separator + \
5538 Parameters + var_separator + \
5539 scaleParameters + var_separator + angleParameters
5540 self.mesh.SetParameters(Parameters)
5542 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5543 StepVector, NbOfSteps, MakeGroups,
5544 scaleFactors, linearVariation, basePoint,
5545 angles, anglesVariation )
5548 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5550 Generate new elements by extrusion of the elements with given ids
5553 IDsOfElements: the list of ids of elements or nodes for extrusion
5554 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5555 the direction and value of extrusion for one step (the total extrusion
5556 length will be NbOfSteps * ||StepVector||)
5557 NbOfSteps: the number of steps
5558 MakeGroups: forces the generation of new groups from existing ones
5559 IsNodes: is True if elements with given ids are nodes
5562 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5564 Example: :ref:`tui_extrusion`
5567 if IsNodes: n = IDsOfElements
5568 else : e,f, = IDsOfElements,IDsOfElements
5569 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5571 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5572 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5574 Generate new elements by extrusion along the normal to a discretized surface or wire
5577 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5578 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5579 StepSize: length of one extrusion step (the total extrusion
5580 length will be *NbOfSteps* *StepSize*).
5581 NbOfSteps: number of extrusion steps.
5582 ByAverageNormal: if True each node is translated by *StepSize*
5583 along the average of the normal vectors to the faces sharing the node;
5584 else each node is translated along the same average normal till
5585 intersection with the plane got by translation of the face sharing
5586 the node along its own normal by *StepSize*.
5587 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5588 for every node of *Elements*.
5589 MakeGroups: forces generation of new groups from existing ones.
5590 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5591 is not yet implemented. This parameter is used if *Elements* contains
5592 both faces and edges, i.e. *Elements* is a Mesh.
5595 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5596 empty list otherwise.
5597 Example: :ref:`tui_extrusion`
5600 unRegister = genObjUnRegister()
5601 if isinstance( Elements, Mesh ):
5602 Elements = [ Elements.GetMesh() ]
5603 if isinstance( Elements, list ):
5605 raise RuntimeError("Elements empty!")
5606 if isinstance( Elements[0], Mesh ):
5607 Elements = [ Elements[0].GetMesh() ]
5608 if isinstance( Elements[0], int ):
5609 Elements = self.GetIDSource( Elements, SMESH.ALL )
5610 unRegister.set( Elements )
5611 if not isinstance( Elements, list ):
5612 Elements = [ Elements ]
5613 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5614 self.mesh.SetParameters(Parameters)
5615 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5616 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5618 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5620 Generate new elements by extrusion of the elements or nodes which belong to the object
5623 theObject: the object whose elements or nodes should be processed.
5624 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5625 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5626 the direction and value of extrusion for one step (the total extrusion
5627 length will be NbOfSteps * ||StepVector||)
5628 NbOfSteps: the number of steps
5629 MakeGroups: forces the generation of new groups from existing ones
5630 IsNodes: is True if elements to extrude are nodes
5633 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5634 Example: :ref:`tui_extrusion`
5638 if IsNodes: n = theObject
5639 else : e,f, = theObject,theObject
5640 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5642 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5644 Generate new elements by extrusion of edges which belong to the object
5647 theObject: object whose 1D elements should be processed.
5648 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5649 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5650 the direction and value of extrusion for one step (the total extrusion
5651 length will be NbOfSteps * ||StepVector||)
5652 NbOfSteps: the number of steps
5653 MakeGroups: to generate new groups from existing ones
5656 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5657 Example: :ref:`tui_extrusion`
5660 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5662 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5664 Generate new elements by extrusion of faces which belong to the object
5667 theObject: object whose 2D elements should be processed.
5668 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5669 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5670 the direction and value of extrusion for one step (the total extrusion
5671 length will be NbOfSteps * ||StepVector||)
5672 NbOfSteps: the number of steps
5673 MakeGroups: forces the generation of new groups from existing ones
5676 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5677 Example: :ref:`tui_extrusion`
5680 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5682 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5683 ExtrFlags, SewTolerance, MakeGroups=False):
5685 Generate new elements by extrusion of the elements with given ids
5688 IDsOfElements: is ids of elements
5689 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5690 the direction and value of extrusion for one step (the total extrusion
5691 length will be NbOfSteps * ||StepVector||)
5692 NbOfSteps: the number of steps
5693 ExtrFlags: sets flags for extrusion
5694 SewTolerance: uses for comparing locations of nodes if flag
5695 EXTRUSION_FLAG_SEW is set
5696 MakeGroups: forces the generation of new groups from existing ones
5699 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5702 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5703 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5704 if isinstance( StepVector, list ):
5705 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5706 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5707 ExtrFlags, SewTolerance, MakeGroups)
5709 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5710 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5711 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5712 ScaleFactors=[], ScalesVariation=False):
5714 Generate new elements by extrusion of the given elements and nodes along the path.
5715 The path of extrusion must be a meshed edge.
5718 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5719 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5720 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5721 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5722 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
5723 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5724 HasAngles: not used obsolete
5725 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5726 around *basePoint*, additionally to previous steps.
5727 LinearVariation: forces the computation of rotation angles as linear
5728 variation of the given Angles along path steps
5729 HasRefPoint: allows using the reference point
5730 RefPoint: optional scaling and rotation center (mass center of the extruded
5731 elements by default). The User can specify any point as the Reference Point.
5732 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5733 MakeGroups: forces the generation of new groups from existing ones
5734 ScaleFactors: optional scale factors to apply during extrusion
5735 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5736 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5739 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5740 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5741 Example: :ref:`tui_extrusion_along_path`
5744 unRegister = genObjUnRegister()
5745 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5746 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5747 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5749 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5750 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5751 if isinstance( RefPoint, list ):
5752 if not RefPoint: RefPoint = [0,0,0]
5753 RefPoint = SMESH.PointStruct( *RefPoint )
5754 if isinstance( PathObject, Mesh ):
5755 PathObject = PathObject.GetMesh()
5756 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5757 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5758 Parameters = AnglesParameters + var_separator + \
5759 RefPoint.parameters + var_separator + ScalesParameters
5760 self.mesh.SetParameters(Parameters)
5761 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5762 PathObject, PathShape, NodeStart,
5763 HasAngles, Angles, LinearVariation,
5764 HasRefPoint, RefPoint, MakeGroups,
5765 ScaleFactors, ScalesVariation)
5767 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5768 HasAngles=False, Angles=[], LinearVariation=False,
5769 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5770 ElemType=SMESH.FACE):
5772 Generate new elements by extrusion of the given elements.
5773 The path of extrusion must be a meshed edge.
5776 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5777 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5778 NodeStart: the start node from Path. Defines the direction of extrusion
5779 HasAngles: not used obsolete
5780 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5781 around *basePoint*, additionally to previous steps.
5782 LinearVariation: forces the computation of rotation angles as linear
5783 variation of the given Angles along path steps
5784 HasRefPoint: allows using the reference point
5785 RefPoint: the reference point around which the elements are rotated (the mass
5786 center of the elements by default).
5787 The User can specify any point as the Reference Point.
5788 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5789 MakeGroups: forces the generation of new groups from existing ones
5790 ElemType: type of elements for extrusion (if param Base is a mesh)
5793 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5794 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5795 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5797 Example: :ref:`tui_extrusion_along_path`
5801 if ElemType == SMESH.NODE: n = Base
5802 if ElemType == SMESH.EDGE: e = Base
5803 if ElemType == SMESH.FACE: f = Base
5804 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5805 HasAngles, Angles, LinearVariation,
5806 HasRefPoint, RefPoint, MakeGroups)
5807 if MakeGroups: return gr,er
5810 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5811 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5812 MakeGroups=False, LinearVariation=False):
5814 Generate new elements by extrusion of the given elements.
5815 The path of extrusion must be a meshed edge.
5818 IDsOfElements: ids of elements
5819 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5820 PathShape: shape (edge) defines the sub-mesh for the path
5821 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5822 HasAngles: not used obsolete
5823 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5824 around *basePoint*, additionally to previous steps.
5825 HasRefPoint: allows using the reference point
5826 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5827 The User can specify any point as the Reference Point.
5828 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5829 MakeGroups: forces the generation of new groups from existing ones
5830 LinearVariation: forces the computation of rotation angles as linear
5831 variation of the given Angles along path steps
5834 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5835 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5836 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5837 Example: :ref:`tui_extrusion_along_path`
5840 if not IDsOfElements:
5841 IDsOfElements = [ self.GetMesh() ]
5842 n,e,f = [],IDsOfElements,IDsOfElements
5843 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5844 NodeStart, HasAngles, Angles,
5846 HasRefPoint, RefPoint, MakeGroups)
5847 if MakeGroups: return gr,er
5850 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5851 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5852 MakeGroups=False, LinearVariation=False):
5854 Generate new elements by extrusion of the elements which belong to the object.
5855 The path of extrusion must be a meshed edge.
5858 theObject: the object whose elements should be processed.
5859 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5860 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5861 PathShape: shape (edge) defines the sub-mesh for the path
5862 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5863 HasAngles: not used obsolete
5864 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5865 around *basePoint*, additionally to previous steps.
5866 HasRefPoint: allows using the reference point
5867 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5868 The User can specify any point as the Reference Point.
5869 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5870 MakeGroups: forces the generation of new groups from existing ones
5871 LinearVariation: forces the computation of rotation angles as linear
5872 variation of the given Angles along path steps
5875 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5876 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5877 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5878 Example: :ref:`tui_extrusion_along_path`
5881 n,e,f = [],theObject,theObject
5882 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5883 HasAngles, Angles, LinearVariation,
5884 HasRefPoint, RefPoint, MakeGroups)
5885 if MakeGroups: return gr,er
5888 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5889 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5890 MakeGroups=False, LinearVariation=False):
5892 Generate new elements by extrusion of mesh segments which belong to the object.
5893 The path of extrusion must be a meshed edge.
5896 theObject: the object whose 1D elements should be processed.
5897 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5898 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5899 PathShape: shape (edge) defines the sub-mesh for the path
5900 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5901 HasAngles: not used obsolete
5902 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5903 around *basePoint*, additionally to previous steps.
5904 HasRefPoint: allows using the reference point
5905 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5906 The User can specify any point as the Reference Point.
5907 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5908 MakeGroups: forces the generation of new groups from existing ones
5909 LinearVariation: forces the computation of rotation angles as linear
5910 variation of the given Angles along path steps
5913 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5914 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5915 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5916 Example: :ref:`tui_extrusion_along_path`
5919 n,e,f = [],theObject,[]
5920 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5921 HasAngles, Angles, LinearVariation,
5922 HasRefPoint, RefPoint, MakeGroups)
5923 if MakeGroups: return gr,er
5926 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5927 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5928 MakeGroups=False, LinearVariation=False):
5930 Generate new elements by extrusion of faces which belong to the object.
5931 The path of extrusion must be a meshed edge.
5934 theObject: the object whose 2D elements should be processed.
5935 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5936 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5937 PathShape: shape (edge) defines the sub-mesh for the path
5938 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5939 HasAngles: not used obsolete
5940 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5941 around *basePoint*, additionally to previous steps.
5942 HasRefPoint: allows using the reference point
5943 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5944 The User can specify any point as the Reference Point.
5945 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5946 MakeGroups: forces the generation of new groups from existing ones
5947 LinearVariation: forces the computation of rotation angles as linear
5948 variation of the given Angles along path steps
5951 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5952 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5953 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5954 Example: :ref:`tui_extrusion_along_path`
5957 n,e,f = [],[],theObject
5958 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5959 HasAngles, Angles, LinearVariation,
5960 HasRefPoint, RefPoint, MakeGroups)
5961 if MakeGroups: return gr,er
5964 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5966 Create a symmetrical copy of mesh elements
5969 IDsOfElements: list of elements ids
5970 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5971 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5972 If the *Mirror* is a geom object this parameter is unnecessary
5973 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5974 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5977 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5980 if IDsOfElements == []:
5981 IDsOfElements = self.GetElementsId()
5982 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5983 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5984 theMirrorType = Mirror._mirrorType
5986 self.mesh.SetParameters(Mirror.parameters)
5987 if Copy and MakeGroups:
5988 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5989 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5992 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5994 Create a new mesh by a symmetrical copy of mesh elements
5997 IDsOfElements: the list of elements ids
5998 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5999 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6000 If the *Mirror* is a geom object this parameter is unnecessary
6001 MakeGroups: to generate new groups from existing ones
6002 NewMeshName: a name of the new mesh to create
6005 instance of class :class:`Mesh`
6008 if IDsOfElements == []:
6009 IDsOfElements = self.GetElementsId()
6010 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6011 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6012 theMirrorType = Mirror._mirrorType
6014 self.mesh.SetParameters(Mirror.parameters)
6015 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6016 MakeGroups, NewMeshName)
6017 return Mesh(self.smeshpyD,self.geompyD,mesh)
6019 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6021 Create a symmetrical copy of the object
6024 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6025 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6026 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6027 If the *Mirror* is a geom object this parameter is unnecessary
6028 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6029 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6032 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6035 if ( isinstance( theObject, Mesh )):
6036 theObject = theObject.GetMesh()
6037 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6038 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6039 theMirrorType = Mirror._mirrorType
6041 self.mesh.SetParameters(Mirror.parameters)
6042 if Copy and MakeGroups:
6043 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6044 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6047 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6049 Create a new mesh by a symmetrical copy of the object
6052 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6053 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6054 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6055 If the *Mirror* is a geom object this parameter is unnecessary
6056 MakeGroups: forces the generation of new groups from existing ones
6057 NewMeshName: the name of the new mesh to create
6060 instance of class :class:`Mesh`
6063 if ( isinstance( theObject, Mesh )):
6064 theObject = theObject.GetMesh()
6065 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6066 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6067 theMirrorType = Mirror._mirrorType
6069 self.mesh.SetParameters(Mirror.parameters)
6070 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6071 MakeGroups, NewMeshName)
6072 return Mesh( self.smeshpyD,self.geompyD,mesh )
6074 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6076 Translate the elements
6079 IDsOfElements: list of elements ids
6080 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6081 Copy: allows copying the translated elements
6082 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6085 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6088 if IDsOfElements == []:
6089 IDsOfElements = self.GetElementsId()
6090 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6091 Vector = self.smeshpyD.GetDirStruct(Vector)
6092 if isinstance( Vector, list ):
6093 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6094 self.mesh.SetParameters(Vector.PS.parameters)
6095 if Copy and MakeGroups:
6096 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6097 self.editor.Translate(IDsOfElements, Vector, Copy)
6100 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6102 Create a new mesh of translated elements
6105 IDsOfElements: list of elements ids
6106 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6107 MakeGroups: forces the generation of new groups from existing ones
6108 NewMeshName: the name of the newly created mesh
6111 instance of class :class:`Mesh`
6114 if IDsOfElements == []:
6115 IDsOfElements = self.GetElementsId()
6116 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6117 Vector = self.smeshpyD.GetDirStruct(Vector)
6118 if isinstance( Vector, list ):
6119 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6120 self.mesh.SetParameters(Vector.PS.parameters)
6121 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6122 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6124 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6126 Translate the object
6129 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6130 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6131 Copy: allows copying the translated elements
6132 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6135 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6138 if ( isinstance( theObject, Mesh )):
6139 theObject = theObject.GetMesh()
6140 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6141 Vector = self.smeshpyD.GetDirStruct(Vector)
6142 if isinstance( Vector, list ):
6143 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6144 self.mesh.SetParameters(Vector.PS.parameters)
6145 if Copy and MakeGroups:
6146 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6147 self.editor.TranslateObject(theObject, Vector, Copy)
6150 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6152 Create a new mesh from the translated object
6155 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6156 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6157 MakeGroups: forces the generation of new groups from existing ones
6158 NewMeshName: the name of the newly created mesh
6161 instance of class :class:`Mesh`
6164 if isinstance( theObject, Mesh ):
6165 theObject = theObject.GetMesh()
6166 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6167 Vector = self.smeshpyD.GetDirStruct(Vector)
6168 if isinstance( Vector, list ):
6169 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6170 self.mesh.SetParameters(Vector.PS.parameters)
6171 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6172 return Mesh( self.smeshpyD, self.geompyD, mesh )
6176 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6181 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6182 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6183 theScaleFact: list of 1-3 scale factors for axises
6184 Copy: allows copying the translated elements
6185 MakeGroups: forces the generation of new groups from existing
6189 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6190 empty list otherwise
6192 unRegister = genObjUnRegister()
6193 if ( isinstance( theObject, Mesh )):
6194 theObject = theObject.GetMesh()
6195 if ( isinstance( theObject, list )):
6196 theObject = self.GetIDSource(theObject, SMESH.ALL)
6197 unRegister.set( theObject )
6198 if ( isinstance( thePoint, list )):
6199 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6200 if ( isinstance( theScaleFact, float )):
6201 theScaleFact = [theScaleFact]
6202 if ( isinstance( theScaleFact, int )):
6203 theScaleFact = [ float(theScaleFact)]
6205 self.mesh.SetParameters(thePoint.parameters)
6207 if Copy and MakeGroups:
6208 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6209 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6212 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6214 Create a new mesh from the translated object
6217 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6218 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6219 theScaleFact: list of 1-3 scale factors for axises
6220 MakeGroups: forces the generation of new groups from existing ones
6221 NewMeshName: the name of the newly created mesh
6224 instance of class :class:`Mesh`
6226 unRegister = genObjUnRegister()
6227 if (isinstance(theObject, Mesh)):
6228 theObject = theObject.GetMesh()
6229 if ( isinstance( theObject, list )):
6230 theObject = self.GetIDSource(theObject,SMESH.ALL)
6231 unRegister.set( theObject )
6232 if ( isinstance( thePoint, list )):
6233 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6234 if ( isinstance( theScaleFact, float )):
6235 theScaleFact = [theScaleFact]
6236 if ( isinstance( theScaleFact, int )):
6237 theScaleFact = [ float(theScaleFact)]
6239 self.mesh.SetParameters(thePoint.parameters)
6240 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6241 MakeGroups, NewMeshName)
6242 return Mesh( self.smeshpyD, self.geompyD, mesh )
6246 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6251 IDsOfElements: list of elements ids
6252 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6253 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6254 Copy: allows copying the rotated elements
6255 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6258 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6262 if IDsOfElements == []:
6263 IDsOfElements = self.GetElementsId()
6264 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6265 Axis = self.smeshpyD.GetAxisStruct(Axis)
6266 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6267 Parameters = Axis.parameters + var_separator + Parameters
6268 self.mesh.SetParameters(Parameters)
6269 if Copy and MakeGroups:
6270 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6271 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6274 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6276 Create a new mesh of rotated elements
6279 IDsOfElements: list of element ids
6280 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6281 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6282 MakeGroups: forces the generation of new groups from existing ones
6283 NewMeshName: the name of the newly created mesh
6286 instance of class :class:`Mesh`
6289 if IDsOfElements == []:
6290 IDsOfElements = self.GetElementsId()
6291 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6292 Axis = self.smeshpyD.GetAxisStruct(Axis)
6293 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6294 Parameters = Axis.parameters + var_separator + Parameters
6295 self.mesh.SetParameters(Parameters)
6296 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6297 MakeGroups, NewMeshName)
6298 return Mesh( self.smeshpyD, self.geompyD, mesh )
6300 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6305 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6306 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6307 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6308 Copy: allows copying the rotated elements
6309 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6312 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6315 if (isinstance(theObject, Mesh)):
6316 theObject = theObject.GetMesh()
6317 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6318 Axis = self.smeshpyD.GetAxisStruct(Axis)
6319 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6320 Parameters = Axis.parameters + ":" + Parameters
6321 self.mesh.SetParameters(Parameters)
6322 if Copy and MakeGroups:
6323 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6324 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6327 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6329 Create a new mesh from the rotated object
6332 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6333 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6334 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6335 MakeGroups: forces the generation of new groups from existing ones
6336 NewMeshName: the name of the newly created mesh
6339 instance of class :class:`Mesh`
6342 if (isinstance( theObject, Mesh )):
6343 theObject = theObject.GetMesh()
6344 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6345 Axis = self.smeshpyD.GetAxisStruct(Axis)
6346 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6347 Parameters = Axis.parameters + ":" + Parameters
6348 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6349 MakeGroups, NewMeshName)
6350 self.mesh.SetParameters(Parameters)
6351 return Mesh( self.smeshpyD, self.geompyD, mesh )
6353 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6355 Create an offset mesh from the given 2D object
6358 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6359 theValue (float): signed offset size
6360 MakeGroups (boolean): forces the generation of new groups from existing ones
6361 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6362 False means to remove original elements.
6363 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6366 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6369 if isinstance( theObject, Mesh ):
6370 theObject = theObject.GetMesh()
6371 theValue,Parameters,hasVars = ParseParameters(Value)
6372 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6373 self.mesh.SetParameters(Parameters)
6375 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6378 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6380 Find groups of adjacent nodes within Tolerance.
6383 Tolerance (float): the value of tolerance
6384 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6385 corner and medium nodes in separate groups thus preventing
6386 their further merge.
6389 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6392 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6394 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6395 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6397 Find groups of adjacent nodes within Tolerance.
6400 Tolerance: the value of tolerance
6401 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6402 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6403 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6404 corner and medium nodes in separate groups thus preventing
6405 their further merge.
6408 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6411 unRegister = genObjUnRegister()
6412 if not isinstance( SubMeshOrGroup, list ):
6413 SubMeshOrGroup = [ SubMeshOrGroup ]
6414 for i,obj in enumerate( SubMeshOrGroup ):
6415 if isinstance( obj, Mesh ):
6416 SubMeshOrGroup = [ obj.GetMesh() ]
6418 if isinstance( obj, int ):
6419 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6420 unRegister.set( SubMeshOrGroup )
6423 if not isinstance( exceptNodes, list ):
6424 exceptNodes = [ exceptNodes ]
6425 if exceptNodes and isinstance( exceptNodes[0], int ):
6426 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6427 unRegister.set( exceptNodes )
6429 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6430 exceptNodes, SeparateCornerAndMediumNodes)
6432 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6437 GroupsOfNodes: a list of groups of nodes IDs for merging.
6438 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6439 in all elements and mesh groups by nodes 1 and 25 correspondingly
6440 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6441 If *NodesToKeep* does not include a node to keep for some group to merge,
6442 then the first node in the group is kept.
6443 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6447 This operation can create gaps in numeration of nodes or elements.
6448 Call :meth:`RenumberElements` to remove the gaps.
6450 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6452 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6454 Find the elements built on the same nodes.
6457 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6458 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6462 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6465 unRegister = genObjUnRegister()
6466 if MeshOrSubMeshOrGroup is None:
6467 MeshOrSubMeshOrGroup = [ self.mesh ]
6468 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6469 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6470 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6471 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6472 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6473 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6474 unRegister.set( MeshOrSubMeshOrGroup )
6475 for item in MeshOrSubMeshOrGroup:
6476 if isinstance( item, Mesh ):
6477 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6479 if not isinstance( exceptElements, list ):
6480 exceptElements = [ exceptElements ]
6481 if exceptElements and isinstance( exceptElements[0], int ):
6482 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6483 unRegister.set( exceptElements )
6485 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6487 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6489 Merge elements in each given group.
6492 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6493 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6494 replaced in all mesh groups by elements 1 and 25)
6495 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6496 If *ElementsToKeep* does not include an element to keep for some group to merge,
6497 then the first element in the group is kept.
6500 This operation can create gaps in numeration of elements.
6501 Call :meth:`RenumberElements` to remove the gaps.
6504 unRegister = genObjUnRegister()
6506 if not isinstance( ElementsToKeep, list ):
6507 ElementsToKeep = [ ElementsToKeep ]
6508 if isinstance( ElementsToKeep[0], int ):
6509 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6510 unRegister.set( ElementsToKeep )
6512 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6514 def MergeEqualElements(self):
6516 Leave one element and remove all other elements built on the same nodes.
6519 This operation can create gaps in numeration of elements.
6520 Call :meth:`RenumberElements` to remove the gaps.
6523 self.editor.MergeEqualElements()
6525 def FindFreeBorders(self, ClosedOnly=True):
6527 Returns all or only closed free borders
6530 list of SMESH.FreeBorder's
6533 return self.editor.FindFreeBorders( ClosedOnly )
6535 def FillHole(self, holeNodes, groupName=""):
6537 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6540 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6541 must describe all sequential nodes of the hole border. The first and the last
6542 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6543 groupName (string): name of a group to add new faces
6545 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6549 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6550 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6551 if not isinstance( holeNodes, SMESH.FreeBorder ):
6552 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6553 return self.editor.FillHole( holeNodes, groupName )
6555 def FindCoincidentFreeBorders (self, tolerance=0.):
6557 Return groups of FreeBorder's coincident within the given tolerance.
6560 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6561 size of elements adjacent to free borders being compared is used.
6564 SMESH.CoincidentFreeBorders structure
6567 return self.editor.FindCoincidentFreeBorders( tolerance )
6569 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6571 Sew FreeBorder's of each group
6574 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6575 where each enclosed list contains node IDs of a group of coincident free
6576 borders such that each consequent triple of IDs within a group describes
6577 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6578 last node of a border.
6579 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6580 groups of coincident free borders, each group including two borders.
6581 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6582 polygons if a node of opposite border falls on a face edge, else such
6583 faces are split into several ones.
6584 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6585 polyhedra if a node of opposite border falls on a volume edge, else such
6586 volumes, if any, remain intact and the mesh becomes non-conformal.
6589 a number of successfully sewed groups
6592 This operation can create gaps in numeration of nodes or elements.
6593 Call :meth:`RenumberElements` to remove the gaps.
6596 if freeBorders and isinstance( freeBorders, list ):
6597 # construct SMESH.CoincidentFreeBorders
6598 if isinstance( freeBorders[0], int ):
6599 freeBorders = [freeBorders]
6601 coincidentGroups = []
6602 for nodeList in freeBorders:
6603 if not nodeList or len( nodeList ) % 3:
6604 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6607 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6608 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6609 nodeList = nodeList[3:]
6611 coincidentGroups.append( group )
6613 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6615 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6617 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6618 FirstNodeID2, SecondNodeID2, LastNodeID2,
6619 CreatePolygons, CreatePolyedrs):
6624 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6627 This operation can create gaps in numeration of nodes or elements.
6628 Call :meth:`RenumberElements` to remove the gaps.
6631 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6632 FirstNodeID2, SecondNodeID2, LastNodeID2,
6633 CreatePolygons, CreatePolyedrs)
6635 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6636 FirstNodeID2, SecondNodeID2):
6638 Sew conform free borders
6641 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6644 This operation can create gaps in numeration of elements.
6645 Call :meth:`RenumberElements` to remove the gaps.
6648 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6649 FirstNodeID2, SecondNodeID2)
6651 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6652 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6657 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6660 This operation can create gaps in numeration of elements.
6661 Call :meth:`RenumberElements` to remove the gaps.
6664 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6665 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6667 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6668 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6669 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6671 Sew two sides of a mesh. The nodes belonging to Side1 are
6672 merged with the nodes of elements of Side2.
6673 The number of elements in theSide1 and in theSide2 must be
6674 equal and they should have similar nodal connectivity.
6675 The nodes to merge should belong to side borders and
6676 the first node should be linked to the second.
6679 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6682 This operation can create gaps in numeration of nodes.
6683 Call :meth:`RenumberElements` to remove the gaps.
6686 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6687 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6688 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6690 def ChangeElemNodes(self, ide, newIDs):
6692 Set new nodes for the given element. Number of nodes should be kept.
6699 False if the number of nodes does not correspond to the type of element
6702 return self.editor.ChangeElemNodes(ide, newIDs)
6704 def GetLastCreatedNodes(self):
6706 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6707 created, this method return the list of their IDs.
6708 If new nodes were not created - return empty list
6711 the list of integer values (can be empty)
6714 return self.editor.GetLastCreatedNodes()
6716 def GetLastCreatedElems(self):
6718 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6719 created this method return the list of their IDs.
6720 If new elements were not created - return empty list
6723 the list of integer values (can be empty)
6726 return self.editor.GetLastCreatedElems()
6728 def ClearLastCreated(self):
6730 Forget what nodes and elements were created by the last mesh edition operation
6733 self.editor.ClearLastCreated()
6735 def DoubleElements(self, theElements, theGroupName=""):
6737 Create duplicates of given elements, i.e. create new elements based on the
6738 same nodes as the given ones.
6741 theElements: container of elements to duplicate. It can be a
6742 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6743 or a list of element IDs. If *theElements* is
6744 a :class:`Mesh`, elements of highest dimension are duplicated
6745 theGroupName: a name of group to contain the generated elements.
6746 If a group with such a name already exists, the new elements
6747 are added to the existing group, else a new group is created.
6748 If *theGroupName* is empty, new elements are not added
6752 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6753 None if *theGroupName* == "".
6756 unRegister = genObjUnRegister()
6757 if isinstance( theElements, Mesh ):
6758 theElements = theElements.mesh
6759 elif isinstance( theElements, list ):
6760 theElements = self.GetIDSource( theElements, SMESH.ALL )
6761 unRegister.set( theElements )
6762 return self.editor.DoubleElements(theElements, theGroupName)
6764 def DoubleNodes(self, theNodes, theModifiedElems):
6766 Create a hole in a mesh by doubling the nodes of some particular elements
6769 theNodes: IDs of nodes to be doubled
6770 theModifiedElems: IDs of elements to be updated by the new (doubled)
6771 nodes. If list of element identifiers is empty then nodes are doubled but
6772 they not assigned to elements
6775 True if operation has been completed successfully, False otherwise
6778 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6780 def DoubleNode(self, theNodeId, theModifiedElems):
6782 Create a hole in a mesh by doubling the nodes of some particular elements.
6783 This method provided for convenience works as :meth:`DoubleNodes`.
6786 theNodeId: IDs of node to double
6787 theModifiedElems: IDs of elements to update
6790 True if operation has been completed successfully, False otherwise
6793 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6795 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6797 Create a hole in a mesh by doubling the nodes of some particular elements.
6798 This method provided for convenience works as :meth:`DoubleNodes`.
6801 theNodes: group of nodes to double.
6802 theModifiedElems: group of elements to update.
6803 theMakeGroup: forces the generation of a group containing new nodes.
6806 True or a created group if operation has been completed successfully,
6807 False or None otherwise
6811 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6812 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6814 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6816 Create a hole in a mesh by doubling the nodes of some particular elements.
6817 This method provided for convenience works as :meth:`DoubleNodes`.
6820 theNodes: list of groups of nodes to double.
6821 theModifiedElems: list of groups of elements to update.
6822 theMakeGroup: forces the generation of a group containing new nodes.
6825 True if operation has been completed successfully, False otherwise
6829 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6830 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6832 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6834 Create a hole in a mesh by doubling the nodes of some particular elements
6837 theElems: the list of elements (edges or faces) to replicate.
6838 The nodes for duplication could be found from these elements
6839 theNodesNot: list of nodes NOT to replicate
6840 theAffectedElems: the list of elements (cells and edges) to which the
6841 replicated nodes should be associated to
6844 True if operation has been completed successfully, False otherwise
6847 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6849 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6851 Create a hole in a mesh by doubling the nodes of some particular elements
6854 theElems: the list of elements (edges or faces) to replicate.
6855 The nodes for duplication could be found from these elements
6856 theNodesNot: list of nodes NOT to replicate
6857 theShape: shape to detect affected elements (element which geometric center
6858 located on or inside shape).
6859 The replicated nodes should be associated to affected elements.
6862 True if operation has been completed successfully, False otherwise
6865 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6867 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6868 theMakeGroup=False, theMakeNodeGroup=False):
6870 Create a hole in a mesh by doubling the nodes of some particular elements.
6871 This method provided for convenience works as :meth:`DoubleNodes`.
6874 theElems: group of of elements (edges or faces) to replicate.
6875 theNodesNot: group of nodes NOT to replicate.
6876 theAffectedElems: group of elements to which the replicated nodes
6877 should be associated to.
6878 theMakeGroup: forces the generation of a group containing new elements.
6879 theMakeNodeGroup: forces the generation of a group containing new nodes.
6882 True or created groups (one or two) if operation has been completed successfully,
6883 False or None otherwise
6886 if theMakeGroup or theMakeNodeGroup:
6887 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6889 theMakeGroup, theMakeNodeGroup)
6890 if theMakeGroup and theMakeNodeGroup:
6893 return twoGroups[ int(theMakeNodeGroup) ]
6894 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6896 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6898 Create a hole in a mesh by doubling the nodes of some particular elements.
6899 This method provided for convenience works as :meth:`DoubleNodes`.
6902 theElems: group of of elements (edges or faces) to replicate
6903 theNodesNot: group of nodes not to replicate
6904 theShape: shape to detect affected elements (element which geometric center
6905 located on or inside shape).
6906 The replicated nodes should be associated to affected elements
6909 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6911 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6912 theMakeGroup=False, theMakeNodeGroup=False):
6914 Create a hole in a mesh by doubling the nodes of some particular elements.
6915 This method provided for convenience works as :meth:`DoubleNodes`.
6918 theElems: list of groups of elements (edges or faces) to replicate
6919 theNodesNot: list of groups of nodes NOT to replicate
6920 theAffectedElems: group of elements to which the replicated nodes
6921 should be associated to
6922 theMakeGroup: forces generation of a group containing new elements.
6923 theMakeNodeGroup: forces generation of a group containing new nodes
6926 True or created groups (one or two) if operation has been completed successfully,
6927 False or None otherwise
6930 if theMakeGroup or theMakeNodeGroup:
6931 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6933 theMakeGroup, theMakeNodeGroup)
6934 if theMakeGroup and theMakeNodeGroup:
6937 return twoGroups[ int(theMakeNodeGroup) ]
6938 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6940 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6942 Create a hole in a mesh by doubling the nodes of some particular elements.
6943 This method provided for convenience works as :meth:`DoubleNodes`.
6946 theElems: list of groups of elements (edges or faces) to replicate
6947 theNodesNot: list of groups of nodes NOT to replicate
6948 theShape: shape to detect affected elements (element which geometric center
6949 located on or inside shape).
6950 The replicated nodes should be associated to affected elements
6953 True if operation has been completed successfully, False otherwise
6956 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6958 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6960 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6961 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6964 theElems: list of groups of nodes or elements (edges or faces) to replicate
6965 theNodesNot: list of groups of nodes NOT to replicate
6966 theShape: shape to detect affected elements (element which geometric center
6967 located on or inside shape).
6968 The replicated nodes should be associated to affected elements
6971 groups of affected elements in order: volumes, faces, edges
6974 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6976 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6979 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6980 The list of groups must describe a partition of the mesh volumes.
6981 The nodes of the internal faces at the boundaries of the groups are doubled.
6982 In option, the internal faces are replaced by flat elements.
6983 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6986 theDomains: list of groups of volumes
6987 createJointElems: if True, create the elements
6988 onAllBoundaries: if True, the nodes and elements are also created on
6989 the boundary between *theDomains* and the rest mesh
6992 True if operation has been completed successfully, False otherwise
6995 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6997 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6999 Double nodes on some external faces and create flat elements.
7000 Flat elements are mainly used by some types of mechanic calculations.
7002 Each group of the list must be constituted of faces.
7003 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7006 theGroupsOfFaces: list of groups of faces
7009 True if operation has been completed successfully, False otherwise
7012 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7014 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7016 Identify all the elements around a geom shape, get the faces delimiting the hole
7018 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7020 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7022 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7023 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7024 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7025 If there are several paths connecting a pair of points, the shortest path is
7026 selected by the module. Position of the cutting plane is defined by the two
7027 points and an optional vector lying on the plane specified by a PolySegment.
7028 By default the vector is defined by Mesh module as following. A middle point
7029 of the two given points is computed. The middle point is projected to the mesh.
7030 The vector goes from the middle point to the projection point. In case of planar
7031 mesh, the vector is normal to the mesh.
7033 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7036 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7037 groupName: optional name of a group where created mesh segments will be added.
7040 editor = self.editor
7042 editor = self.mesh.GetMeshEditPreviewer()
7043 segmentsRes = editor.MakePolyLine( segments, groupName )
7044 for i, seg in enumerate( segmentsRes ):
7045 segments[i].vector = seg.vector
7047 return editor.GetPreviewData()
7050 def MakeSlot(self, segmentGroup, width ):
7052 Create a slot of given width around given 1D elements lying on a triangle mesh.
7053 The slot is constructed by cutting faces by cylindrical surfaces made
7054 around each segment. Segments are expected to be created by MakePolyLine().
7057 FaceEdge's located at the slot boundary
7059 return self.editor.MakeSlot( segmentGroup, width )
7061 def GetFunctor(self, funcType ):
7063 Return a cached numerical functor by its type.
7066 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7067 Note that not all items correspond to numerical functors.
7070 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7073 fn = self.functors[ funcType._v ]
7075 fn = self.smeshpyD.GetFunctor(funcType)
7076 fn.SetMesh(self.mesh)
7077 self.functors[ funcType._v ] = fn
7080 def FunctorValue(self, funcType, elemId, isElem=True):
7082 Return value of a functor for a given element
7085 funcType: an item of :class:`SMESH.FunctorType` enum.
7086 elemId: element or node ID
7087 isElem: *elemId* is ID of element or node
7090 the functor value or zero in case of invalid arguments
7093 fn = self.GetFunctor( funcType )
7094 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7095 val = fn.GetValue(elemId)
7100 def GetLength(self, elemId=None):
7102 Get length of given 1D elements or of all 1D mesh elements
7105 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.
7108 Sum of lengths of given elements
7113 length = self.smeshpyD.GetLength(self)
7114 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7115 length = self.smeshpyD.GetLength(elemId)
7118 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7120 length += self.smeshpyD.GetLength(obj)
7121 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7122 unRegister = genObjUnRegister()
7123 obj = self.GetIDSource( elemId )
7124 unRegister.set( obj )
7125 length = self.smeshpyD.GetLength( obj )
7127 length = self.FunctorValue(SMESH.FT_Length, elemId)
7130 def GetArea(self, elemId=None):
7132 Get area of given 2D elements or of all 2D mesh elements
7135 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.
7138 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7143 area = self.smeshpyD.GetArea(self)
7144 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7145 area = self.smeshpyD.GetArea(elemId)
7148 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7150 area += self.smeshpyD.GetArea(obj)
7151 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7152 unRegister = genObjUnRegister()
7153 obj = self.GetIDSource( elemId )
7154 unRegister.set( obj )
7155 area = self.smeshpyD.GetArea( obj )
7157 area = self.FunctorValue(SMESH.FT_Area, elemId)
7160 def GetVolume(self, elemId=None):
7162 Get volume of given 3D elements or of all 3D mesh elements
7165 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.
7168 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7173 volume= self.smeshpyD.GetVolume(self)
7174 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7175 volume= self.smeshpyD.GetVolume(elemId)
7178 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7180 volume+= self.smeshpyD.GetVolume(obj)
7181 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7182 unRegister = genObjUnRegister()
7183 obj = self.GetIDSource( elemId )
7184 unRegister.set( obj )
7185 volume= self.smeshpyD.GetVolume( obj )
7187 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7190 def GetAngle(self, node1, node2, node3 ):
7192 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7195 node1,node2,node3: IDs of the three nodes
7198 Angle in radians [0,PI]. -1 if failure case.
7200 p1 = self.GetNodeXYZ( node1 )
7201 p2 = self.GetNodeXYZ( node2 )
7202 p3 = self.GetNodeXYZ( node3 )
7203 if p1 and p2 and p3:
7204 return self.smeshpyD.GetAngle( p1,p2,p3 )
7208 def GetMaxElementLength(self, elemId):
7210 Get maximum element length.
7213 elemId: mesh element ID
7216 element's maximum length value
7219 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7220 ftype = SMESH.FT_MaxElementLength3D
7222 ftype = SMESH.FT_MaxElementLength2D
7223 return self.FunctorValue(ftype, elemId)
7225 def GetAspectRatio(self, elemId):
7227 Get aspect ratio of 2D or 3D element.
7230 elemId: mesh element ID
7233 element's aspect ratio value
7236 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7237 ftype = SMESH.FT_AspectRatio3D
7239 ftype = SMESH.FT_AspectRatio
7240 return self.FunctorValue(ftype, elemId)
7242 def GetWarping(self, elemId):
7244 Get warping angle of 2D element.
7247 elemId: mesh element ID
7250 element's warping angle value
7253 return self.FunctorValue(SMESH.FT_Warping, elemId)
7255 def GetMinimumAngle(self, elemId):
7257 Get minimum angle of 2D element.
7260 elemId: mesh element ID
7263 element's minimum angle value
7266 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7268 def GetTaper(self, elemId):
7270 Get taper of 2D element.
7273 elemId: mesh element ID
7276 element's taper value
7279 return self.FunctorValue(SMESH.FT_Taper, elemId)
7281 def GetSkew(self, elemId):
7283 Get skew of 2D element.
7286 elemId: mesh element ID
7289 element's skew value
7292 return self.FunctorValue(SMESH.FT_Skew, elemId)
7294 def GetMinMax(self, funType, meshPart=None):
7296 Return minimal and maximal value of a given functor.
7299 funType (SMESH.FunctorType): a functor type.
7300 Note that not all items of :class:`SMESH.FunctorType` corresponds
7301 to numerical functors.
7302 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7308 unRegister = genObjUnRegister()
7309 if isinstance( meshPart, list ):
7310 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7311 unRegister.set( meshPart )
7312 if isinstance( meshPart, Mesh ):
7313 meshPart = meshPart.mesh
7314 fun = self.GetFunctor( funType )
7317 if hasattr( meshPart, "SetMesh" ):
7318 meshPart.SetMesh( self.mesh ) # set mesh to filter
7319 hist = fun.GetLocalHistogram( 1, False, meshPart )
7321 hist = fun.GetHistogram( 1, False )
7323 return hist[0].min, hist[0].max
7326 pass # end of Mesh class
7329 class meshProxy(SMESH._objref_SMESH_Mesh):
7331 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7332 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7334 def __init__(self,*args):
7335 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7336 def __deepcopy__(self, memo=None):
7337 new = self.__class__(self)
7339 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7340 if len( args ) == 3:
7341 args += SMESH.ALL_NODES, True
7342 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7343 def ExportToMEDX(self, *args): # function removed
7344 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7345 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7346 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7347 def ExportToMED(self, *args): # function removed
7348 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7349 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7351 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7353 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7354 def ExportPartToMED(self, *args): # 'version' parameter removed
7355 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7356 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7357 def ExportMED(self, *args): # signature of method changed
7358 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7360 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7362 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7364 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7367 class submeshProxy(SMESH._objref_SMESH_subMesh):
7370 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7372 def __init__(self,*args):
7373 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7375 def __deepcopy__(self, memo=None):
7376 new = self.__class__(self)
7379 def Compute(self,refresh=False):
7381 Compute the sub-mesh and return the status of the computation
7384 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7389 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7390 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7394 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7396 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7398 if salome.sg.hasDesktop():
7399 if refresh: salome.sg.updateObjBrowser()
7404 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7407 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7409 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7410 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7413 def __init__(self,*args):
7414 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7416 def __getattr__(self, name ): # method called if an attribute not found
7417 if not self.mesh: # look for name() method in Mesh class
7418 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7419 if hasattr( self.mesh, name ):
7420 return getattr( self.mesh, name )
7421 if name == "ExtrusionAlongPathObjX":
7422 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7423 print("meshEditor: attribute '%s' NOT FOUND" % name)
7425 def __deepcopy__(self, memo=None):
7426 new = self.__class__(self)
7428 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7429 if len( args ) == 1: args += False,
7430 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7431 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7432 if len( args ) == 2: args += False,
7433 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7434 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7435 if len( args ) == 1:
7436 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7437 NodesToKeep = args[1]
7438 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7439 unRegister = genObjUnRegister()
7441 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7442 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7443 if not isinstance( NodesToKeep, list ):
7444 NodesToKeep = [ NodesToKeep ]
7445 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7447 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7449 class Pattern(SMESH._objref_SMESH_Pattern):
7451 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7452 variables in some methods
7455 def LoadFromFile(self, patternTextOrFile ):
7456 text = patternTextOrFile
7457 if os.path.exists( text ):
7458 text = open( patternTextOrFile ).read()
7460 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7462 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7463 decrFun = lambda i: i-1
7464 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7465 theMesh.SetParameters(Parameters)
7466 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7468 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7469 decrFun = lambda i: i-1
7470 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7471 theMesh.SetParameters(Parameters)
7472 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7474 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7475 if isinstance( mesh, Mesh ):
7476 mesh = mesh.GetMesh()
7477 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7479 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7481 Registering the new proxy for Pattern
7486 Private class used to bind methods creating algorithms to the class Mesh
7489 def __init__(self, method):
7491 self.defaultAlgoType = ""
7492 self.algoTypeToClass = {}
7493 self.method = method
7495 def add(self, algoClass):
7497 Store a python class of algorithm
7499 if inspect.isclass(algoClass) and \
7500 hasattr( algoClass, "algoType"):
7501 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7502 if not self.defaultAlgoType and \
7503 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7504 self.defaultAlgoType = algoClass.algoType
7505 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7507 def copy(self, mesh):
7509 Create a copy of self and assign mesh to the copy
7512 other = algoCreator( self.method )
7513 other.defaultAlgoType = self.defaultAlgoType
7514 other.algoTypeToClass = self.algoTypeToClass
7518 def __call__(self,algo="",geom=0,*args):
7520 Create an instance of algorithm
7524 if isinstance( algo, str ):
7526 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7527 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7532 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7534 elif not algoType and isinstance( geom, str ):
7539 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7541 elif isinstance( arg, str ) and not algoType:
7544 import traceback, sys
7545 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7546 sys.stderr.write( msg + '\n' )
7547 tb = traceback.extract_stack(None,2)
7548 traceback.print_list( [tb[0]] )
7550 algoType = self.defaultAlgoType
7551 if not algoType and self.algoTypeToClass:
7552 algoType = sorted( self.algoTypeToClass.keys() )[0]
7553 if algoType in self.algoTypeToClass:
7554 #print("Create algo",algoType)
7555 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7556 raise RuntimeError( "No class found for algo type %s" % algoType)
7559 class hypMethodWrapper:
7561 Private class used to substitute and store variable parameters of hypotheses.
7564 def __init__(self, hyp, method):
7566 self.method = method
7567 #print("REBIND:", method.__name__)
7570 def __call__(self,*args):
7572 call a method of hypothesis with calling SetVarParameter() before
7576 return self.method( self.hyp, *args ) # hypothesis method with no args
7578 #print("MethWrapper.__call__", self.method.__name__, args)
7580 parsed = ParseParameters(*args) # replace variables with their values
7581 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7582 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7583 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7584 # maybe there is a replaced string arg which is not variable
7585 result = self.method( self.hyp, *args )
7586 except ValueError as detail: # raised by ParseParameters()
7588 result = self.method( self.hyp, *args )
7589 except omniORB.CORBA.BAD_PARAM:
7590 raise ValueError(detail) # wrong variable name
7595 class genObjUnRegister:
7597 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7600 def __init__(self, genObj=None):
7601 self.genObjList = []
7605 def set(self, genObj):
7606 "Store one or a list of of SALOME.GenericObj'es"
7607 if isinstance( genObj, list ):
7608 self.genObjList.extend( genObj )
7610 self.genObjList.append( genObj )
7614 for genObj in self.genObjList:
7615 if genObj and hasattr( genObj, "UnRegister" ):
7618 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7620 Bind methods creating mesher plug-ins to the Mesh class
7623 # print("pluginName: ", pluginName)
7624 pluginBuilderName = pluginName + "Builder"
7626 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7627 except Exception as e:
7628 from salome_utils import verbose
7629 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7631 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7632 plugin = eval( pluginBuilderName )
7633 # print(" plugin:" , str(plugin))
7635 # add methods creating algorithms to Mesh
7636 for k in dir( plugin ):
7637 if k[0] == '_': continue
7638 algo = getattr( plugin, k )
7639 #print(" algo:", str(algo))
7640 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7641 #print(" meshMethod:" , str(algo.meshMethod))
7642 if not hasattr( Mesh, algo.meshMethod ):
7643 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7645 _mmethod = getattr( Mesh, algo.meshMethod )
7646 if hasattr( _mmethod, "add" ):