1 # Copyright (C) 2007-2019 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 isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
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 GetMeshInfo(self, obj):
1244 Get the mesh statistic.
1247 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1250 if isinstance( obj, Mesh ):
1253 if hasattr(obj, "GetMeshInfo"):
1254 values = obj.GetMeshInfo()
1255 for i in range(SMESH.Entity_Last._v):
1256 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1260 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1262 Get minimum distance between two objects
1264 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1265 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1268 src1 (SMESH.SMESH_IDSource): first source object
1269 src2 (SMESH.SMESH_IDSource): second source object
1270 id1 (int): node/element id from the first source
1271 id2 (int): node/element id from the second (or first) source
1272 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1273 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1276 minimum distance value
1279 :meth:`GetMinDistance`
1282 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1286 result = result.value
1289 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1291 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1293 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1294 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1297 src1 (SMESH.SMESH_IDSource): first source object
1298 src2 (SMESH.SMESH_IDSource): second source object
1299 id1 (int): node/element id from the first source
1300 id2 (int): node/element id from the second (or first) source
1301 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1302 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1305 :class:`SMESH.Measure` structure or None if input data is invalid
1310 if isinstance(src1, Mesh): src1 = src1.mesh
1311 if isinstance(src2, Mesh): src2 = src2.mesh
1312 if src2 is None and id2 != 0: src2 = src1
1313 if not hasattr(src1, "_narrow"): return None
1314 src1 = src1._narrow(SMESH.SMESH_IDSource)
1315 if not src1: return None
1316 unRegister = genObjUnRegister()
1319 e = m.GetMeshEditor()
1321 src1 = e.MakeIDSource([id1], SMESH.FACE)
1323 src1 = e.MakeIDSource([id1], SMESH.NODE)
1324 unRegister.set( src1 )
1326 if hasattr(src2, "_narrow"):
1327 src2 = src2._narrow(SMESH.SMESH_IDSource)
1328 if src2 and id2 != 0:
1330 e = m.GetMeshEditor()
1332 src2 = e.MakeIDSource([id2], SMESH.FACE)
1334 src2 = e.MakeIDSource([id2], SMESH.NODE)
1335 unRegister.set( src2 )
1338 aMeasurements = self.CreateMeasurements()
1339 unRegister.set( aMeasurements )
1340 result = aMeasurements.MinDistance(src1, src2)
1343 def BoundingBox(self, objects):
1345 Get bounding box of the specified object(s)
1348 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1351 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1354 :meth:`GetBoundingBox`
1357 result = self.GetBoundingBox(objects)
1361 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1364 def GetBoundingBox(self, objects):
1366 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1369 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1372 :class:`SMESH.Measure` structure
1378 if isinstance(objects, tuple):
1379 objects = list(objects)
1380 if not isinstance(objects, list):
1384 if isinstance(o, Mesh):
1385 srclist.append(o.mesh)
1386 elif hasattr(o, "_narrow"):
1387 src = o._narrow(SMESH.SMESH_IDSource)
1388 if src: srclist.append(src)
1391 aMeasurements = self.CreateMeasurements()
1392 result = aMeasurements.BoundingBox(srclist)
1393 aMeasurements.UnRegister()
1396 def GetLength(self, obj):
1398 Get sum of lengths of all 1D elements in the mesh object.
1401 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1404 sum of lengths of all 1D elements
1407 if isinstance(obj, Mesh): obj = obj.mesh
1408 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1409 aMeasurements = self.CreateMeasurements()
1410 value = aMeasurements.Length(obj)
1411 aMeasurements.UnRegister()
1414 def GetArea(self, obj):
1416 Get sum of areas of all 2D elements in the mesh object.
1419 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1422 sum of areas of all 2D elements
1425 if isinstance(obj, Mesh): obj = obj.mesh
1426 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1427 aMeasurements = self.CreateMeasurements()
1428 value = aMeasurements.Area(obj)
1429 aMeasurements.UnRegister()
1432 def GetVolume(self, obj):
1434 Get sum of volumes of all 3D elements in the mesh object.
1437 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1440 sum of volumes of all 3D elements
1443 if isinstance(obj, Mesh): obj = obj.mesh
1444 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1445 aMeasurements = self.CreateMeasurements()
1446 value = aMeasurements.Volume(obj)
1447 aMeasurements.UnRegister()
1450 def GetGravityCenter(self, obj):
1452 Get gravity center of all nodes of a mesh object.
1455 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1458 Three components of the gravity center (x,y,z)
1461 :meth:`Mesh.BaryCenter`
1463 if isinstance(obj, Mesh): obj = obj.mesh
1464 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1465 aMeasurements = self.CreateMeasurements()
1466 pointStruct = aMeasurements.GravityCenter(obj)
1467 aMeasurements.UnRegister()
1468 return pointStruct.x, pointStruct.y, pointStruct.z
1470 def GetAngle(self, p1, p2, p3 ):
1472 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1475 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1481 if isinstance( p1, list ): p1 = PointStruct(*p1)
1482 if isinstance( p2, list ): p2 = PointStruct(*p2)
1483 if isinstance( p3, list ): p3 = PointStruct(*p3)
1485 aMeasurements = self.CreateMeasurements()
1486 angle = aMeasurements.Angle(p1,p2,p3)
1487 aMeasurements.UnRegister()
1492 pass # end of class smeshBuilder
1495 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1496 """Registering the new proxy for SMESH.SMESH_Gen"""
1499 def New( instance=None, instanceGeom=None):
1501 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1502 interface to create or load meshes.
1507 salome.salome_init()
1508 from salome.smesh import smeshBuilder
1509 smesh = smeshBuilder.New()
1512 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1513 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1515 :class:`smeshBuilder` instance
1520 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1522 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1527 smeshInst = smeshBuilder()
1528 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1529 smeshInst.init_smesh(instanceGeom)
1533 # Public class: Mesh
1534 # ==================
1537 class Mesh(metaclass = MeshMeta):
1539 This class allows defining and managing a mesh.
1540 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1541 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1542 new nodes and elements and by changing the existing entities), to get information
1543 about a mesh and to export a mesh in different formats.
1550 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1555 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1556 sets the GUI name of this mesh to *name*.
1559 smeshpyD: an instance of smeshBuilder class
1560 geompyD: an instance of geomBuilder class
1561 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1562 name: Study name of the mesh
1565 self.smeshpyD = smeshpyD
1566 self.geompyD = geompyD
1571 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1574 # publish geom of mesh (issue 0021122)
1575 if not self.geom.GetStudyEntry():
1579 geo_name = name + " shape"
1581 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1582 geompyD.addToStudy( self.geom, geo_name )
1583 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1585 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1588 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1590 self.smeshpyD.SetName(self.mesh, name)
1592 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1595 self.geom = self.mesh.GetShapeToMesh()
1597 self.editor = self.mesh.GetMeshEditor()
1598 self.functors = [None] * SMESH.FT_Undefined._v
1600 # set self to algoCreator's
1601 for attrName in dir(self):
1602 attr = getattr( self, attrName )
1603 if isinstance( attr, algoCreator ):
1604 setattr( self, attrName, attr.copy( self ))
1611 Destructor. Clean-up resources
1614 #self.mesh.UnRegister()
1618 def SetMesh(self, theMesh):
1620 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1623 theMesh: a :class:`SMESH.SMESH_Mesh` object
1625 # do not call Register() as this prevents mesh servant deletion at closing study
1626 #if self.mesh: self.mesh.UnRegister()
1629 #self.mesh.Register()
1630 self.geom = self.mesh.GetShapeToMesh()
1632 self.geompyD = self.geom.GetGen()
1638 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1641 a :class:`SMESH.SMESH_Mesh` object
1646 def GetEngine(self):
1648 Return a smeshBuilder instance created this mesh
1650 return self.smeshpyD
1652 def GetGeomEngine(self):
1654 Return a geomBuilder instance
1660 Get the name of the mesh
1663 the name of the mesh as a string
1666 name = GetName(self.GetMesh())
1669 def SetName(self, name):
1671 Set a name to the mesh
1674 name: a new name of the mesh
1677 self.smeshpyD.SetName(self.GetMesh(), name)
1679 def GetSubMesh(self, geom, name):
1681 Get a sub-mesh object associated to a *geom* geometrical object.
1684 geom: a geometrical object (shape)
1685 name: a name for the sub-mesh in the Object Browser
1688 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1689 which lies on the given shape
1692 A sub-mesh is implicitly created when a sub-shape is specified at
1693 creating an algorithm, for example::
1695 algo1D = mesh.Segment(geom=Edge_1)
1697 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1698 The created sub-mesh can be retrieved from the algorithm::
1700 submesh = algo1D.GetSubMesh()
1703 AssureGeomPublished( self, geom, name )
1704 submesh = self.mesh.GetSubMesh( geom, name )
1709 Return the shape associated to the mesh
1717 def SetShape(self, geom):
1719 Associate the given shape to the mesh (entails the recreation of the mesh)
1722 geom: the shape to be meshed (GEOM_Object)
1725 self.mesh = self.smeshpyD.CreateMesh(geom)
1727 def HasShapeToMesh(self):
1729 Return ``True`` if this mesh is based on geometry
1731 return self.mesh.HasShapeToMesh()
1735 Load mesh from the study after opening the study
1739 def IsReadyToCompute(self, theSubObject):
1741 Return true if the hypotheses are defined well
1744 theSubObject: a sub-shape of a mesh shape
1750 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1752 def GetAlgoState(self, theSubObject):
1754 Return errors of hypotheses definition.
1755 The list of errors is empty if everything is OK.
1758 theSubObject: a sub-shape of a mesh shape
1764 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1766 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1768 Return a geometrical object on which the given element was built.
1769 The returned geometrical object, if not nil, is either found in the
1770 study or published by this method with the given name
1773 theElementID: the id of the mesh element
1774 theGeomName: the user-defined name of the geometrical object
1777 GEOM.GEOM_Object instance
1780 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1782 def MeshDimension(self):
1784 Return the mesh dimension depending on the dimension of the underlying shape
1785 or, if the mesh is not based on any shape, basing on deimension of elements
1788 mesh dimension as an integer value [0,3]
1791 if self.mesh.HasShapeToMesh():
1792 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1793 if len( shells ) > 0 :
1795 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1797 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1802 if self.NbVolumes() > 0: return 3
1803 if self.NbFaces() > 0: return 2
1804 if self.NbEdges() > 0: return 1
1807 def Evaluate(self, geom=0):
1809 Evaluate size of prospective mesh on a shape
1812 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1813 To know predicted number of e.g. edges, inquire it this way::
1815 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1818 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1820 geom = self.mesh.GetShapeToMesh()
1823 return self.smeshpyD.Evaluate(self.mesh, geom)
1826 def Compute(self, geom=0, discardModifs=False, refresh=False):
1828 Compute the mesh and return the status of the computation
1831 geom: geomtrical shape on which mesh data should be computed
1832 discardModifs: if True and the mesh has been edited since
1833 a last total re-compute and that may prevent successful partial re-compute,
1834 then the mesh is cleaned before Compute()
1835 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1841 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1843 geom = self.mesh.GetShapeToMesh()
1848 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1850 ok = self.smeshpyD.Compute(self.mesh, geom)
1851 except SALOME.SALOME_Exception as ex:
1852 print("Mesh computation failed, exception caught:")
1853 print(" ", ex.details.text)
1856 print("Mesh computation failed, exception caught:")
1857 traceback.print_exc()
1861 # Treat compute errors
1862 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1864 for err in computeErrors:
1865 if self.mesh.HasShapeToMesh():
1866 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1868 stdErrors = ["OK", #COMPERR_OK
1869 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1870 "std::exception", #COMPERR_STD_EXCEPTION
1871 "OCC exception", #COMPERR_OCC_EXCEPTION
1872 "..", #COMPERR_SLM_EXCEPTION
1873 "Unknown exception", #COMPERR_EXCEPTION
1874 "Memory allocation problem", #COMPERR_MEMORY_PB
1875 "Algorithm failed", #COMPERR_ALGO_FAILED
1876 "Unexpected geometry", #COMPERR_BAD_SHAPE
1877 "Warning", #COMPERR_WARNING
1878 "Computation cancelled",#COMPERR_CANCELED
1879 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1881 if err.code < len(stdErrors): errText = stdErrors[err.code]
1883 errText = "code %s" % -err.code
1884 if errText: errText += ". "
1885 errText += err.comment
1886 if allReasons: allReasons += "\n"
1888 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1890 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1894 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1896 if err.isGlobalAlgo:
1904 reason = '%s %sD algorithm is missing' % (glob, dim)
1905 elif err.state == HYP_MISSING:
1906 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1907 % (glob, dim, name, dim))
1908 elif err.state == HYP_NOTCONFORM:
1909 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1910 elif err.state == HYP_BAD_PARAMETER:
1911 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1912 % ( glob, dim, name ))
1913 elif err.state == HYP_BAD_GEOMETRY:
1914 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1915 'geometry' % ( glob, dim, name ))
1916 elif err.state == HYP_HIDDEN_ALGO:
1917 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1918 'algorithm of upper dimension generating %sD mesh'
1919 % ( glob, dim, name, glob, dim ))
1921 reason = ("For unknown reason. "
1922 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1924 if allReasons: allReasons += "\n"
1925 allReasons += "- " + reason
1927 if not ok or allReasons != "":
1928 msg = '"' + GetName(self.mesh) + '"'
1929 if ok: msg += " has been computed with warnings"
1930 else: msg += " has not been computed"
1931 if allReasons != "": msg += ":"
1936 if salome.sg.hasDesktop():
1937 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1938 if refresh: salome.sg.updateObjBrowser()
1942 def GetComputeErrors(self, shape=0 ):
1944 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1948 shape = self.mesh.GetShapeToMesh()
1949 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1951 def GetSubShapeName(self, subShapeID ):
1953 Return a name of a sub-shape by its ID.
1954 Possible variants (for *subShapeID* == 3):
1956 - **"Face_12"** - published sub-shape
1957 - **FACE #3** - not published sub-shape
1958 - **sub-shape #3** - invalid sub-shape ID
1959 - **#3** - error in this function
1962 subShapeID: a unique ID of a sub-shape
1965 a string describing the sub-shape
1969 if not self.mesh.HasShapeToMesh():
1973 mainIOR = salome.orb.object_to_string( self.GetShape() )
1975 mainSO = s.FindObjectIOR(mainIOR)
1978 shapeText = '"%s"' % mainSO.GetName()
1979 subIt = s.NewChildIterator(mainSO)
1981 subSO = subIt.Value()
1983 obj = subSO.GetObject()
1984 if not obj: continue
1985 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1988 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1991 if ids == subShapeID:
1992 shapeText = '"%s"' % subSO.GetName()
1995 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
1997 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
1999 shapeText = 'sub-shape #%s' % (subShapeID)
2001 shapeText = "#%s" % (subShapeID)
2004 def GetFailedShapes(self, publish=False):
2006 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2007 error of an algorithm
2010 publish: if *True*, the returned groups will be published in the study
2013 a list of GEOM groups each named after a failed algorithm
2018 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2019 for err in computeErrors:
2020 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2021 if not shape: continue
2022 if err.algoName in algo2shapes:
2023 algo2shapes[ err.algoName ].append( shape )
2025 algo2shapes[ err.algoName ] = [ shape ]
2029 for algoName, shapes in list(algo2shapes.items()):
2031 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2032 otherTypeShapes = []
2034 group = self.geompyD.CreateGroup( self.geom, groupType )
2035 for shape in shapes:
2036 if shape.GetShapeType() == shapes[0].GetShapeType():
2037 sameTypeShapes.append( shape )
2039 otherTypeShapes.append( shape )
2040 self.geompyD.UnionList( group, sameTypeShapes )
2042 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2044 group.SetName( algoName )
2045 groups.append( group )
2046 shapes = otherTypeShapes
2049 for group in groups:
2050 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2053 def GetMeshOrder(self):
2055 Return sub-mesh objects list in meshing order
2058 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2061 return self.mesh.GetMeshOrder()
2063 def SetMeshOrder(self, submeshes):
2065 Set priority of sub-meshes. It works in two ways:
2067 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2068 *several dimensions*, it sets the order in which the sub-meshes are computed.
2069 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2070 when looking for meshing parameters to apply to a sub-shape. To impose the
2071 order in which sub-meshes with uni-dimensional algorithms are computed,
2072 call **submesh.Compute()** in a desired order.
2075 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2078 return self.mesh.SetMeshOrder(submeshes)
2080 def Clear(self, refresh=False):
2082 Remove all nodes and elements generated on geometry. Imported elements remain.
2085 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2089 if ( salome.sg.hasDesktop() ):
2090 if refresh: salome.sg.updateObjBrowser()
2092 def ClearSubMesh(self, geomId, refresh=False):
2094 Remove all nodes and elements of indicated shape
2097 geomId: the ID of a sub-shape to remove elements on
2098 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2101 self.mesh.ClearSubMesh(geomId)
2102 if salome.sg.hasDesktop():
2103 if refresh: salome.sg.updateObjBrowser()
2105 def AutomaticTetrahedralization(self, fineness=0):
2107 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2110 fineness: [0.0,1.0] defines mesh fineness
2116 dim = self.MeshDimension()
2118 self.RemoveGlobalHypotheses()
2119 self.Segment().AutomaticLength(fineness)
2121 self.Triangle().LengthFromEdges()
2126 return self.Compute()
2128 def AutomaticHexahedralization(self, fineness=0):
2130 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2133 fineness: [0.0, 1.0] defines mesh fineness
2139 dim = self.MeshDimension()
2140 # assign the hypotheses
2141 self.RemoveGlobalHypotheses()
2142 self.Segment().AutomaticLength(fineness)
2149 return self.Compute()
2151 def AddHypothesis(self, hyp, geom=0):
2156 hyp: a hypothesis to assign
2157 geom: a subhape of mesh geometry
2160 :class:`SMESH.Hypothesis_Status`
2163 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2164 hyp, geom = geom, hyp
2165 if isinstance( hyp, Mesh_Algorithm ):
2166 hyp = hyp.GetAlgorithm()
2171 geom = self.mesh.GetShapeToMesh()
2174 if self.mesh.HasShapeToMesh():
2175 hyp_type = hyp.GetName()
2176 lib_name = hyp.GetLibName()
2177 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2178 # if checkAll and geom:
2179 # checkAll = geom.GetType() == 37
2181 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2183 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2184 status = self.mesh.AddHypothesis(geom, hyp)
2186 status = HYP_BAD_GEOMETRY, ""
2187 hyp_name = GetName( hyp )
2190 geom_name = geom.GetName()
2191 isAlgo = hyp._narrow( SMESH_Algo )
2192 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2195 def IsUsedHypothesis(self, hyp, geom):
2197 Return True if an algorithm or hypothesis is assigned to a given shape
2200 hyp: an algorithm or hypothesis to check
2201 geom: a subhape of mesh geometry
2207 if not hyp: # or not geom
2209 if isinstance( hyp, Mesh_Algorithm ):
2210 hyp = hyp.GetAlgorithm()
2212 hyps = self.GetHypothesisList(geom)
2214 if h.GetId() == hyp.GetId():
2218 def RemoveHypothesis(self, hyp, geom=0):
2220 Unassign a hypothesis
2223 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2224 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2227 :class:`SMESH.Hypothesis_Status`
2232 if isinstance( hyp, Mesh_Algorithm ):
2233 hyp = hyp.GetAlgorithm()
2239 if self.IsUsedHypothesis( hyp, shape ):
2240 return self.mesh.RemoveHypothesis( shape, hyp )
2241 hypName = GetName( hyp )
2242 geoName = GetName( shape )
2243 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2246 def GetHypothesisList(self, geom):
2248 Get the list of hypotheses added on a geometry
2251 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2254 the sequence of :class:`SMESH.SMESH_Hypothesis`
2257 return self.mesh.GetHypothesisList( geom )
2259 def RemoveGlobalHypotheses(self):
2261 Remove all global hypotheses
2264 current_hyps = self.mesh.GetHypothesisList( self.geom )
2265 for hyp in current_hyps:
2266 self.mesh.RemoveHypothesis( self.geom, hyp )
2269 def ExportMED(self, *args, **kwargs):
2271 Export the mesh in a file in MED format
2272 allowing to overwrite the file if it exists or add the exported data to its contents
2275 fileName: is the file name
2276 auto_groups (boolean): parameter for creating/not creating
2277 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2278 the typical use is auto_groups=False.
2279 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2280 The minor must be between 0 and the current minor version of MED file library.
2281 If minor is equal to -1, the minor version is not changed (default).
2282 The major version (x, where version is x.y.z) cannot be changed.
2283 overwrite (boolean): parameter for overwriting/not overwriting the file
2284 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2285 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2287 - 1D if all mesh nodes lie on OX coordinate axis, or
2288 - 2D if all mesh nodes lie on XOY coordinate plane, or
2289 - 3D in the rest cases.
2291 If *autoDimension* is *False*, the space dimension is always 3.
2292 fields: list of GEOM fields defined on the shape to mesh.
2293 geomAssocFields: each character of this string means a need to export a
2294 corresponding field; correspondence between fields and characters
2297 - 'v' stands for "_vertices_" field;
2298 - 'e' stands for "_edges_" field;
2299 - 'f' stands for "_faces_" field;
2300 - 's' stands for "_solids_" field.
2302 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2303 close to zero within a given tolerance, the coordinate is set to zero.
2304 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2306 # process positional arguments
2307 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2309 auto_groups = args[1] if len(args) > 1 else False
2310 minor = args[2] if len(args) > 2 else -1
2311 overwrite = args[3] if len(args) > 3 else True
2312 meshPart = args[4] if len(args) > 4 else None
2313 autoDimension = args[5] if len(args) > 5 else True
2314 fields = args[6] if len(args) > 6 else []
2315 geomAssocFields = args[7] if len(args) > 7 else ''
2316 z_tolerance = args[8] if len(args) > 8 else -1.
2317 # process keywords arguments
2318 auto_groups = kwargs.get("auto_groups", auto_groups)
2319 minor = kwargs.get("minor", minor)
2320 overwrite = kwargs.get("overwrite", overwrite)
2321 meshPart = kwargs.get("meshPart", meshPart)
2322 autoDimension = kwargs.get("autoDimension", autoDimension)
2323 fields = kwargs.get("fields", fields)
2324 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2325 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2327 # invoke engine's function
2328 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2329 unRegister = genObjUnRegister()
2330 if isinstance( meshPart, list ):
2331 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2332 unRegister.set( meshPart )
2334 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2335 self.mesh.SetParameters(Parameters)
2337 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2338 fields, geomAssocFields, z_tolerance)
2340 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2342 def ExportSAUV(self, f, auto_groups=0):
2344 Export the mesh in a file in SAUV format
2349 auto_groups: boolean parameter for creating/not creating
2350 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2351 the typical use is auto_groups=False.
2354 self.mesh.ExportSAUV(f, auto_groups)
2356 def ExportDAT(self, f, meshPart=None):
2358 Export the mesh in a file in DAT format
2362 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2366 unRegister = genObjUnRegister()
2367 if isinstance( meshPart, list ):
2368 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2369 unRegister.set( meshPart )
2370 self.mesh.ExportPartToDAT( meshPart, f )
2372 self.mesh.ExportDAT(f)
2374 def ExportUNV(self, f, meshPart=None):
2376 Export the mesh in a file in UNV 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.ExportPartToUNV( meshPart, f )
2390 self.mesh.ExportUNV(f)
2392 def ExportSTL(self, f, ascii=1, meshPart=None):
2394 Export the mesh in a file in STL format
2398 ascii: defines the file encoding
2399 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2403 unRegister = genObjUnRegister()
2404 if isinstance( meshPart, list ):
2405 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2406 unRegister.set( meshPart )
2407 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2409 self.mesh.ExportSTL(f, ascii)
2411 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2413 Export the mesh in a file in CGNS format
2417 overwrite: boolean parameter for overwriting/not overwriting the file
2418 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2419 groupElemsByType: if True all elements of same entity type are exported at ones,
2420 else elements are exported in order of their IDs which can cause creation
2421 of multiple cgns sections
2424 unRegister = genObjUnRegister()
2425 if isinstance( meshPart, list ):
2426 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2427 unRegister.set( meshPart )
2428 if isinstance( meshPart, Mesh ):
2429 meshPart = meshPart.mesh
2431 meshPart = self.mesh
2432 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2434 def ExportGMF(self, f, meshPart=None):
2436 Export the mesh in a file in GMF format.
2437 GMF files must have .mesh extension for the ASCII format and .meshb for
2438 the bynary format. Other extensions are not allowed.
2442 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2445 unRegister = genObjUnRegister()
2446 if isinstance( meshPart, list ):
2447 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2448 unRegister.set( meshPart )
2449 if isinstance( meshPart, Mesh ):
2450 meshPart = meshPart.mesh
2452 meshPart = self.mesh
2453 self.mesh.ExportGMF(meshPart, f, True)
2455 def ExportToMED(self, *args, **kwargs):
2457 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2458 Export the mesh in a file in MED format
2459 allowing to overwrite the file if it exists or add the exported data to its contents
2462 fileName: the file name
2463 opt (boolean): parameter for creating/not creating
2464 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2465 overwrite: boolean parameter for overwriting/not overwriting the file
2466 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2468 - 1D if all mesh nodes lie on OX coordinate axis, or
2469 - 2D if all mesh nodes lie on XOY coordinate plane, or
2470 - 3D in the rest cases.
2472 If **autoDimension** is *False*, the space dimension is always 3.
2475 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2476 # process positional arguments
2477 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2479 auto_groups = args[1] if len(args) > 1 else False
2480 overwrite = args[2] if len(args) > 2 else True
2481 autoDimension = args[3] if len(args) > 3 else True
2482 # process keywords arguments
2483 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2484 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2485 overwrite = kwargs.get("overwrite", overwrite)
2486 autoDimension = kwargs.get("autoDimension", autoDimension)
2488 # invoke engine's function
2489 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2491 def ExportToMEDX(self, *args, **kwargs):
2493 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2494 Export the mesh in a file in MED format
2497 fileName: the file name
2498 opt (boolean): parameter for creating/not creating
2499 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2500 overwrite: boolean parameter for overwriting/not overwriting the file
2501 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2503 - 1D if all mesh nodes lie on OX coordinate axis, or
2504 - 2D if all mesh nodes lie on XOY coordinate plane, or
2505 - 3D in the rest cases.
2507 If **autoDimension** is *False*, the space dimension is always 3.
2510 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2511 # process positional arguments
2512 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2514 auto_groups = args[1] if len(args) > 1 else False
2515 overwrite = args[2] if len(args) > 2 else True
2516 autoDimension = args[3] if len(args) > 3 else True
2517 # process keywords arguments
2518 auto_groups = kwargs.get("auto_groups", auto_groups)
2519 overwrite = kwargs.get("overwrite", overwrite)
2520 autoDimension = kwargs.get("autoDimension", autoDimension)
2522 # invoke engine's function
2523 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2527 def Append(self, meshes, uniteIdenticalGroups = True,
2528 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2530 Append given meshes into this mesh.
2531 All groups of input meshes will be created in this mesh.
2534 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2535 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2536 mergeNodesAndElements: if True, equal nodes and elements are merged
2537 mergeTolerance: tolerance for merging nodes
2538 allGroups: forces creation of groups corresponding to every input mesh
2540 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2541 mergeNodesAndElements, mergeTolerance, allGroups,
2542 meshToAppendTo = self.GetMesh() )
2544 # Operations with groups:
2545 # ----------------------
2546 def CreateEmptyGroup(self, elementType, name):
2548 Create an empty standalone mesh group
2551 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2552 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2553 name: the name of the mesh group
2556 :class:`SMESH.SMESH_Group`
2559 return self.mesh.CreateGroup(elementType, name)
2561 def Group(self, grp, name=""):
2563 Create a mesh group based on the geometric object *grp*
2564 and give it a *name*.
2565 If *name* is not defined the name of the geometric group is used
2568 Works like :meth:`GroupOnGeom`.
2571 grp: a geometric group, a vertex, an edge, a face or a solid
2572 name: the name of the mesh group
2575 :class:`SMESH.SMESH_GroupOnGeom`
2578 return self.GroupOnGeom(grp, name)
2580 def GroupOnGeom(self, grp, name="", typ=None):
2582 Create a mesh group based on the geometrical object *grp*
2583 and give it a *name*.
2584 if *name* is not defined the name of the geometric group is used
2587 grp: a geometrical group, a vertex, an edge, a face or a solid
2588 name: the name of the mesh group
2589 typ: the type of elements in the group; either of
2590 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2591 automatically detected by the type of the geometry
2594 :class:`SMESH.SMESH_GroupOnGeom`
2597 AssureGeomPublished( self, grp, name )
2599 name = grp.GetName()
2601 typ = self._groupTypeFromShape( grp )
2602 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2604 def _groupTypeFromShape( self, shape ):
2606 Pivate method to get a type of group on geometry
2608 tgeo = str(shape.GetShapeType())
2609 if tgeo == "VERTEX":
2611 elif tgeo == "EDGE":
2613 elif tgeo == "FACE" or tgeo == "SHELL":
2615 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2617 elif tgeo == "COMPOUND":
2618 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2620 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2621 return self._groupTypeFromShape( sub[0] )
2623 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2626 def GroupOnFilter(self, typ, name, filter):
2628 Create a mesh group with given *name* based on the *filter*.
2629 It is a special type of group dynamically updating it's contents during
2633 typ: the type of elements in the group; either of
2634 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2635 name: the name of the mesh group
2636 filter (SMESH.Filter): the filter defining group contents
2639 :class:`SMESH.SMESH_GroupOnFilter`
2642 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2644 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2646 Create a mesh group by the given ids of elements
2649 groupName: the name of the mesh group
2650 elementType: the type of elements in the group; either of
2651 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2652 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2655 :class:`SMESH.SMESH_Group`
2658 group = self.mesh.CreateGroup(elementType, groupName)
2659 if isinstance( elemIDs, Mesh ):
2660 elemIDs = elemIDs.GetMesh()
2661 if hasattr( elemIDs, "GetIDs" ):
2662 if hasattr( elemIDs, "SetMesh" ):
2663 elemIDs.SetMesh( self.GetMesh() )
2664 group.AddFrom( elemIDs )
2672 CritType=FT_Undefined,
2675 UnaryOp=FT_Undefined,
2678 Create a mesh group by the given conditions
2681 groupName: the name of the mesh group
2682 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2683 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2684 Note that the items starting from FT_LessThan are not suitable for CritType.
2685 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2686 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2687 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2688 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2689 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2692 :class:`SMESH.SMESH_GroupOnFilter`
2695 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2696 group = self.MakeGroupByCriterion(groupName, aCriterion)
2699 def MakeGroupByCriterion(self, groupName, Criterion):
2701 Create a mesh group by the given criterion
2704 groupName: the name of the mesh group
2705 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2708 :class:`SMESH.SMESH_GroupOnFilter`
2711 :meth:`smeshBuilder.GetCriterion`
2714 return self.MakeGroupByCriteria( groupName, [Criterion] )
2716 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2718 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2721 groupName: the name of the mesh group
2722 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2723 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2726 :class:`SMESH.SMESH_GroupOnFilter`
2729 :meth:`smeshBuilder.GetCriterion`
2732 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2733 group = self.MakeGroupByFilter(groupName, aFilter)
2736 def MakeGroupByFilter(self, groupName, theFilter):
2738 Create a mesh group by the given filter
2741 groupName (string): the name of the mesh group
2742 theFilter (SMESH.Filter): the filter
2745 :class:`SMESH.SMESH_GroupOnFilter`
2748 :meth:`smeshBuilder.GetFilter`
2751 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2752 #theFilter.SetMesh( self.mesh )
2753 #group.AddFrom( theFilter )
2754 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2757 def RemoveGroup(self, group):
2762 group (SMESH.SMESH_GroupBase): group to remove
2765 self.mesh.RemoveGroup(group)
2767 def RemoveGroupWithContents(self, group):
2769 Remove a group with its contents
2772 group (SMESH.SMESH_GroupBase): group to remove
2775 This operation can create gaps in numeration of nodes or elements.
2776 Call :meth:`RenumberElements` to remove the gaps.
2779 self.mesh.RemoveGroupWithContents(group)
2781 def GetGroups(self, elemType = SMESH.ALL):
2783 Get the list of groups existing in the mesh in the order of creation
2784 (starting from the oldest one)
2787 elemType (SMESH.ElementType): type of elements the groups contain;
2788 by default groups of elements of all types are returned
2791 a list of :class:`SMESH.SMESH_GroupBase`
2794 groups = self.mesh.GetGroups()
2795 if elemType == SMESH.ALL:
2799 if g.GetType() == elemType:
2800 typedGroups.append( g )
2807 Get the number of groups existing in the mesh
2810 the quantity of groups as an integer value
2813 return self.mesh.NbGroups()
2815 def GetGroupNames(self):
2817 Get the list of names of groups existing in the mesh
2823 groups = self.GetGroups()
2825 for group in groups:
2826 names.append(group.GetName())
2829 def GetGroupByName(self, name, elemType = None):
2831 Find groups by name and type
2834 name (string): name of the group of interest
2835 elemType (SMESH.ElementType): type of elements the groups contain;
2836 by default one group of any type is returned;
2837 if elemType == SMESH.ALL then all groups of any type are returned
2840 a list of :class:`SMESH.SMESH_GroupBase`
2844 for group in self.GetGroups():
2845 if group.GetName() == name:
2846 if elemType is None:
2848 if ( elemType == SMESH.ALL or
2849 group.GetType() == elemType ):
2850 groups.append( group )
2853 def UnionGroups(self, group1, group2, name):
2855 Produce a union of two groups.
2856 A new group is created. All mesh elements that are
2857 present in the initial groups are added to the new one
2860 group1 (SMESH.SMESH_GroupBase): a group
2861 group2 (SMESH.SMESH_GroupBase): another group
2864 instance of :class:`SMESH.SMESH_Group`
2867 return self.mesh.UnionGroups(group1, group2, name)
2869 def UnionListOfGroups(self, groups, name):
2871 Produce a union list of groups.
2872 New group is created. All mesh elements that are present in
2873 initial groups are added to the new one
2876 groups: list of :class:`SMESH.SMESH_GroupBase`
2879 instance of :class:`SMESH.SMESH_Group`
2881 return self.mesh.UnionListOfGroups(groups, name)
2883 def IntersectGroups(self, group1, group2, name):
2885 Prodice an intersection of two groups.
2886 A new group is created. All mesh elements that are common
2887 for the two initial groups are added to the new one.
2890 group1 (SMESH.SMESH_GroupBase): a group
2891 group2 (SMESH.SMESH_GroupBase): another group
2894 instance of :class:`SMESH.SMESH_Group`
2897 return self.mesh.IntersectGroups(group1, group2, name)
2899 def IntersectListOfGroups(self, groups, name):
2901 Produce an intersection of groups.
2902 New group is created. All mesh elements that are present in all
2903 initial groups simultaneously are added to the new one
2906 groups: a list of :class:`SMESH.SMESH_GroupBase`
2909 instance of :class:`SMESH.SMESH_Group`
2911 return self.mesh.IntersectListOfGroups(groups, name)
2913 def CutGroups(self, main_group, tool_group, name):
2915 Produce a cut of two groups.
2916 A new group is created. All mesh elements that are present in
2917 the main group but are not present in the tool group are added to the new one
2920 main_group (SMESH.SMESH_GroupBase): a group to cut from
2921 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2924 an instance of :class:`SMESH.SMESH_Group`
2927 return self.mesh.CutGroups(main_group, tool_group, name)
2929 def CutListOfGroups(self, main_groups, tool_groups, name):
2931 Produce a cut of groups.
2932 A new group is created. All mesh elements that are present in main groups
2933 but do not present in tool groups are added to the new one
2936 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2937 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2940 an instance of :class:`SMESH.SMESH_Group`
2943 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2945 def CreateDimGroup(self, groups, elemType, name,
2946 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2948 Create a standalone group of entities basing on nodes of other groups.
2951 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2952 elemType: a type of elements to include to the new group; either of
2953 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2954 name: a name of the new group.
2955 nbCommonNodes: a criterion of inclusion of an element to the new group
2956 basing on number of element nodes common with reference *groups*.
2957 Meaning of possible values are:
2959 - SMESH.ALL_NODES - include if all nodes are common,
2960 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2961 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2962 - SMEHS.MAJORITY - include if half of nodes or more are common.
2963 underlyingOnly: if *True* (default), an element is included to the
2964 new group provided that it is based on nodes of an element of *groups*;
2965 in this case the reference *groups* are supposed to be of higher dimension
2966 than *elemType*, which can be useful for example to get all faces lying on
2967 volumes of the reference *groups*.
2970 an instance of :class:`SMESH.SMESH_Group`
2973 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2975 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2977 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
2979 Distribute all faces of the mesh among groups using sharp edges and optionally
2980 existing 1D elements as group boundaries.
2983 sharpAngle: edge is considered sharp if an angle between normals of
2984 adjacent faces is more than \a sharpAngle in degrees.
2985 createEdges (boolean): to create 1D elements for detected sharp edges.
2986 useExistingEdges (boolean): to use existing edges as group boundaries
2988 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
2990 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
2991 self.mesh.SetParameters(Parameters)
2992 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
2994 def ConvertToStandalone(self, group):
2996 Convert group on geom into standalone group
2999 return self.mesh.ConvertToStandalone(group)
3001 # Get some info about mesh:
3002 # ------------------------
3004 def GetLog(self, clearAfterGet):
3006 Return the log of nodes and elements added or removed
3007 since the previous clear of the log.
3010 clearAfterGet: log is emptied after Get (safe if concurrents access)
3013 list of SMESH.log_block structures { commandType, number, coords, indexes }
3016 return self.mesh.GetLog(clearAfterGet)
3020 Clear the log of nodes and elements added or removed since the previous
3021 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3024 self.mesh.ClearLog()
3026 def SetAutoColor(self, theAutoColor):
3028 Toggle auto color mode on the object.
3029 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3032 theAutoColor (boolean): the flag which toggles auto color mode.
3035 self.mesh.SetAutoColor(theAutoColor)
3037 def GetAutoColor(self):
3039 Get flag of object auto color mode.
3045 return self.mesh.GetAutoColor()
3052 integer value, which is the internal Id of the mesh
3055 return self.mesh.GetId()
3057 def HasDuplicatedGroupNamesMED(self):
3059 Check the group names for duplications.
3060 Consider the maximum group name length stored in MED file.
3066 return self.mesh.HasDuplicatedGroupNamesMED()
3068 def GetMeshEditor(self):
3070 Obtain the mesh editor tool
3073 an instance of :class:`SMESH.SMESH_MeshEditor`
3078 def GetIDSource(self, ids, elemType = SMESH.ALL):
3080 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3081 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3085 elemType: type of elements; this parameter is used to distinguish
3086 IDs of nodes from IDs of elements; by default ids are treated as
3087 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3090 an instance of :class:`SMESH.SMESH_IDSource`
3093 call UnRegister() for the returned object as soon as it is no more useful::
3095 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3096 mesh.DoSomething( idSrc )
3100 if isinstance( ids, int ):
3102 return self.editor.MakeIDSource(ids, elemType)
3105 # Get information about mesh contents:
3106 # ------------------------------------
3108 def GetMeshInfo(self, obj = None):
3110 Get the mesh statistic.
3113 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3116 if not obj: obj = self.mesh
3117 return self.smeshpyD.GetMeshInfo(obj)
3121 Return the number of nodes in the mesh
3127 return self.mesh.NbNodes()
3129 def NbElements(self):
3131 Return the number of elements in the mesh
3137 return self.mesh.NbElements()
3139 def Nb0DElements(self):
3141 Return the number of 0d elements in the mesh
3147 return self.mesh.Nb0DElements()
3151 Return the number of ball discrete elements in the mesh
3157 return self.mesh.NbBalls()
3161 Return the number of edges in the mesh
3167 return self.mesh.NbEdges()
3169 def NbEdgesOfOrder(self, elementOrder):
3171 Return the number of edges with the given order in the mesh
3174 elementOrder: the order of elements
3175 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3181 return self.mesh.NbEdgesOfOrder(elementOrder)
3185 Return the number of faces in the mesh
3191 return self.mesh.NbFaces()
3193 def NbFacesOfOrder(self, elementOrder):
3195 Return the number of faces with the given order in the mesh
3198 elementOrder: the order of elements
3199 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3205 return self.mesh.NbFacesOfOrder(elementOrder)
3207 def NbTriangles(self):
3209 Return the number of triangles in the mesh
3215 return self.mesh.NbTriangles()
3217 def NbTrianglesOfOrder(self, elementOrder):
3219 Return the number of triangles with the given order in the mesh
3222 elementOrder: is the order of elements
3223 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3229 return self.mesh.NbTrianglesOfOrder(elementOrder)
3231 def NbBiQuadTriangles(self):
3233 Return the number of biquadratic triangles in the mesh
3239 return self.mesh.NbBiQuadTriangles()
3241 def NbQuadrangles(self):
3243 Return the number of quadrangles in the mesh
3249 return self.mesh.NbQuadrangles()
3251 def NbQuadranglesOfOrder(self, elementOrder):
3253 Return the number of quadrangles with the given order in the mesh
3256 elementOrder: the order of elements
3257 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3263 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3265 def NbBiQuadQuadrangles(self):
3267 Return the number of biquadratic quadrangles in the mesh
3273 return self.mesh.NbBiQuadQuadrangles()
3275 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3277 Return the number of polygons of given order in the mesh
3280 elementOrder: the order of elements
3281 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3287 return self.mesh.NbPolygonsOfOrder(elementOrder)
3289 def NbVolumes(self):
3291 Return the number of volumes in the mesh
3297 return self.mesh.NbVolumes()
3300 def NbVolumesOfOrder(self, elementOrder):
3302 Return the number of volumes with the given order in the mesh
3305 elementOrder: the order of elements
3306 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3312 return self.mesh.NbVolumesOfOrder(elementOrder)
3316 Return the number of tetrahedrons in the mesh
3322 return self.mesh.NbTetras()
3324 def NbTetrasOfOrder(self, elementOrder):
3326 Return the number of tetrahedrons with the given order in the mesh
3329 elementOrder: the order of elements
3330 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3336 return self.mesh.NbTetrasOfOrder(elementOrder)
3340 Return the number of hexahedrons in the mesh
3346 return self.mesh.NbHexas()
3348 def NbHexasOfOrder(self, elementOrder):
3350 Return the number of hexahedrons with the given order in the mesh
3353 elementOrder: the order of elements
3354 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3360 return self.mesh.NbHexasOfOrder(elementOrder)
3362 def NbTriQuadraticHexas(self):
3364 Return the number of triquadratic hexahedrons in the mesh
3370 return self.mesh.NbTriQuadraticHexas()
3372 def NbPyramids(self):
3374 Return the number of pyramids in the mesh
3380 return self.mesh.NbPyramids()
3382 def NbPyramidsOfOrder(self, elementOrder):
3384 Return the number of pyramids with the given order in the mesh
3387 elementOrder: the order of elements
3388 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3394 return self.mesh.NbPyramidsOfOrder(elementOrder)
3398 Return the number of prisms in the mesh
3404 return self.mesh.NbPrisms()
3406 def NbPrismsOfOrder(self, elementOrder):
3408 Return the number of prisms with the given order in the mesh
3411 elementOrder: the order of elements
3412 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3418 return self.mesh.NbPrismsOfOrder(elementOrder)
3420 def NbHexagonalPrisms(self):
3422 Return the number of hexagonal prisms in the mesh
3428 return self.mesh.NbHexagonalPrisms()
3430 def NbPolyhedrons(self):
3432 Return the number of polyhedrons in the mesh
3438 return self.mesh.NbPolyhedrons()
3440 def NbSubMesh(self):
3442 Return the number of submeshes in the mesh
3448 return self.mesh.NbSubMesh()
3450 def GetElementsId(self):
3452 Return the list of all mesh elements IDs
3455 the list of integer values
3458 :meth:`GetElementsByType`
3461 return self.mesh.GetElementsId()
3463 def GetElementsByType(self, elementType):
3465 Return the list of IDs of mesh elements with the given type
3468 elementType (SMESH.ElementType): the required type of elements
3471 list of integer values
3474 return self.mesh.GetElementsByType(elementType)
3476 def GetNodesId(self):
3478 Return the list of mesh nodes IDs
3481 the list of integer values
3484 return self.mesh.GetNodesId()
3486 # Get the information about mesh elements:
3487 # ------------------------------------
3489 def GetElementType(self, id, iselem=True):
3491 Return the type of mesh element or node
3494 the value from :class:`SMESH.ElementType` enumeration.
3495 Return SMESH.ALL if element or node with the given ID does not exist
3498 return self.mesh.GetElementType(id, iselem)
3500 def GetElementGeomType(self, id):
3502 Return the geometric type of mesh element
3505 the value from :class:`SMESH.EntityType` enumeration.
3508 return self.mesh.GetElementGeomType(id)
3510 def GetElementShape(self, id):
3512 Return the shape type of mesh element
3515 the value from :class:`SMESH.GeometryType` enumeration.
3518 return self.mesh.GetElementShape(id)
3520 def GetSubMeshElementsId(self, Shape):
3522 Return the list of sub-mesh elements IDs
3525 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3526 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3529 list of integer values
3532 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3533 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3536 return self.mesh.GetSubMeshElementsId(ShapeID)
3538 def GetSubMeshNodesId(self, Shape, all):
3540 Return the list of sub-mesh nodes IDs
3543 Shape: a geom object (sub-shape).
3544 *Shape* must be the sub-shape of a :meth:`GetShape`
3545 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3548 list of integer values
3551 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3552 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3555 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3557 def GetSubMeshElementType(self, Shape):
3559 Return type of elements on given shape
3562 Shape: a geom object (sub-shape).
3563 *Shape* must be a sub-shape of a ShapeToMesh()
3566 :class:`SMESH.ElementType`
3569 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3570 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3573 return self.mesh.GetSubMeshElementType(ShapeID)
3577 Get the mesh description
3583 return self.mesh.Dump()
3586 # Get the information about nodes and elements of a mesh by its IDs:
3587 # -----------------------------------------------------------
3589 def GetNodeXYZ(self, id):
3591 Get XYZ coordinates of a node.
3592 If there is no node for the given ID - return an empty list
3595 list of float values
3598 return self.mesh.GetNodeXYZ(id)
3600 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3602 Return list of IDs of inverse elements for the given node.
3603 If there is no node for the given ID - return an empty list
3607 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3610 list of integer values
3613 return self.mesh.GetNodeInverseElements(id,elemType)
3615 def GetNodePosition(self,NodeID):
3617 Return the position of a node on the shape
3620 :class:`SMESH.NodePosition`
3623 return self.mesh.GetNodePosition(NodeID)
3625 def GetElementPosition(self,ElemID):
3627 Return the position of an element on the shape
3630 :class:`SMESH.ElementPosition`
3633 return self.mesh.GetElementPosition(ElemID)
3635 def GetShapeID(self, id):
3637 Return the ID of the shape, on which the given node was generated.
3640 an integer value > 0 or -1 if there is no node for the given
3641 ID or the node is not assigned to any geometry
3644 return self.mesh.GetShapeID(id)
3646 def GetShapeIDForElem(self,id):
3648 Return the ID of the shape, on which the given element was generated.
3651 an integer value > 0 or -1 if there is no element for the given
3652 ID or the element is not assigned to any geometry
3655 return self.mesh.GetShapeIDForElem(id)
3657 def GetElemNbNodes(self, id):
3659 Return the number of nodes of the given element
3662 an integer value > 0 or -1 if there is no element for the given ID
3665 return self.mesh.GetElemNbNodes(id)
3667 def GetElemNode(self, id, index):
3669 Return the node ID the given (zero based) index for the given element.
3671 * If there is no element for the given ID - return -1.
3672 * If there is no node for the given index - return -2.
3675 id (int): element ID
3676 index (int): node index within the element
3679 an integer value (ID)
3682 :meth:`GetElemNodes`
3685 return self.mesh.GetElemNode(id, index)
3687 def GetElemNodes(self, id):
3689 Return the IDs of nodes of the given element
3692 a list of integer values
3695 return self.mesh.GetElemNodes(id)
3697 def IsMediumNode(self, elementID, nodeID):
3699 Return true if the given node is the medium node in the given quadratic element
3702 return self.mesh.IsMediumNode(elementID, nodeID)
3704 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3706 Return true if the given node is the medium node in one of quadratic elements
3709 nodeID: ID of the node
3710 elementType: the type of elements to check a state of the node, either of
3711 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3714 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3716 def ElemNbEdges(self, id):
3718 Return the number of edges for the given element
3721 return self.mesh.ElemNbEdges(id)
3723 def ElemNbFaces(self, id):
3725 Return the number of faces for the given element
3728 return self.mesh.ElemNbFaces(id)
3730 def GetElemFaceNodes(self,elemId, faceIndex):
3732 Return nodes of given face (counted from zero) for given volumic element.
3735 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3737 def GetFaceNormal(self, faceId, normalized=False):
3739 Return three components of normal of given mesh face
3740 (or an empty array in KO case)
3743 return self.mesh.GetFaceNormal(faceId,normalized)
3745 def FindElementByNodes(self, nodes):
3747 Return an element based on all given nodes.
3750 return self.mesh.FindElementByNodes(nodes)
3752 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3754 Return elements including all given nodes.
3757 return self.mesh.GetElementsByNodes( nodes, elemType )
3759 def IsPoly(self, id):
3761 Return true if the given element is a polygon
3764 return self.mesh.IsPoly(id)
3766 def IsQuadratic(self, id):
3768 Return true if the given element is quadratic
3771 return self.mesh.IsQuadratic(id)
3773 def GetBallDiameter(self, id):
3775 Return diameter of a ball discrete element or zero in case of an invalid *id*
3778 return self.mesh.GetBallDiameter(id)
3780 def BaryCenter(self, id):
3782 Return XYZ coordinates of the barycenter of the given element.
3783 If there is no element for the given ID - return an empty list
3786 a list of three double values
3789 :meth:`smeshBuilder.GetGravityCenter`
3792 return self.mesh.BaryCenter(id)
3794 def GetIdsFromFilter(self, filter, meshParts=[] ):
3796 Pass mesh elements through the given filter and return IDs of fitting elements
3799 filter: :class:`SMESH.Filter`
3800 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3806 :meth:`SMESH.Filter.GetIDs`
3807 :meth:`SMESH.Filter.GetElementsIdFromParts`
3810 filter.SetMesh( self.mesh )
3813 if isinstance( meshParts, Mesh ):
3814 filter.SetMesh( meshParts.GetMesh() )
3815 return theFilter.GetIDs()
3816 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3817 meshParts = [ meshParts ]
3818 return filter.GetElementsIdFromParts( meshParts )
3820 return filter.GetIDs()
3822 # Get mesh measurements information:
3823 # ------------------------------------
3825 def GetFreeBorders(self):
3827 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3828 Return a list of special structures (borders).
3831 a list of :class:`SMESH.FreeEdges.Border`
3834 aFilterMgr = self.smeshpyD.CreateFilterManager()
3835 aPredicate = aFilterMgr.CreateFreeEdges()
3836 aPredicate.SetMesh(self.mesh)
3837 aBorders = aPredicate.GetBorders()
3838 aFilterMgr.UnRegister()
3841 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3843 Get minimum distance between two nodes, elements or distance to the origin
3846 id1: first node/element id
3847 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3848 isElem1: *True* if *id1* is element id, *False* if it is node id
3849 isElem2: *True* if *id2* is element id, *False* if it is node id
3852 minimum distance value
3854 :meth:`GetMinDistance`
3857 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3858 return aMeasure.value
3860 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3862 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3865 id1: first node/element id
3866 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3867 isElem1: *True* if *id1* is element id, *False* if it is node id
3868 isElem2: *True* if *id2* is element id, *False* if it is node id
3871 :class:`SMESH.Measure` structure
3877 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3879 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3882 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3884 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3889 aMeasurements = self.smeshpyD.CreateMeasurements()
3890 aMeasure = aMeasurements.MinDistance(id1, id2)
3891 genObjUnRegister([aMeasurements,id1, id2])
3894 def BoundingBox(self, objects=None, isElem=False):
3896 Get bounding box of the specified object(s)
3899 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3900 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3901 *False* specifies that *objects* are nodes
3904 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3907 :meth:`GetBoundingBox()`
3910 result = self.GetBoundingBox(objects, isElem)
3914 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3917 def GetBoundingBox(self, objects=None, isElem=False):
3919 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3922 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3923 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3924 False means that *objects* are nodes
3927 :class:`SMESH.Measure` structure
3930 :meth:`BoundingBox()`
3934 objects = [self.mesh]
3935 elif isinstance(objects, tuple):
3936 objects = list(objects)
3937 if not isinstance(objects, list):
3939 if len(objects) > 0 and isinstance(objects[0], int):
3942 unRegister = genObjUnRegister()
3944 if isinstance(o, Mesh):
3945 srclist.append(o.mesh)
3946 elif hasattr(o, "_narrow"):
3947 src = o._narrow(SMESH.SMESH_IDSource)
3948 if src: srclist.append(src)
3950 elif isinstance(o, list):
3952 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3954 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3955 unRegister.set( srclist[-1] )
3958 aMeasurements = self.smeshpyD.CreateMeasurements()
3959 unRegister.set( aMeasurements )
3960 aMeasure = aMeasurements.BoundingBox(srclist)
3963 # Mesh edition (SMESH_MeshEditor functionality):
3964 # ---------------------------------------------
3966 def RemoveElements(self, IDsOfElements):
3968 Remove the elements from the mesh by ids
3971 IDsOfElements: is a list of ids of elements to remove
3977 This operation can create gaps in numeration of elements.
3978 Call :meth:`RenumberElements` to remove the gaps.
3981 return self.editor.RemoveElements(IDsOfElements)
3983 def RemoveNodes(self, IDsOfNodes):
3985 Remove nodes from mesh by ids
3988 IDsOfNodes: is a list of ids of nodes to remove
3994 This operation can create gaps in numeration of nodes.
3995 Call :meth:`RenumberElements` to remove the gaps.
3998 return self.editor.RemoveNodes(IDsOfNodes)
4000 def RemoveOrphanNodes(self):
4002 Remove all orphan (free) nodes from mesh
4005 number of the removed nodes
4008 This operation can create gaps in numeration of nodes.
4009 Call :meth:`RenumberElements` to remove the gaps.
4012 return self.editor.RemoveOrphanNodes()
4014 def AddNode(self, x, y, z):
4016 Add a node to the mesh by coordinates
4022 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4023 if hasVars: self.mesh.SetParameters(Parameters)
4024 return self.editor.AddNode( x, y, z)
4026 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4028 Create a 0D element on a node with given number.
4031 IDOfNode: the ID of node for creation of the element.
4032 DuplicateElements: to add one more 0D element to a node or not
4035 ID of the new 0D element
4038 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4040 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4042 Create 0D elements on all nodes of the given elements except those
4043 nodes on which a 0D element already exists.
4046 theObject: an object on whose nodes 0D elements will be created.
4047 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4048 theGroupName: optional name of a group to add 0D elements created
4049 and/or found on nodes of *theObject*.
4050 DuplicateElements: to add one more 0D element to a node or not
4053 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4054 IDs of new and/or found 0D elements. IDs of 0D elements
4055 can be retrieved from the returned object by
4056 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4059 unRegister = genObjUnRegister()
4060 if isinstance( theObject, Mesh ):
4061 theObject = theObject.GetMesh()
4062 elif isinstance( theObject, list ):
4063 theObject = self.GetIDSource( theObject, SMESH.ALL )
4064 unRegister.set( theObject )
4065 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4067 def AddBall(self, IDOfNode, diameter):
4069 Create a ball element on a node with given ID.
4072 IDOfNode: the ID of node for creation of the element.
4073 diameter: the bal diameter.
4076 ID of the new ball element
4079 return self.editor.AddBall( IDOfNode, diameter )
4081 def AddEdge(self, IDsOfNodes):
4083 Create a linear or quadratic edge (this is determined
4084 by the number of given nodes).
4087 IDsOfNodes: list of node IDs for creation of the element.
4088 The order of nodes in this list should correspond to
4089 the :ref:`connectivity convention <connectivity_page>`.
4095 return self.editor.AddEdge(IDsOfNodes)
4097 def AddFace(self, IDsOfNodes):
4099 Create a linear or quadratic face (this is determined
4100 by the number of given nodes).
4103 IDsOfNodes: list of node IDs for creation of the element.
4104 The order of nodes in this list should correspond to
4105 the :ref:`connectivity convention <connectivity_page>`.
4111 return self.editor.AddFace(IDsOfNodes)
4113 def AddPolygonalFace(self, IdsOfNodes):
4115 Add a polygonal face defined by a list of node IDs
4118 IdsOfNodes: the list of node IDs for creation of the element.
4124 return self.editor.AddPolygonalFace(IdsOfNodes)
4126 def AddQuadPolygonalFace(self, IdsOfNodes):
4128 Add a quadratic polygonal face defined by a list of node IDs
4131 IdsOfNodes: the list of node IDs for creation of the element;
4132 corner nodes follow first.
4138 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4140 def AddVolume(self, IDsOfNodes):
4142 Create both simple and quadratic volume (this is determined
4143 by the number of given nodes).
4146 IDsOfNodes: list of node IDs for creation of the element.
4147 The order of nodes in this list should correspond to
4148 the :ref:`connectivity convention <connectivity_page>`.
4151 ID of the new volumic element
4154 return self.editor.AddVolume(IDsOfNodes)
4156 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4158 Create a volume of many faces, giving nodes for each face.
4161 IdsOfNodes: list of node IDs for volume creation, face by face.
4162 Quantities: list of integer values, Quantities[i]
4163 gives the quantity of nodes in face number i.
4166 ID of the new volumic element
4169 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4171 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4173 Create a volume of many faces, giving the IDs of the existing faces.
4176 The created volume will refer only to the nodes
4177 of the given faces, not to the faces themselves.
4180 IdsOfFaces: the list of face IDs for volume creation.
4183 ID of the new volumic element
4186 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4189 def SetNodeOnVertex(self, NodeID, Vertex):
4191 Bind a node to a vertex
4195 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4198 True if succeed else raises an exception
4201 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4202 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4206 self.editor.SetNodeOnVertex(NodeID, VertexID)
4207 except SALOME.SALOME_Exception as inst:
4208 raise ValueError(inst.details.text)
4212 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4214 Store the node position on an edge
4218 Edge: an edge (GEOM.GEOM_Object) or edge ID
4219 paramOnEdge: a parameter on the edge where the node is located
4222 True if succeed else raises an exception
4225 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4226 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4230 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4231 except SALOME.SALOME_Exception as inst:
4232 raise ValueError(inst.details.text)
4235 def SetNodeOnFace(self, NodeID, Face, u, v):
4237 Store node position on a face
4241 Face: a face (GEOM.GEOM_Object) or face ID
4242 u: U parameter on the face where the node is located
4243 v: V parameter on the face where the node is located
4246 True if succeed else raises an exception
4249 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4250 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4254 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4255 except SALOME.SALOME_Exception as inst:
4256 raise ValueError(inst.details.text)
4259 def SetNodeInVolume(self, NodeID, Solid):
4261 Bind a node to a solid
4265 Solid: a solid (GEOM.GEOM_Object) or solid ID
4268 True if succeed else raises an exception
4271 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4272 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4276 self.editor.SetNodeInVolume(NodeID, SolidID)
4277 except SALOME.SALOME_Exception as inst:
4278 raise ValueError(inst.details.text)
4281 def SetMeshElementOnShape(self, ElementID, Shape):
4283 Bind an element to a shape
4286 ElementID: an element ID
4287 Shape: a shape (GEOM.GEOM_Object) or shape ID
4290 True if succeed else raises an exception
4293 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4294 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4298 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4299 except SALOME.SALOME_Exception as inst:
4300 raise ValueError(inst.details.text)
4304 def MoveNode(self, NodeID, x, y, z):
4306 Move the node with the given id
4309 NodeID: the id of the node
4310 x: a new X coordinate
4311 y: a new Y coordinate
4312 z: a new Z coordinate
4315 True if succeed else False
4318 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4319 if hasVars: self.mesh.SetParameters(Parameters)
4320 return self.editor.MoveNode(NodeID, x, y, z)
4322 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4324 Find the node closest to a point and moves it to a point location
4327 x: the X coordinate of a point
4328 y: the Y coordinate of a point
4329 z: the Z coordinate of a point
4330 NodeID: if specified (>0), the node with this ID is moved,
4331 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4334 the ID of a moved node
4337 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4338 if hasVars: self.mesh.SetParameters(Parameters)
4339 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4341 def FindNodeClosestTo(self, x, y, z):
4343 Find the node closest to a point
4346 x: the X coordinate of a point
4347 y: the Y coordinate of a point
4348 z: the Z coordinate of a point
4354 return self.editor.FindNodeClosestTo(x, y, z)
4356 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4358 Find the elements where a point lays IN or ON
4361 x,y,z (float): coordinates of the point
4362 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4363 means elements of any type excluding nodes, discrete and 0D elements.
4364 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4367 list of IDs of found elements
4370 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4372 return self.editor.FindElementsByPoint(x, y, z, elementType)
4374 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4376 Project a point to a mesh object.
4377 Return ID of an element of given type where the given point is projected
4378 and coordinates of the projection point.
4379 In the case if nothing found, return -1 and []
4381 if isinstance( meshObject, Mesh ):
4382 meshObject = meshObject.GetMesh()
4384 meshObject = self.GetMesh()
4385 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4387 def GetPointState(self, x, y, z):
4389 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4390 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4391 UNKNOWN state means that either mesh is wrong or the analysis fails.
4394 return self.editor.GetPointState(x, y, z)
4396 def IsManifold(self):
4398 Check if a 2D mesh is manifold
4401 return self.editor.IsManifold()
4403 def IsCoherentOrientation2D(self):
4405 Check if orientation of 2D elements is coherent
4408 return self.editor.IsCoherentOrientation2D()
4410 def Get1DBranches( self, edges, startNode = 0 ):
4412 Partition given 1D elements into groups of contiguous edges.
4413 A node where number of meeting edges != 2 is a group end.
4414 An optional startNode is used to orient groups it belongs to.
4417 A list of edge groups and a list of corresponding node groups,
4418 where the group is a list of IDs of edges or elements, like follows
4419 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4420 If a group is closed, the first and last nodes of the group are same.
4422 if isinstance( edges, Mesh ):
4423 edges = edges.GetMesh()
4424 unRegister = genObjUnRegister()
4425 if isinstance( edges, list ):
4426 edges = self.GetIDSource( edges, SMESH.EDGE )
4427 unRegister.set( edges )
4428 return self.editor.Get1DBranches( edges, startNode )
4430 def FindSharpEdges( self, angle, addExisting=False ):
4432 Return sharp edges of faces and non-manifold ones.
4433 Optionally add existing edges.
4436 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4437 addExisting: to return existing edges (1D elements) as well
4440 list of FaceEdge structures
4442 angle = ParseParameters( angle )[0]
4443 return self.editor.FindSharpEdges( angle, addExisting )
4445 def MeshToPassThroughAPoint(self, x, y, z):
4447 Find the node closest to a point and moves it to a point location
4450 x: the X coordinate of a point
4451 y: the Y coordinate of a point
4452 z: the Z coordinate of a point
4455 the ID of a moved node
4458 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4460 def InverseDiag(self, NodeID1, NodeID2):
4462 Replace two neighbour triangles sharing Node1-Node2 link
4463 with the triangles built on the same 4 nodes but having other common link.
4466 NodeID1: the ID of the first node
4467 NodeID2: the ID of the second node
4470 False if proper faces were not found
4472 return self.editor.InverseDiag(NodeID1, NodeID2)
4474 def DeleteDiag(self, NodeID1, NodeID2):
4476 Replace two neighbour triangles sharing *Node1-Node2* link
4477 with a quadrangle built on the same 4 nodes.
4480 NodeID1: ID of the first node
4481 NodeID2: ID of the second node
4484 False if proper faces were not found
4487 This operation can create gaps in numeration of elements.
4488 Call :meth:`RenumberElements` to remove the gaps.
4491 return self.editor.DeleteDiag(NodeID1, NodeID2)
4493 def Reorient(self, IDsOfElements=None):
4495 Reorient elements by ids
4498 IDsOfElements: if undefined reorients all mesh elements
4501 True if succeed else False
4504 if IDsOfElements == None:
4505 IDsOfElements = self.GetElementsId()
4506 return self.editor.Reorient(IDsOfElements)
4508 def ReorientObject(self, theObject):
4510 Reorient all elements of the object
4513 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4516 True if succeed else False
4519 if ( isinstance( theObject, Mesh )):
4520 theObject = theObject.GetMesh()
4521 return self.editor.ReorientObject(theObject)
4523 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4525 Reorient faces contained in *the2DObject*.
4528 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4529 theDirection: a desired direction of normal of *theFace*.
4530 It can be either a GEOM vector or a list of coordinates [x,y,z].
4531 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4532 compared with theDirection. It can be either ID of face or a point
4533 by which the face will be found. The point can be given as either
4534 a GEOM vertex or a list of point coordinates.
4537 number of reoriented faces
4540 unRegister = genObjUnRegister()
4542 if isinstance( the2DObject, Mesh ):
4543 the2DObject = the2DObject.GetMesh()
4544 if isinstance( the2DObject, list ):
4545 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4546 unRegister.set( the2DObject )
4547 # check theDirection
4548 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4549 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4550 if isinstance( theDirection, list ):
4551 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4552 # prepare theFace and thePoint
4553 theFace = theFaceOrPoint
4554 thePoint = PointStruct(0,0,0)
4555 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4556 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4558 if isinstance( theFaceOrPoint, list ):
4559 thePoint = PointStruct( *theFaceOrPoint )
4561 if isinstance( theFaceOrPoint, PointStruct ):
4562 thePoint = theFaceOrPoint
4564 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4566 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4568 Reorient faces according to adjacent volumes.
4571 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4572 either IDs of faces or face groups.
4573 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4574 theOutsideNormal: to orient faces to have their normals
4575 pointing either *outside* or *inside* the adjacent volumes.
4578 number of reoriented faces.
4581 unRegister = genObjUnRegister()
4583 if not isinstance( the2DObject, list ):
4584 the2DObject = [ the2DObject ]
4585 elif the2DObject and isinstance( the2DObject[0], int ):
4586 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4587 unRegister.set( the2DObject )
4588 the2DObject = [ the2DObject ]
4589 for i,obj2D in enumerate( the2DObject ):
4590 if isinstance( obj2D, Mesh ):
4591 the2DObject[i] = obj2D.GetMesh()
4592 if isinstance( obj2D, list ):
4593 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4594 unRegister.set( the2DObject[i] )
4596 if isinstance( the3DObject, Mesh ):
4597 the3DObject = the3DObject.GetMesh()
4598 if isinstance( the3DObject, list ):
4599 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4600 unRegister.set( the3DObject )
4601 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4603 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4605 Fuse the neighbouring triangles into quadrangles.
4608 IDsOfElements: The triangles to be fused.
4609 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4610 applied to possible quadrangles to choose a neighbour to fuse with.
4611 Note that not all items of :class:`SMESH.FunctorType` corresponds
4612 to numerical functors.
4613 MaxAngle: is the maximum angle between element normals at which the fusion
4614 is still performed; theMaxAngle is measured in radians.
4615 Also it could be a name of variable which defines angle in degrees.
4618 True in case of success, False otherwise.
4621 This operation can create gaps in numeration of elements.
4622 Call :meth:`RenumberElements` to remove the gaps.
4625 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4626 self.mesh.SetParameters(Parameters)
4627 if not IDsOfElements:
4628 IDsOfElements = self.GetElementsId()
4629 Functor = self.smeshpyD.GetFunctor(theCriterion)
4630 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4632 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4634 Fuse the neighbouring triangles of the object into quadrangles
4637 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4638 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4639 applied to possible quadrangles to choose a neighbour to fuse with.
4640 Note that not all items of :class:`SMESH.FunctorType` corresponds
4641 to numerical functors.
4642 MaxAngle: a max angle between element normals at which the fusion
4643 is still performed; theMaxAngle is measured in radians.
4646 True in case of success, False otherwise.
4649 This operation can create gaps in numeration of elements.
4650 Call :meth:`RenumberElements` to remove the gaps.
4653 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4654 self.mesh.SetParameters(Parameters)
4655 if isinstance( theObject, Mesh ):
4656 theObject = theObject.GetMesh()
4657 Functor = self.smeshpyD.GetFunctor(theCriterion)
4658 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4660 def QuadToTri (self, IDsOfElements, theCriterion = None):
4662 Split quadrangles into triangles.
4665 IDsOfElements: the faces to be splitted.
4666 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4667 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4668 value, then quadrangles will be split by the smallest diagonal.
4669 Note that not all items of :class:`SMESH.FunctorType` corresponds
4670 to numerical functors.
4673 True in case of success, False otherwise.
4676 This operation can create gaps in numeration of elements.
4677 Call :meth:`RenumberElements` to remove the gaps.
4679 if IDsOfElements == []:
4680 IDsOfElements = self.GetElementsId()
4681 if theCriterion is None:
4682 theCriterion = FT_MaxElementLength2D
4683 Functor = self.smeshpyD.GetFunctor(theCriterion)
4684 return self.editor.QuadToTri(IDsOfElements, Functor)
4686 def QuadToTriObject (self, theObject, theCriterion = None):
4688 Split quadrangles into triangles.
4691 theObject: the object from which the list of elements is taken,
4692 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4693 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4694 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4695 value, then quadrangles will be split by the smallest diagonal.
4696 Note that not all items of :class:`SMESH.FunctorType` corresponds
4697 to numerical functors.
4700 True in case of success, False otherwise.
4703 This operation can create gaps in numeration of elements.
4704 Call :meth:`RenumberElements` to remove the gaps.
4706 if ( isinstance( theObject, Mesh )):
4707 theObject = theObject.GetMesh()
4708 if theCriterion is None:
4709 theCriterion = FT_MaxElementLength2D
4710 Functor = self.smeshpyD.GetFunctor(theCriterion)
4711 return self.editor.QuadToTriObject(theObject, Functor)
4713 def QuadTo4Tri (self, theElements=[]):
4715 Split each of given quadrangles into 4 triangles. A node is added at the center of
4719 theElements: the faces to be splitted. This can be either
4720 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4721 or a list of face IDs. By default all quadrangles are split
4724 This operation can create gaps in numeration of elements.
4725 Call :meth:`RenumberElements` to remove the gaps.
4727 unRegister = genObjUnRegister()
4728 if isinstance( theElements, Mesh ):
4729 theElements = theElements.mesh
4730 elif not theElements:
4731 theElements = self.mesh
4732 elif isinstance( theElements, list ):
4733 theElements = self.GetIDSource( theElements, SMESH.FACE )
4734 unRegister.set( theElements )
4735 return self.editor.QuadTo4Tri( theElements )
4737 def SplitQuad (self, IDsOfElements, Diag13):
4739 Split quadrangles into triangles.
4742 IDsOfElements: the faces to be splitted
4743 Diag13 (boolean): is used to choose a diagonal for splitting.
4746 True in case of success, False otherwise.
4749 This operation can create gaps in numeration of elements.
4750 Call :meth:`RenumberElements` to remove the gaps.
4752 if IDsOfElements == []:
4753 IDsOfElements = self.GetElementsId()
4754 return self.editor.SplitQuad(IDsOfElements, Diag13)
4756 def SplitQuadObject (self, theObject, Diag13):
4758 Split quadrangles into triangles.
4761 theObject: the object from which the list of elements is taken,
4762 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4763 Diag13 (boolean): is used to choose a diagonal for splitting.
4766 True in case of success, False otherwise.
4769 This operation can create gaps in numeration of elements.
4770 Call :meth:`RenumberElements` to remove the gaps.
4772 if ( isinstance( theObject, Mesh )):
4773 theObject = theObject.GetMesh()
4774 return self.editor.SplitQuadObject(theObject, Diag13)
4776 def BestSplit (self, IDOfQuad, theCriterion):
4778 Find a better splitting of the given quadrangle.
4781 IDOfQuad: the ID of the quadrangle to be splitted.
4782 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4783 choose a diagonal for splitting.
4784 Note that not all items of :class:`SMESH.FunctorType` corresponds
4785 to numerical functors.
4788 * 1 if 1-3 diagonal is better,
4789 * 2 if 2-4 diagonal is better,
4790 * 0 if error occurs.
4793 This operation can create gaps in numeration of elements.
4794 Call :meth:`RenumberElements` to remove the gaps.
4796 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4798 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4800 Split volumic elements into tetrahedrons
4803 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4804 method: flags passing splitting method:
4805 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4806 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4809 This operation can create gaps in numeration of elements.
4810 Call :meth:`RenumberElements` to remove the gaps.
4812 unRegister = genObjUnRegister()
4813 if isinstance( elems, Mesh ):
4814 elems = elems.GetMesh()
4815 if ( isinstance( elems, list )):
4816 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4817 unRegister.set( elems )
4818 self.editor.SplitVolumesIntoTetra(elems, method)
4821 def SplitBiQuadraticIntoLinear(self, elems=None):
4823 Split bi-quadratic elements into linear ones without creation of additional nodes:
4825 - bi-quadratic triangle will be split into 3 linear quadrangles;
4826 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4827 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4829 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4830 will be split in order to keep the mesh conformal.
4833 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4834 if None (default), all bi-quadratic elements will be split
4837 This operation can create gaps in numeration of elements.
4838 Call :meth:`RenumberElements` to remove the gaps.
4840 unRegister = genObjUnRegister()
4841 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4842 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4843 unRegister.set( elems )
4845 elems = [ self.GetMesh() ]
4846 if isinstance( elems, Mesh ):
4847 elems = [ elems.GetMesh() ]
4848 if not isinstance( elems, list ):
4850 self.editor.SplitBiQuadraticIntoLinear( elems )
4852 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4853 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4855 Split hexahedra into prisms
4858 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4859 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4860 gives a normal vector defining facets to split into triangles.
4861 *startHexPoint* can be either a triple of coordinates or a vertex.
4862 facetNormal: a normal to a facet to split into triangles of a
4863 hexahedron found by *startHexPoint*.
4864 *facetNormal* can be either a triple of coordinates or an edge.
4865 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4866 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4867 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4868 to *startHexPoint* are split, else *startHexPoint*
4869 is used to find the facet to split in all domains present in *elems*.
4872 This operation can create gaps in numeration of elements.
4873 Call :meth:`RenumberElements` to remove the gaps.
4876 unRegister = genObjUnRegister()
4877 if isinstance( elems, Mesh ):
4878 elems = elems.GetMesh()
4879 if ( isinstance( elems, list )):
4880 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4881 unRegister.set( elems )
4884 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4885 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4886 elif isinstance( startHexPoint, list ):
4887 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4890 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4891 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4892 elif isinstance( facetNormal, list ):
4893 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4896 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4898 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4900 def SplitQuadsNearTriangularFacets(self):
4902 Split quadrangle faces near triangular facets of volumes
4905 This operation can create gaps in numeration of elements.
4906 Call :meth:`RenumberElements` to remove the gaps.
4908 faces_array = self.GetElementsByType(SMESH.FACE)
4909 for face_id in faces_array:
4910 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4911 quad_nodes = self.mesh.GetElemNodes(face_id)
4912 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4913 isVolumeFound = False
4914 for node1_elem in node1_elems:
4915 if not isVolumeFound:
4916 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4917 nb_nodes = self.GetElemNbNodes(node1_elem)
4918 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4919 volume_elem = node1_elem
4920 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4921 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4922 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4923 isVolumeFound = True
4924 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4925 self.SplitQuad([face_id], False) # diagonal 2-4
4926 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4927 isVolumeFound = True
4928 self.SplitQuad([face_id], True) # diagonal 1-3
4929 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4930 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4931 isVolumeFound = True
4932 self.SplitQuad([face_id], True) # diagonal 1-3
4934 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4936 Split hexahedrons into tetrahedrons.
4938 This operation uses :doc:`pattern_mapping` functionality for splitting.
4941 theObject: the object from which the list of hexahedrons is taken;
4942 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4943 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4944 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4945 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4946 key-point will be mapped into *theNode001*-th node of each volume.
4947 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4950 True in case of success, False otherwise.
4953 This operation can create gaps in numeration of elements.
4954 Call :meth:`RenumberElements` to remove the gaps.
4962 # (0,0,1) 4.---------.7 * |
4969 # (0,0,0) 0.---------.3
4970 pattern_tetra = "!!! Nb of points: \n 8 \n\
4980 !!! Indices of points of 6 tetras: \n\
4988 pattern = self.smeshpyD.GetPattern()
4989 isDone = pattern.LoadFromFile(pattern_tetra)
4991 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4994 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4995 isDone = pattern.MakeMesh(self.mesh, False, False)
4996 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4998 # split quafrangle faces near triangular facets of volumes
4999 self.SplitQuadsNearTriangularFacets()
5003 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5005 Split hexahedrons into prisms.
5007 Uses the :doc:`pattern_mapping` functionality for splitting.
5010 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5011 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5012 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5013 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5014 will be mapped into the *theNode001* -th node of each volume.
5015 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5018 True in case of success, False otherwise.
5021 This operation can create gaps in numeration of elements.
5022 Call :meth:`RenumberElements` to remove the gaps.
5024 # Pattern: 5.---------.6
5029 # (0,0,1) 4.---------.7 |
5036 # (0,0,0) 0.---------.3
5037 pattern_prism = "!!! Nb of points: \n 8 \n\
5047 !!! Indices of points of 2 prisms: \n\
5051 pattern = self.smeshpyD.GetPattern()
5052 isDone = pattern.LoadFromFile(pattern_prism)
5054 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5057 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5058 isDone = pattern.MakeMesh(self.mesh, False, False)
5059 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5061 # Split quafrangle faces near triangular facets of volumes
5062 self.SplitQuadsNearTriangularFacets()
5066 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5067 MaxNbOfIterations, MaxAspectRatio, Method):
5072 IDsOfElements: the list if ids of elements to smooth
5073 IDsOfFixedNodes: the list of ids of fixed nodes.
5074 Note that nodes built on edges and boundary nodes are always fixed.
5075 MaxNbOfIterations: the maximum number of iterations
5076 MaxAspectRatio: varies in range [1.0, inf]
5077 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5078 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5081 True in case of success, False otherwise.
5084 if IDsOfElements == []:
5085 IDsOfElements = self.GetElementsId()
5086 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5087 self.mesh.SetParameters(Parameters)
5088 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5089 MaxNbOfIterations, MaxAspectRatio, Method)
5091 def SmoothObject(self, theObject, IDsOfFixedNodes,
5092 MaxNbOfIterations, MaxAspectRatio, Method):
5094 Smooth elements which belong to the given object
5097 theObject: the object to smooth
5098 IDsOfFixedNodes: the list of ids of fixed nodes.
5099 Note that nodes built on edges and boundary nodes are always fixed.
5100 MaxNbOfIterations: the maximum number of iterations
5101 MaxAspectRatio: varies in range [1.0, inf]
5102 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5103 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5106 True in case of success, False otherwise.
5109 if ( isinstance( theObject, Mesh )):
5110 theObject = theObject.GetMesh()
5111 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5112 MaxNbOfIterations, MaxAspectRatio, Method)
5114 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5115 MaxNbOfIterations, MaxAspectRatio, Method):
5117 Parametrically smooth the given elements
5120 IDsOfElements: the list if ids of elements to smooth
5121 IDsOfFixedNodes: the list of ids of fixed nodes.
5122 Note that nodes built on edges and boundary nodes are always fixed.
5123 MaxNbOfIterations: the maximum number of iterations
5124 MaxAspectRatio: varies in range [1.0, inf]
5125 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5126 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5129 True in case of success, False otherwise.
5132 if IDsOfElements == []:
5133 IDsOfElements = self.GetElementsId()
5134 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5135 self.mesh.SetParameters(Parameters)
5136 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5137 MaxNbOfIterations, MaxAspectRatio, Method)
5139 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5140 MaxNbOfIterations, MaxAspectRatio, Method):
5142 Parametrically smooth the elements which belong to the given object
5145 theObject: the object to smooth
5146 IDsOfFixedNodes: the list of ids of fixed nodes.
5147 Note that nodes built on edges and boundary nodes are always fixed.
5148 MaxNbOfIterations: the maximum number of iterations
5149 MaxAspectRatio: varies in range [1.0, inf]
5150 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5151 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5154 True in case of success, False otherwise.
5157 if ( isinstance( theObject, Mesh )):
5158 theObject = theObject.GetMesh()
5159 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5160 MaxNbOfIterations, MaxAspectRatio, Method)
5162 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5164 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5165 them with quadratic with the same id.
5168 theForce3d: method of new node creation:
5170 * False - the medium node lies at the geometrical entity from which the mesh element is built
5171 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5172 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5173 theToBiQuad: If True, converts the mesh to bi-quadratic
5176 :class:`SMESH.ComputeError` which can hold a warning
5179 If *theSubMesh* is provided, the mesh can become non-conformal
5182 This operation can create gaps in numeration of nodes or elements.
5183 Call :meth:`RenumberElements` to remove the gaps.
5186 if isinstance( theSubMesh, Mesh ):
5187 theSubMesh = theSubMesh.mesh
5189 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5192 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5194 self.editor.ConvertToQuadratic(theForce3d)
5195 error = self.editor.GetLastError()
5196 if error and error.comment:
5197 print(error.comment)
5200 def ConvertFromQuadratic(self, theSubMesh=None):
5202 Convert the mesh from quadratic to ordinary,
5203 deletes old quadratic elements,
5204 replacing them with ordinary mesh elements with the same id.
5207 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5210 If *theSubMesh* is provided, the mesh can become non-conformal
5213 This operation can create gaps in numeration of nodes or elements.
5214 Call :meth:`RenumberElements` to remove the gaps.
5218 self.editor.ConvertFromQuadraticObject(theSubMesh)
5220 return self.editor.ConvertFromQuadratic()
5222 def Make2DMeshFrom3D(self):
5224 Create 2D mesh as skin on boundary faces of a 3D mesh
5227 True if operation has been completed successfully, False otherwise
5230 return self.editor.Make2DMeshFrom3D()
5232 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5233 toCopyElements=False, toCopyExistingBondary=False):
5235 Create missing boundary elements
5238 elements: elements whose boundary is to be checked:
5239 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5240 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5241 dimension: defines type of boundary elements to create, either of
5242 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5243 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5244 groupName: a name of group to store created boundary elements in,
5245 "" means not to create the group
5246 meshName: a name of new mesh to store created boundary elements in,
5247 "" means not to create the new mesh
5248 toCopyElements: if True, the checked elements will be copied into
5249 the new mesh else only boundary elements will be copied into the new mesh
5250 toCopyExistingBondary: if True, not only new but also pre-existing
5251 boundary elements will be copied into the new mesh
5254 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5257 unRegister = genObjUnRegister()
5258 if isinstance( elements, Mesh ):
5259 elements = elements.GetMesh()
5260 if ( isinstance( elements, list )):
5261 elemType = SMESH.ALL
5262 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5263 elements = self.editor.MakeIDSource(elements, elemType)
5264 unRegister.set( elements )
5265 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5266 toCopyElements,toCopyExistingBondary)
5267 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5270 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5271 toCopyAll=False, groups=[]):
5273 Create missing boundary elements around either the whole mesh or
5277 dimension: defines type of boundary elements to create, either of
5278 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5279 groupName: a name of group to store all boundary elements in,
5280 "" means not to create the group
5281 meshName: a name of a new mesh, which is a copy of the initial
5282 mesh + created boundary elements; "" means not to create the new mesh
5283 toCopyAll: if True, the whole initial mesh will be copied into
5284 the new mesh else only boundary elements will be copied into the new mesh
5285 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5288 tuple( long, mesh, group )
5289 - long - number of added boundary elements
5290 - mesh - the :class:`Mesh` where elements were added to
5291 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5294 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5296 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5297 return nb, mesh, group
5299 def RenumberNodes(self):
5301 Renumber mesh nodes to remove unused node IDs
5303 self.editor.RenumberNodes()
5305 def RenumberElements(self):
5307 Renumber mesh elements to remove unused element IDs
5309 self.editor.RenumberElements()
5311 def _getIdSourceList(self, arg, idType, unRegister):
5313 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5315 if arg and isinstance( arg, list ):
5316 if isinstance( arg[0], int ):
5317 arg = self.GetIDSource( arg, idType )
5318 unRegister.set( arg )
5319 elif isinstance( arg[0], Mesh ):
5320 arg[0] = arg[0].GetMesh()
5321 elif isinstance( arg, Mesh ):
5323 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5327 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5328 MakeGroups=False, TotalAngle=False):
5330 Generate new elements by rotation of the given elements and nodes around the axis
5333 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5334 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5335 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5336 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5337 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5338 which defines angle in degrees
5339 NbOfSteps: the number of steps
5340 Tolerance: tolerance
5341 MakeGroups: forces the generation of new groups from existing ones
5342 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5343 of all steps, else - size of each step
5346 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5349 unRegister = genObjUnRegister()
5350 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5351 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5352 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5354 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5355 Axis = self.smeshpyD.GetAxisStruct( Axis )
5356 if isinstance( Axis, list ):
5357 Axis = SMESH.AxisStruct( *Axis )
5359 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5360 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5361 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5362 self.mesh.SetParameters(Parameters)
5363 if TotalAngle and NbOfSteps:
5364 AngleInRadians /= NbOfSteps
5365 return self.editor.RotationSweepObjects( nodes, edges, faces,
5366 Axis, AngleInRadians,
5367 NbOfSteps, Tolerance, MakeGroups)
5369 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5370 MakeGroups=False, TotalAngle=False):
5372 Generate new elements by rotation of the elements around the axis
5375 IDsOfElements: the list of ids of elements to sweep
5376 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5377 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5378 NbOfSteps: the number of steps
5379 Tolerance: tolerance
5380 MakeGroups: forces the generation of new groups from existing ones
5381 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5382 of all steps, else - size of each step
5385 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5388 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5389 AngleInRadians, NbOfSteps, Tolerance,
5390 MakeGroups, TotalAngle)
5392 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5393 MakeGroups=False, TotalAngle=False):
5395 Generate new elements by rotation of the elements of object around the axis
5396 theObject object which elements should be sweeped.
5397 It can be a mesh, a sub mesh or a group.
5400 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5401 AngleInRadians: the angle of Rotation
5402 NbOfSteps: number of steps
5403 Tolerance: tolerance
5404 MakeGroups: forces the generation of new groups from existing ones
5405 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5406 of all steps, else - size of each step
5409 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5412 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5413 AngleInRadians, NbOfSteps, Tolerance,
5414 MakeGroups, TotalAngle )
5416 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5417 MakeGroups=False, TotalAngle=False):
5419 Generate new elements by rotation of the elements of object around the axis
5420 theObject object which elements should be sweeped.
5421 It can be a mesh, a sub mesh or a group.
5424 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5425 AngleInRadians: the angle of Rotation
5426 NbOfSteps: number of steps
5427 Tolerance: tolerance
5428 MakeGroups: forces the generation of new groups from existing ones
5429 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5430 of all steps, else - size of each step
5433 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5434 empty list otherwise
5437 return self.RotationSweepObjects([],theObject,[], Axis,
5438 AngleInRadians, NbOfSteps, Tolerance,
5439 MakeGroups, TotalAngle)
5441 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5442 MakeGroups=False, TotalAngle=False):
5444 Generate new elements by rotation of the elements of object around the axis
5445 theObject object which elements should be sweeped.
5446 It can be a mesh, a sub mesh or a group.
5449 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5450 AngleInRadians: the angle of Rotation
5451 NbOfSteps: number of steps
5452 Tolerance: tolerance
5453 MakeGroups: forces the generation of new groups from existing ones
5454 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5455 of all steps, else - size of each step
5458 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5461 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5462 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5464 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5465 scaleFactors=[], linearVariation=False, basePoint=[],
5466 angles=[], anglesVariation=False):
5468 Generate new elements by extrusion of the given elements and nodes
5471 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5472 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5473 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5474 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5475 the direction and value of extrusion for one step (the total extrusion
5476 length will be NbOfSteps * ||StepVector||)
5477 NbOfSteps: the number of steps
5478 MakeGroups: forces the generation of new groups from existing ones
5479 scaleFactors: optional scale factors to apply during extrusion
5480 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5481 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5482 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5483 nodes and elements being extruded is used as the scaling center.
5486 - a list of tree components of the point or
5489 angles: list of angles in radians. Nodes at each extrusion step are rotated
5490 around *basePoint*, additionally to previous steps.
5491 anglesVariation: forces the computation of rotation angles as linear
5492 variation of the given *angles* along path steps
5494 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5496 Example: :ref:`tui_extrusion`
5498 unRegister = genObjUnRegister()
5499 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5500 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5501 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5503 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5504 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5505 if isinstance( StepVector, list ):
5506 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5508 if isinstance( basePoint, int):
5509 xyz = self.GetNodeXYZ( basePoint )
5511 raise RuntimeError("Invalid node ID: %s" % basePoint)
5513 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5514 basePoint = self.geompyD.PointCoordinates( basePoint )
5516 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5517 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5518 angles,angleParameters,hasVars = ParseAngles(angles)
5519 Parameters = StepVector.PS.parameters + var_separator + \
5520 Parameters + var_separator + \
5521 scaleParameters + var_separator + angleParameters
5522 self.mesh.SetParameters(Parameters)
5524 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5525 StepVector, NbOfSteps, MakeGroups,
5526 scaleFactors, linearVariation, basePoint,
5527 angles, anglesVariation )
5530 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5532 Generate new elements by extrusion of the elements with given ids
5535 IDsOfElements: the list of ids of elements or nodes for extrusion
5536 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5537 the direction and value of extrusion for one step (the total extrusion
5538 length will be NbOfSteps * ||StepVector||)
5539 NbOfSteps: the number of steps
5540 MakeGroups: forces the generation of new groups from existing ones
5541 IsNodes: is True if elements with given ids are nodes
5544 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5546 Example: :ref:`tui_extrusion`
5549 if IsNodes: n = IDsOfElements
5550 else : e,f, = IDsOfElements,IDsOfElements
5551 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5553 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5554 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5556 Generate new elements by extrusion along the normal to a discretized surface or wire
5559 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5560 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5561 StepSize: length of one extrusion step (the total extrusion
5562 length will be *NbOfSteps* *StepSize*).
5563 NbOfSteps: number of extrusion steps.
5564 ByAverageNormal: if True each node is translated by *StepSize*
5565 along the average of the normal vectors to the faces sharing the node;
5566 else each node is translated along the same average normal till
5567 intersection with the plane got by translation of the face sharing
5568 the node along its own normal by *StepSize*.
5569 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5570 for every node of *Elements*.
5571 MakeGroups: forces generation of new groups from existing ones.
5572 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5573 is not yet implemented. This parameter is used if *Elements* contains
5574 both faces and edges, i.e. *Elements* is a Mesh.
5577 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5578 empty list otherwise.
5579 Example: :ref:`tui_extrusion`
5582 unRegister = genObjUnRegister()
5583 if isinstance( Elements, Mesh ):
5584 Elements = [ Elements.GetMesh() ]
5585 if isinstance( Elements, list ):
5587 raise RuntimeError("Elements empty!")
5588 if isinstance( Elements[0], Mesh ):
5589 Elements = [ Elements[0].GetMesh() ]
5590 if isinstance( Elements[0], int ):
5591 Elements = self.GetIDSource( Elements, SMESH.ALL )
5592 unRegister.set( Elements )
5593 if not isinstance( Elements, list ):
5594 Elements = [ Elements ]
5595 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5596 self.mesh.SetParameters(Parameters)
5597 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5598 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5600 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5602 Generate new elements by extrusion of the elements or nodes which belong to the object
5605 theObject: the object whose elements or nodes should be processed.
5606 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5607 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5608 the direction and value of extrusion for one step (the total extrusion
5609 length will be NbOfSteps * ||StepVector||)
5610 NbOfSteps: the number of steps
5611 MakeGroups: forces the generation of new groups from existing ones
5612 IsNodes: is True if elements to extrude are nodes
5615 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5616 Example: :ref:`tui_extrusion`
5620 if IsNodes: n = theObject
5621 else : e,f, = theObject,theObject
5622 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5624 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5626 Generate new elements by extrusion of edges which belong to the object
5629 theObject: object whose 1D elements should be processed.
5630 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5631 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5632 the direction and value of extrusion for one step (the total extrusion
5633 length will be NbOfSteps * ||StepVector||)
5634 NbOfSteps: the number of steps
5635 MakeGroups: to generate new groups from existing ones
5638 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5639 Example: :ref:`tui_extrusion`
5642 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5644 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5646 Generate new elements by extrusion of faces which belong to the object
5649 theObject: object whose 2D elements should be processed.
5650 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5651 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5652 the direction and value of extrusion for one step (the total extrusion
5653 length will be NbOfSteps * ||StepVector||)
5654 NbOfSteps: the number of steps
5655 MakeGroups: forces the generation of new groups from existing ones
5658 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5659 Example: :ref:`tui_extrusion`
5662 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5664 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5665 ExtrFlags, SewTolerance, MakeGroups=False):
5667 Generate new elements by extrusion of the elements with given ids
5670 IDsOfElements: is ids of elements
5671 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5672 the direction and value of extrusion for one step (the total extrusion
5673 length will be NbOfSteps * ||StepVector||)
5674 NbOfSteps: the number of steps
5675 ExtrFlags: sets flags for extrusion
5676 SewTolerance: uses for comparing locations of nodes if flag
5677 EXTRUSION_FLAG_SEW is set
5678 MakeGroups: forces the generation of new groups from existing ones
5681 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5684 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5685 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5686 if isinstance( StepVector, list ):
5687 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5688 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5689 ExtrFlags, SewTolerance, MakeGroups)
5691 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5692 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5693 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5694 ScaleFactors=[], ScalesVariation=False):
5696 Generate new elements by extrusion of the given elements and nodes along the path.
5697 The path of extrusion must be a meshed edge.
5700 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5701 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5702 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5703 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5704 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
5705 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5706 HasAngles: not used obsolete
5707 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5708 around *basePoint*, additionally to previous steps.
5709 LinearVariation: forces the computation of rotation angles as linear
5710 variation of the given Angles along path steps
5711 HasRefPoint: allows using the reference point
5712 RefPoint: optional scaling and rotation center (mass center of the extruded
5713 elements by default). The User can specify any point as the Reference Point.
5714 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5715 MakeGroups: forces the generation of new groups from existing ones
5716 ScaleFactors: optional scale factors to apply during extrusion
5717 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5718 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5721 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5722 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5723 Example: :ref:`tui_extrusion_along_path`
5726 unRegister = genObjUnRegister()
5727 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5728 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5729 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5731 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5732 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5733 if isinstance( RefPoint, list ):
5734 if not RefPoint: RefPoint = [0,0,0]
5735 RefPoint = SMESH.PointStruct( *RefPoint )
5736 if isinstance( PathObject, Mesh ):
5737 PathObject = PathObject.GetMesh()
5738 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5739 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5740 Parameters = AnglesParameters + var_separator + \
5741 RefPoint.parameters + var_separator + ScalesParameters
5742 self.mesh.SetParameters(Parameters)
5743 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5744 PathObject, PathShape, NodeStart,
5745 HasAngles, Angles, LinearVariation,
5746 HasRefPoint, RefPoint, MakeGroups,
5747 ScaleFactors, ScalesVariation)
5749 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5750 HasAngles=False, Angles=[], LinearVariation=False,
5751 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5752 ElemType=SMESH.FACE):
5754 Generate new elements by extrusion of the given elements.
5755 The path of extrusion must be a meshed edge.
5758 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5759 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5760 NodeStart: the start node from Path. Defines the direction of extrusion
5761 HasAngles: not used obsolete
5762 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5763 around *basePoint*, additionally to previous steps.
5764 LinearVariation: forces the computation of rotation angles as linear
5765 variation of the given Angles along path steps
5766 HasRefPoint: allows using the reference point
5767 RefPoint: the reference point around which the elements are rotated (the mass
5768 center of the elements by default).
5769 The User can specify any point as the Reference Point.
5770 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5771 MakeGroups: forces the generation of new groups from existing ones
5772 ElemType: type of elements for extrusion (if param Base is a mesh)
5775 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5776 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5777 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5779 Example: :ref:`tui_extrusion_along_path`
5783 if ElemType == SMESH.NODE: n = Base
5784 if ElemType == SMESH.EDGE: e = Base
5785 if ElemType == SMESH.FACE: f = Base
5786 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5787 HasAngles, Angles, LinearVariation,
5788 HasRefPoint, RefPoint, MakeGroups)
5789 if MakeGroups: return gr,er
5792 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5793 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5794 MakeGroups=False, LinearVariation=False):
5796 Generate new elements by extrusion of the given elements.
5797 The path of extrusion must be a meshed edge.
5800 IDsOfElements: ids of elements
5801 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5802 PathShape: shape (edge) defines the sub-mesh for the path
5803 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5804 HasAngles: not used obsolete
5805 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5806 around *basePoint*, additionally to previous steps.
5807 HasRefPoint: allows using the reference point
5808 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5809 The User can specify any point as the Reference Point.
5810 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5811 MakeGroups: forces the generation of new groups from existing ones
5812 LinearVariation: forces the computation of rotation angles as linear
5813 variation of the given Angles along path steps
5816 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5817 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5818 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5819 Example: :ref:`tui_extrusion_along_path`
5822 if not IDsOfElements:
5823 IDsOfElements = [ self.GetMesh() ]
5824 n,e,f = [],IDsOfElements,IDsOfElements
5825 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5826 NodeStart, HasAngles, Angles,
5828 HasRefPoint, RefPoint, MakeGroups)
5829 if MakeGroups: return gr,er
5832 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5833 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5834 MakeGroups=False, LinearVariation=False):
5836 Generate new elements by extrusion of the elements which belong to the object.
5837 The path of extrusion must be a meshed edge.
5840 theObject: the object whose elements should be processed.
5841 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5842 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5843 PathShape: shape (edge) defines the sub-mesh for the path
5844 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5845 HasAngles: not used obsolete
5846 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5847 around *basePoint*, additionally to previous steps.
5848 HasRefPoint: allows using the reference point
5849 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5850 The User can specify any point as the Reference Point.
5851 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5852 MakeGroups: forces the generation of new groups from existing ones
5853 LinearVariation: forces the computation of rotation angles as linear
5854 variation of the given Angles along path steps
5857 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5858 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5859 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5860 Example: :ref:`tui_extrusion_along_path`
5863 n,e,f = [],theObject,theObject
5864 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5865 HasAngles, Angles, LinearVariation,
5866 HasRefPoint, RefPoint, MakeGroups)
5867 if MakeGroups: return gr,er
5870 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5871 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5872 MakeGroups=False, LinearVariation=False):
5874 Generate new elements by extrusion of mesh segments which belong to the object.
5875 The path of extrusion must be a meshed edge.
5878 theObject: the object whose 1D elements should be processed.
5879 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5880 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5881 PathShape: shape (edge) defines the sub-mesh for the path
5882 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5883 HasAngles: not used obsolete
5884 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5885 around *basePoint*, additionally to previous steps.
5886 HasRefPoint: allows using the reference point
5887 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5888 The User can specify any point as the Reference Point.
5889 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5890 MakeGroups: forces the generation of new groups from existing ones
5891 LinearVariation: forces the computation of rotation angles as linear
5892 variation of the given Angles along path steps
5895 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5896 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5897 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5898 Example: :ref:`tui_extrusion_along_path`
5901 n,e,f = [],theObject,[]
5902 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5903 HasAngles, Angles, LinearVariation,
5904 HasRefPoint, RefPoint, MakeGroups)
5905 if MakeGroups: return gr,er
5908 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5909 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5910 MakeGroups=False, LinearVariation=False):
5912 Generate new elements by extrusion of faces which belong to the object.
5913 The path of extrusion must be a meshed edge.
5916 theObject: the object whose 2D elements should be processed.
5917 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5918 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5919 PathShape: shape (edge) defines the sub-mesh for the path
5920 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5921 HasAngles: not used obsolete
5922 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5923 around *basePoint*, additionally to previous steps.
5924 HasRefPoint: allows using the reference point
5925 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5926 The User can specify any point as the Reference Point.
5927 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5928 MakeGroups: forces the generation of new groups from existing ones
5929 LinearVariation: forces the computation of rotation angles as linear
5930 variation of the given Angles along path steps
5933 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5934 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5935 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5936 Example: :ref:`tui_extrusion_along_path`
5939 n,e,f = [],[],theObject
5940 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5941 HasAngles, Angles, LinearVariation,
5942 HasRefPoint, RefPoint, MakeGroups)
5943 if MakeGroups: return gr,er
5946 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5948 Create a symmetrical copy of mesh elements
5951 IDsOfElements: list of elements ids
5952 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5953 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5954 If the *Mirror* is a geom object this parameter is unnecessary
5955 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5956 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5959 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5962 if IDsOfElements == []:
5963 IDsOfElements = self.GetElementsId()
5964 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5965 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5966 theMirrorType = Mirror._mirrorType
5968 self.mesh.SetParameters(Mirror.parameters)
5969 if Copy and MakeGroups:
5970 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5971 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5974 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5976 Create a new mesh by a symmetrical copy of mesh elements
5979 IDsOfElements: the list of elements ids
5980 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5981 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5982 If the *Mirror* is a geom object this parameter is unnecessary
5983 MakeGroups: to generate new groups from existing ones
5984 NewMeshName: a name of the new mesh to create
5987 instance of class :class:`Mesh`
5990 if IDsOfElements == []:
5991 IDsOfElements = self.GetElementsId()
5992 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5993 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5994 theMirrorType = Mirror._mirrorType
5996 self.mesh.SetParameters(Mirror.parameters)
5997 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5998 MakeGroups, NewMeshName)
5999 return Mesh(self.smeshpyD,self.geompyD,mesh)
6001 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6003 Create a symmetrical copy of the object
6006 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6007 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6008 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6009 If the *Mirror* is a geom object this parameter is unnecessary
6010 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6011 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6014 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6017 if ( isinstance( theObject, Mesh )):
6018 theObject = theObject.GetMesh()
6019 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6020 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6021 theMirrorType = Mirror._mirrorType
6023 self.mesh.SetParameters(Mirror.parameters)
6024 if Copy and MakeGroups:
6025 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6026 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6029 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6031 Create a new mesh by a symmetrical copy of the object
6034 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6035 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6036 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6037 If the *Mirror* is a geom object this parameter is unnecessary
6038 MakeGroups: forces the generation of new groups from existing ones
6039 NewMeshName: the name of the new mesh to create
6042 instance of class :class:`Mesh`
6045 if ( isinstance( theObject, Mesh )):
6046 theObject = theObject.GetMesh()
6047 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6048 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6049 theMirrorType = Mirror._mirrorType
6051 self.mesh.SetParameters(Mirror.parameters)
6052 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6053 MakeGroups, NewMeshName)
6054 return Mesh( self.smeshpyD,self.geompyD,mesh )
6056 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6058 Translate the elements
6061 IDsOfElements: list of elements ids
6062 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6063 Copy: allows copying the translated elements
6064 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6067 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6070 if IDsOfElements == []:
6071 IDsOfElements = self.GetElementsId()
6072 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6073 Vector = self.smeshpyD.GetDirStruct(Vector)
6074 if isinstance( Vector, list ):
6075 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6076 self.mesh.SetParameters(Vector.PS.parameters)
6077 if Copy and MakeGroups:
6078 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6079 self.editor.Translate(IDsOfElements, Vector, Copy)
6082 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6084 Create a new mesh of translated elements
6087 IDsOfElements: list of elements ids
6088 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6089 MakeGroups: forces the generation of new groups from existing ones
6090 NewMeshName: the name of the newly created mesh
6093 instance of class :class:`Mesh`
6096 if IDsOfElements == []:
6097 IDsOfElements = self.GetElementsId()
6098 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6099 Vector = self.smeshpyD.GetDirStruct(Vector)
6100 if isinstance( Vector, list ):
6101 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6102 self.mesh.SetParameters(Vector.PS.parameters)
6103 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6104 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6106 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6108 Translate the object
6111 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6112 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6113 Copy: allows copying the translated elements
6114 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6117 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6120 if ( isinstance( theObject, Mesh )):
6121 theObject = theObject.GetMesh()
6122 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6123 Vector = self.smeshpyD.GetDirStruct(Vector)
6124 if isinstance( Vector, list ):
6125 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6126 self.mesh.SetParameters(Vector.PS.parameters)
6127 if Copy and MakeGroups:
6128 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6129 self.editor.TranslateObject(theObject, Vector, Copy)
6132 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6134 Create a new mesh from the translated object
6137 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6138 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6139 MakeGroups: forces the generation of new groups from existing ones
6140 NewMeshName: the name of the newly created mesh
6143 instance of class :class:`Mesh`
6146 if isinstance( theObject, Mesh ):
6147 theObject = theObject.GetMesh()
6148 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6149 Vector = self.smeshpyD.GetDirStruct(Vector)
6150 if isinstance( Vector, list ):
6151 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6152 self.mesh.SetParameters(Vector.PS.parameters)
6153 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6154 return Mesh( self.smeshpyD, self.geompyD, mesh )
6158 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6163 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6164 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6165 theScaleFact: list of 1-3 scale factors for axises
6166 Copy: allows copying the translated elements
6167 MakeGroups: forces the generation of new groups from existing
6171 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6172 empty list otherwise
6174 unRegister = genObjUnRegister()
6175 if ( isinstance( theObject, Mesh )):
6176 theObject = theObject.GetMesh()
6177 if ( isinstance( theObject, list )):
6178 theObject = self.GetIDSource(theObject, SMESH.ALL)
6179 unRegister.set( theObject )
6180 if ( isinstance( thePoint, list )):
6181 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6182 if ( isinstance( theScaleFact, float )):
6183 theScaleFact = [theScaleFact]
6184 if ( isinstance( theScaleFact, int )):
6185 theScaleFact = [ float(theScaleFact)]
6187 self.mesh.SetParameters(thePoint.parameters)
6189 if Copy and MakeGroups:
6190 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6191 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6194 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6196 Create a new mesh from the translated object
6199 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6200 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6201 theScaleFact: list of 1-3 scale factors for axises
6202 MakeGroups: forces the generation of new groups from existing ones
6203 NewMeshName: the name of the newly created mesh
6206 instance of class :class:`Mesh`
6208 unRegister = genObjUnRegister()
6209 if (isinstance(theObject, Mesh)):
6210 theObject = theObject.GetMesh()
6211 if ( isinstance( theObject, list )):
6212 theObject = self.GetIDSource(theObject,SMESH.ALL)
6213 unRegister.set( theObject )
6214 if ( isinstance( thePoint, list )):
6215 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6216 if ( isinstance( theScaleFact, float )):
6217 theScaleFact = [theScaleFact]
6218 if ( isinstance( theScaleFact, int )):
6219 theScaleFact = [ float(theScaleFact)]
6221 self.mesh.SetParameters(thePoint.parameters)
6222 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6223 MakeGroups, NewMeshName)
6224 return Mesh( self.smeshpyD, self.geompyD, mesh )
6228 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6233 IDsOfElements: list of elements ids
6234 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6235 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6236 Copy: allows copying the rotated elements
6237 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6240 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6244 if IDsOfElements == []:
6245 IDsOfElements = self.GetElementsId()
6246 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6247 Axis = self.smeshpyD.GetAxisStruct(Axis)
6248 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6249 Parameters = Axis.parameters + var_separator + Parameters
6250 self.mesh.SetParameters(Parameters)
6251 if Copy and MakeGroups:
6252 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6253 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6256 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6258 Create a new mesh of rotated elements
6261 IDsOfElements: list of element ids
6262 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6263 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6264 MakeGroups: forces the generation of new groups from existing ones
6265 NewMeshName: the name of the newly created mesh
6268 instance of class :class:`Mesh`
6271 if IDsOfElements == []:
6272 IDsOfElements = self.GetElementsId()
6273 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6274 Axis = self.smeshpyD.GetAxisStruct(Axis)
6275 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6276 Parameters = Axis.parameters + var_separator + Parameters
6277 self.mesh.SetParameters(Parameters)
6278 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6279 MakeGroups, NewMeshName)
6280 return Mesh( self.smeshpyD, self.geompyD, mesh )
6282 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6287 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6288 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6289 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6290 Copy: allows copying the rotated elements
6291 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6294 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6297 if (isinstance(theObject, Mesh)):
6298 theObject = theObject.GetMesh()
6299 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6300 Axis = self.smeshpyD.GetAxisStruct(Axis)
6301 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6302 Parameters = Axis.parameters + ":" + Parameters
6303 self.mesh.SetParameters(Parameters)
6304 if Copy and MakeGroups:
6305 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6306 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6309 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6311 Create a new mesh from the rotated object
6314 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6315 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6316 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6317 MakeGroups: forces the generation of new groups from existing ones
6318 NewMeshName: the name of the newly created mesh
6321 instance of class :class:`Mesh`
6324 if (isinstance( theObject, Mesh )):
6325 theObject = theObject.GetMesh()
6326 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6327 Axis = self.smeshpyD.GetAxisStruct(Axis)
6328 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6329 Parameters = Axis.parameters + ":" + Parameters
6330 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6331 MakeGroups, NewMeshName)
6332 self.mesh.SetParameters(Parameters)
6333 return Mesh( self.smeshpyD, self.geompyD, mesh )
6335 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6337 Create an offset mesh from the given 2D object
6340 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6341 theValue (float): signed offset size
6342 MakeGroups (boolean): forces the generation of new groups from existing ones
6343 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6344 False means to remove original elements.
6345 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6348 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6351 if isinstance( theObject, Mesh ):
6352 theObject = theObject.GetMesh()
6353 theValue,Parameters,hasVars = ParseParameters(Value)
6354 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6355 self.mesh.SetParameters(Parameters)
6356 # if mesh_groups[0]:
6357 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6360 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6362 Find groups of adjacent nodes within Tolerance.
6365 Tolerance (float): the value of tolerance
6366 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6367 corner and medium nodes in separate groups thus preventing
6368 their further merge.
6371 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6374 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6376 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6377 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6379 Find groups of adjacent nodes within Tolerance.
6382 Tolerance: the value of tolerance
6383 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6384 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6385 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6386 corner and medium nodes in separate groups thus preventing
6387 their further merge.
6390 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6393 unRegister = genObjUnRegister()
6394 if not isinstance( SubMeshOrGroup, list ):
6395 SubMeshOrGroup = [ SubMeshOrGroup ]
6396 for i,obj in enumerate( SubMeshOrGroup ):
6397 if isinstance( obj, Mesh ):
6398 SubMeshOrGroup = [ obj.GetMesh() ]
6400 if isinstance( obj, int ):
6401 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6402 unRegister.set( SubMeshOrGroup )
6405 if not isinstance( exceptNodes, list ):
6406 exceptNodes = [ exceptNodes ]
6407 if exceptNodes and isinstance( exceptNodes[0], int ):
6408 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6409 unRegister.set( exceptNodes )
6411 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6412 exceptNodes, SeparateCornerAndMediumNodes)
6414 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6419 GroupsOfNodes: a list of groups of nodes IDs for merging.
6420 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6421 in all elements and mesh groups by nodes 1 and 25 correspondingly
6422 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6423 If *NodesToKeep* does not include a node to keep for some group to merge,
6424 then the first node in the group is kept.
6425 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6429 This operation can create gaps in numeration of nodes or elements.
6430 Call :meth:`RenumberElements` to remove the gaps.
6432 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6434 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6436 Find the elements built on the same nodes.
6439 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6440 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6444 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6447 unRegister = genObjUnRegister()
6448 if MeshOrSubMeshOrGroup is None:
6449 MeshOrSubMeshOrGroup = [ self.mesh ]
6450 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6451 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6452 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6453 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6454 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6455 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6456 unRegister.set( MeshOrSubMeshOrGroup )
6457 for item in MeshOrSubMeshOrGroup:
6458 if isinstance( item, Mesh ):
6459 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6461 if not isinstance( exceptElements, list ):
6462 exceptElements = [ exceptElements ]
6463 if exceptElements and isinstance( exceptElements[0], int ):
6464 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6465 unRegister.set( exceptElements )
6467 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6469 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6471 Merge elements in each given group.
6474 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6475 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6476 replaced in all mesh groups by elements 1 and 25)
6477 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6478 If *ElementsToKeep* does not include an element to keep for some group to merge,
6479 then the first element in the group is kept.
6482 This operation can create gaps in numeration of elements.
6483 Call :meth:`RenumberElements` to remove the gaps.
6486 unRegister = genObjUnRegister()
6488 if not isinstance( ElementsToKeep, list ):
6489 ElementsToKeep = [ ElementsToKeep ]
6490 if isinstance( ElementsToKeep[0], int ):
6491 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6492 unRegister.set( ElementsToKeep )
6494 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6496 def MergeEqualElements(self):
6498 Leave one element and remove all other elements built on the same nodes.
6501 This operation can create gaps in numeration of elements.
6502 Call :meth:`RenumberElements` to remove the gaps.
6505 self.editor.MergeEqualElements()
6507 def FindFreeBorders(self, ClosedOnly=True):
6509 Returns all or only closed free borders
6512 list of SMESH.FreeBorder's
6515 return self.editor.FindFreeBorders( ClosedOnly )
6517 def FillHole(self, holeNodes, groupName=""):
6519 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6522 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6523 must describe all sequential nodes of the hole border. The first and the last
6524 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6525 groupName (string): name of a group to add new faces
6527 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6531 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6532 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6533 if not isinstance( holeNodes, SMESH.FreeBorder ):
6534 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6535 return self.editor.FillHole( holeNodes, groupName )
6537 def FindCoincidentFreeBorders (self, tolerance=0.):
6539 Return groups of FreeBorder's coincident within the given tolerance.
6542 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6543 size of elements adjacent to free borders being compared is used.
6546 SMESH.CoincidentFreeBorders structure
6549 return self.editor.FindCoincidentFreeBorders( tolerance )
6551 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6553 Sew FreeBorder's of each group
6556 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6557 where each enclosed list contains node IDs of a group of coincident free
6558 borders such that each consequent triple of IDs within a group describes
6559 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6560 last node of a border.
6561 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6562 groups of coincident free borders, each group including two borders.
6563 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6564 polygons if a node of opposite border falls on a face edge, else such
6565 faces are split into several ones.
6566 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6567 polyhedra if a node of opposite border falls on a volume edge, else such
6568 volumes, if any, remain intact and the mesh becomes non-conformal.
6571 a number of successfully sewed groups
6574 This operation can create gaps in numeration of nodes or elements.
6575 Call :meth:`RenumberElements` to remove the gaps.
6578 if freeBorders and isinstance( freeBorders, list ):
6579 # construct SMESH.CoincidentFreeBorders
6580 if isinstance( freeBorders[0], int ):
6581 freeBorders = [freeBorders]
6583 coincidentGroups = []
6584 for nodeList in freeBorders:
6585 if not nodeList or len( nodeList ) % 3:
6586 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6589 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6590 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6591 nodeList = nodeList[3:]
6593 coincidentGroups.append( group )
6595 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6597 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6599 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6600 FirstNodeID2, SecondNodeID2, LastNodeID2,
6601 CreatePolygons, CreatePolyedrs):
6606 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6609 This operation can create gaps in numeration of nodes or elements.
6610 Call :meth:`RenumberElements` to remove the gaps.
6613 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6614 FirstNodeID2, SecondNodeID2, LastNodeID2,
6615 CreatePolygons, CreatePolyedrs)
6617 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6618 FirstNodeID2, SecondNodeID2):
6620 Sew conform free borders
6623 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6626 This operation can create gaps in numeration of elements.
6627 Call :meth:`RenumberElements` to remove the gaps.
6630 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6631 FirstNodeID2, SecondNodeID2)
6633 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6634 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6639 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6642 This operation can create gaps in numeration of elements.
6643 Call :meth:`RenumberElements` to remove the gaps.
6646 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6647 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6649 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6650 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6651 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6653 Sew two sides of a mesh. The nodes belonging to Side1 are
6654 merged with the nodes of elements of Side2.
6655 The number of elements in theSide1 and in theSide2 must be
6656 equal and they should have similar nodal connectivity.
6657 The nodes to merge should belong to side borders and
6658 the first node should be linked to the second.
6661 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6664 This operation can create gaps in numeration of nodes.
6665 Call :meth:`RenumberElements` to remove the gaps.
6668 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6669 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6670 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6672 def ChangeElemNodes(self, ide, newIDs):
6674 Set new nodes for the given element. Number of nodes should be kept.
6681 False if the number of nodes does not correspond to the type of element
6684 return self.editor.ChangeElemNodes(ide, newIDs)
6686 def GetLastCreatedNodes(self):
6688 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6689 created, this method return the list of their IDs.
6690 If new nodes were not created - return empty list
6693 the list of integer values (can be empty)
6696 return self.editor.GetLastCreatedNodes()
6698 def GetLastCreatedElems(self):
6700 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6701 created this method return the list of their IDs.
6702 If new elements were not created - return empty list
6705 the list of integer values (can be empty)
6708 return self.editor.GetLastCreatedElems()
6710 def ClearLastCreated(self):
6712 Forget what nodes and elements were created by the last mesh edition operation
6715 self.editor.ClearLastCreated()
6717 def DoubleElements(self, theElements, theGroupName=""):
6719 Create duplicates of given elements, i.e. create new elements based on the
6720 same nodes as the given ones.
6723 theElements: container of elements to duplicate. It can be a
6724 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6725 or a list of element IDs. If *theElements* is
6726 a :class:`Mesh`, elements of highest dimension are duplicated
6727 theGroupName: a name of group to contain the generated elements.
6728 If a group with such a name already exists, the new elements
6729 are added to the existing group, else a new group is created.
6730 If *theGroupName* is empty, new elements are not added
6734 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6735 None if *theGroupName* == "".
6738 unRegister = genObjUnRegister()
6739 if isinstance( theElements, Mesh ):
6740 theElements = theElements.mesh
6741 elif isinstance( theElements, list ):
6742 theElements = self.GetIDSource( theElements, SMESH.ALL )
6743 unRegister.set( theElements )
6744 return self.editor.DoubleElements(theElements, theGroupName)
6746 def DoubleNodes(self, theNodes, theModifiedElems):
6748 Create a hole in a mesh by doubling the nodes of some particular elements
6751 theNodes: IDs of nodes to be doubled
6752 theModifiedElems: IDs of elements to be updated by the new (doubled)
6753 nodes. If list of element identifiers is empty then nodes are doubled but
6754 they not assigned to elements
6757 True if operation has been completed successfully, False otherwise
6760 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6762 def DoubleNode(self, theNodeId, theModifiedElems):
6764 Create a hole in a mesh by doubling the nodes of some particular elements.
6765 This method provided for convenience works as :meth:`DoubleNodes`.
6768 theNodeId: IDs of node to double
6769 theModifiedElems: IDs of elements to update
6772 True if operation has been completed successfully, False otherwise
6775 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6777 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6779 Create a hole in a mesh by doubling the nodes of some particular elements.
6780 This method provided for convenience works as :meth:`DoubleNodes`.
6783 theNodes: group of nodes to double.
6784 theModifiedElems: group of elements to update.
6785 theMakeGroup: forces the generation of a group containing new nodes.
6788 True or a created group if operation has been completed successfully,
6789 False or None otherwise
6793 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6794 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6796 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6798 Create a hole in a mesh by doubling the nodes of some particular elements.
6799 This method provided for convenience works as :meth:`DoubleNodes`.
6802 theNodes: list of groups of nodes to double.
6803 theModifiedElems: list of groups of elements to update.
6804 theMakeGroup: forces the generation of a group containing new nodes.
6807 True if operation has been completed successfully, False otherwise
6811 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6812 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6814 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6816 Create a hole in a mesh by doubling the nodes of some particular elements
6819 theElems: the list of elements (edges or faces) to replicate.
6820 The nodes for duplication could be found from these elements
6821 theNodesNot: list of nodes NOT to replicate
6822 theAffectedElems: the list of elements (cells and edges) to which the
6823 replicated nodes should be associated to
6826 True if operation has been completed successfully, False otherwise
6829 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6831 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6833 Create a hole in a mesh by doubling the nodes of some particular elements
6836 theElems: the list of elements (edges or faces) to replicate.
6837 The nodes for duplication could be found from these elements
6838 theNodesNot: list of nodes NOT to replicate
6839 theShape: shape to detect affected elements (element which geometric center
6840 located on or inside shape).
6841 The replicated nodes should be associated to affected elements.
6844 True if operation has been completed successfully, False otherwise
6847 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6849 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6850 theMakeGroup=False, theMakeNodeGroup=False):
6852 Create a hole in a mesh by doubling the nodes of some particular elements.
6853 This method provided for convenience works as :meth:`DoubleNodes`.
6856 theElems: group of of elements (edges or faces) to replicate.
6857 theNodesNot: group of nodes NOT to replicate.
6858 theAffectedElems: group of elements to which the replicated nodes
6859 should be associated to.
6860 theMakeGroup: forces the generation of a group containing new elements.
6861 theMakeNodeGroup: forces the generation of a group containing new nodes.
6864 True or created groups (one or two) if operation has been completed successfully,
6865 False or None otherwise
6868 if theMakeGroup or theMakeNodeGroup:
6869 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6871 theMakeGroup, theMakeNodeGroup)
6872 if theMakeGroup and theMakeNodeGroup:
6875 return twoGroups[ int(theMakeNodeGroup) ]
6876 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6878 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6880 Create a hole in a mesh by doubling the nodes of some particular elements.
6881 This method provided for convenience works as :meth:`DoubleNodes`.
6884 theElems: group of of elements (edges or faces) to replicate
6885 theNodesNot: group of nodes not to replicate
6886 theShape: shape to detect affected elements (element which geometric center
6887 located on or inside shape).
6888 The replicated nodes should be associated to affected elements
6891 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6893 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6894 theMakeGroup=False, theMakeNodeGroup=False):
6896 Create a hole in a mesh by doubling the nodes of some particular elements.
6897 This method provided for convenience works as :meth:`DoubleNodes`.
6900 theElems: list of groups of elements (edges or faces) to replicate
6901 theNodesNot: list of groups of nodes NOT to replicate
6902 theAffectedElems: group of elements to which the replicated nodes
6903 should be associated to
6904 theMakeGroup: forces generation of a group containing new elements.
6905 theMakeNodeGroup: forces generation of a group containing new nodes
6908 True or created groups (one or two) if operation has been completed successfully,
6909 False or None otherwise
6912 if theMakeGroup or theMakeNodeGroup:
6913 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6915 theMakeGroup, theMakeNodeGroup)
6916 if theMakeGroup and theMakeNodeGroup:
6919 return twoGroups[ int(theMakeNodeGroup) ]
6920 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6922 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6924 Create a hole in a mesh by doubling the nodes of some particular elements.
6925 This method provided for convenience works as :meth:`DoubleNodes`.
6928 theElems: list of groups of elements (edges or faces) to replicate
6929 theNodesNot: list of groups of nodes NOT to replicate
6930 theShape: shape to detect affected elements (element which geometric center
6931 located on or inside shape).
6932 The replicated nodes should be associated to affected elements
6935 True if operation has been completed successfully, False otherwise
6938 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6940 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6942 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6943 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6946 theElems: list of groups of nodes or 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 groups of affected elements in order: volumes, faces, edges
6956 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6958 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6961 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6962 The list of groups must describe a partition of the mesh volumes.
6963 The nodes of the internal faces at the boundaries of the groups are doubled.
6964 In option, the internal faces are replaced by flat elements.
6965 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6968 theDomains: list of groups of volumes
6969 createJointElems: if True, create the elements
6970 onAllBoundaries: if True, the nodes and elements are also created on
6971 the boundary between *theDomains* and the rest mesh
6974 True if operation has been completed successfully, False otherwise
6977 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6979 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6981 Double nodes on some external faces and create flat elements.
6982 Flat elements are mainly used by some types of mechanic calculations.
6984 Each group of the list must be constituted of faces.
6985 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6988 theGroupsOfFaces: list of groups of faces
6991 True if operation has been completed successfully, False otherwise
6994 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6996 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6998 Identify all the elements around a geom shape, get the faces delimiting the hole
7000 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7002 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7004 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7005 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7006 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7007 If there are several paths connecting a pair of points, the shortest path is
7008 selected by the module. Position of the cutting plane is defined by the two
7009 points and an optional vector lying on the plane specified by a PolySegment.
7010 By default the vector is defined by Mesh module as following. A middle point
7011 of the two given points is computed. The middle point is projected to the mesh.
7012 The vector goes from the middle point to the projection point. In case of planar
7013 mesh, the vector is normal to the mesh.
7015 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7018 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7019 groupName: optional name of a group where created mesh segments will be added.
7022 editor = self.editor
7024 editor = self.mesh.GetMeshEditPreviewer()
7025 segmentsRes = editor.MakePolyLine( segments, groupName )
7026 for i, seg in enumerate( segmentsRes ):
7027 segments[i].vector = seg.vector
7029 return editor.GetPreviewData()
7032 def MakeSlot(self, segmentGroup, width ):
7034 Create a slot of given width around given 1D elements lying on a triangle mesh.
7035 The slot is constructed by cutting faces by cylindrical surfaces made
7036 around each segment. Segments are expected to be created by MakePolyLine().
7039 FaceEdge's located at the slot boundary
7041 return self.editor.MakeSlot( segmentGroup, width )
7043 def GetFunctor(self, funcType ):
7045 Return a cached numerical functor by its type.
7048 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7049 Note that not all items correspond to numerical functors.
7052 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7055 fn = self.functors[ funcType._v ]
7057 fn = self.smeshpyD.GetFunctor(funcType)
7058 fn.SetMesh(self.mesh)
7059 self.functors[ funcType._v ] = fn
7062 def FunctorValue(self, funcType, elemId, isElem=True):
7064 Return value of a functor for a given element
7067 funcType: an item of :class:`SMESH.FunctorType` enum.
7068 elemId: element or node ID
7069 isElem: *elemId* is ID of element or node
7072 the functor value or zero in case of invalid arguments
7075 fn = self.GetFunctor( funcType )
7076 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7077 val = fn.GetValue(elemId)
7082 def GetLength(self, elemId=None):
7084 Get length of given 1D elements or of all 1D mesh elements
7087 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.
7090 Sum of lengths of given elements
7095 length = self.smeshpyD.GetLength(self)
7096 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7097 length = self.smeshpyD.GetLength(elemId)
7100 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7102 length += self.smeshpyD.GetLength(obj)
7103 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7104 unRegister = genObjUnRegister()
7105 obj = self.GetIDSource( elemId )
7106 unRegister.set( obj )
7107 length = self.smeshpyD.GetLength( obj )
7109 length = self.FunctorValue(SMESH.FT_Length, elemId)
7112 def GetArea(self, elemId=None):
7114 Get area of given 2D elements or of all 2D mesh elements
7117 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.
7120 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7125 area = self.smeshpyD.GetArea(self)
7126 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7127 area = self.smeshpyD.GetArea(elemId)
7130 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7132 area += self.smeshpyD.GetArea(obj)
7133 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7134 unRegister = genObjUnRegister()
7135 obj = self.GetIDSource( elemId )
7136 unRegister.set( obj )
7137 area = self.smeshpyD.GetArea( obj )
7139 area = self.FunctorValue(SMESH.FT_Area, elemId)
7142 def GetVolume(self, elemId=None):
7144 Get volume of given 3D elements or of all 3D mesh elements
7147 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.
7150 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7155 volume= self.smeshpyD.GetVolume(self)
7156 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7157 volume= self.smeshpyD.GetVolume(elemId)
7160 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7162 volume+= self.smeshpyD.GetVolume(obj)
7163 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7164 unRegister = genObjUnRegister()
7165 obj = self.GetIDSource( elemId )
7166 unRegister.set( obj )
7167 volume= self.smeshpyD.GetVolume( obj )
7169 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7172 def GetAngle(self, node1, node2, node3 ):
7174 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7177 node1,node2,node3: IDs of the three nodes
7180 Angle in radians [0,PI]. -1 if failure case.
7182 p1 = self.GetNodeXYZ( node1 )
7183 p2 = self.GetNodeXYZ( node2 )
7184 p3 = self.GetNodeXYZ( node3 )
7185 if p1 and p2 and p3:
7186 return self.smeshpyD.GetAngle( p1,p2,p3 )
7190 def GetMaxElementLength(self, elemId):
7192 Get maximum element length.
7195 elemId: mesh element ID
7198 element's maximum length value
7201 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7202 ftype = SMESH.FT_MaxElementLength3D
7204 ftype = SMESH.FT_MaxElementLength2D
7205 return self.FunctorValue(ftype, elemId)
7207 def GetAspectRatio(self, elemId):
7209 Get aspect ratio of 2D or 3D element.
7212 elemId: mesh element ID
7215 element's aspect ratio value
7218 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7219 ftype = SMESH.FT_AspectRatio3D
7221 ftype = SMESH.FT_AspectRatio
7222 return self.FunctorValue(ftype, elemId)
7224 def GetWarping(self, elemId):
7226 Get warping angle of 2D element.
7229 elemId: mesh element ID
7232 element's warping angle value
7235 return self.FunctorValue(SMESH.FT_Warping, elemId)
7237 def GetMinimumAngle(self, elemId):
7239 Get minimum angle of 2D element.
7242 elemId: mesh element ID
7245 element's minimum angle value
7248 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7250 def GetTaper(self, elemId):
7252 Get taper of 2D element.
7255 elemId: mesh element ID
7258 element's taper value
7261 return self.FunctorValue(SMESH.FT_Taper, elemId)
7263 def GetSkew(self, elemId):
7265 Get skew of 2D element.
7268 elemId: mesh element ID
7271 element's skew value
7274 return self.FunctorValue(SMESH.FT_Skew, elemId)
7276 def GetMinMax(self, funType, meshPart=None):
7278 Return minimal and maximal value of a given functor.
7281 funType (SMESH.FunctorType): a functor type.
7282 Note that not all items of :class:`SMESH.FunctorType` corresponds
7283 to numerical functors.
7284 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7290 unRegister = genObjUnRegister()
7291 if isinstance( meshPart, list ):
7292 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7293 unRegister.set( meshPart )
7294 if isinstance( meshPart, Mesh ):
7295 meshPart = meshPart.mesh
7296 fun = self.GetFunctor( funType )
7299 if hasattr( meshPart, "SetMesh" ):
7300 meshPart.SetMesh( self.mesh ) # set mesh to filter
7301 hist = fun.GetLocalHistogram( 1, False, meshPart )
7303 hist = fun.GetHistogram( 1, False )
7305 return hist[0].min, hist[0].max
7308 pass # end of Mesh class
7311 class meshProxy(SMESH._objref_SMESH_Mesh):
7313 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7314 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7316 def __init__(self,*args):
7317 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7318 def __deepcopy__(self, memo=None):
7319 new = self.__class__(self)
7321 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7322 if len( args ) == 3:
7323 args += SMESH.ALL_NODES, True
7324 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7325 def ExportToMEDX(self, *args): # function removed
7326 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7327 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7328 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7329 def ExportToMED(self, *args): # function removed
7330 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7331 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7333 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7335 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7336 def ExportPartToMED(self, *args): # 'version' parameter removed
7337 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7338 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7339 def ExportMED(self, *args): # signature of method changed
7340 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7342 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7344 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7346 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7349 class submeshProxy(SMESH._objref_SMESH_subMesh):
7352 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7354 def __init__(self,*args):
7355 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7357 def __deepcopy__(self, memo=None):
7358 new = self.__class__(self)
7361 def Compute(self,refresh=False):
7363 Compute the sub-mesh and return the status of the computation
7366 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7371 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7372 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7376 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7378 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7380 if salome.sg.hasDesktop():
7381 if refresh: salome.sg.updateObjBrowser()
7386 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7389 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7391 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7392 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7395 def __init__(self,*args):
7396 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7398 def __getattr__(self, name ): # method called if an attribute not found
7399 if not self.mesh: # look for name() method in Mesh class
7400 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7401 if hasattr( self.mesh, name ):
7402 return getattr( self.mesh, name )
7403 if name == "ExtrusionAlongPathObjX":
7404 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7405 print("meshEditor: attribute '%s' NOT FOUND" % name)
7407 def __deepcopy__(self, memo=None):
7408 new = self.__class__(self)
7410 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7411 if len( args ) == 1: args += False,
7412 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7413 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7414 if len( args ) == 2: args += False,
7415 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7416 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7417 if len( args ) == 1:
7418 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7419 NodesToKeep = args[1]
7420 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7421 unRegister = genObjUnRegister()
7423 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7424 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7425 if not isinstance( NodesToKeep, list ):
7426 NodesToKeep = [ NodesToKeep ]
7427 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7429 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7431 class Pattern(SMESH._objref_SMESH_Pattern):
7433 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7434 variables in some methods
7437 def LoadFromFile(self, patternTextOrFile ):
7438 text = patternTextOrFile
7439 if os.path.exists( text ):
7440 text = open( patternTextOrFile ).read()
7442 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7444 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7445 decrFun = lambda i: i-1
7446 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7447 theMesh.SetParameters(Parameters)
7448 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7450 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7451 decrFun = lambda i: i-1
7452 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7453 theMesh.SetParameters(Parameters)
7454 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7456 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7457 if isinstance( mesh, Mesh ):
7458 mesh = mesh.GetMesh()
7459 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7461 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7463 Registering the new proxy for Pattern
7468 Private class used to bind methods creating algorithms to the class Mesh
7471 def __init__(self, method):
7473 self.defaultAlgoType = ""
7474 self.algoTypeToClass = {}
7475 self.method = method
7477 def add(self, algoClass):
7479 Store a python class of algorithm
7481 if inspect.isclass(algoClass) and \
7482 hasattr( algoClass, "algoType"):
7483 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7484 if not self.defaultAlgoType and \
7485 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7486 self.defaultAlgoType = algoClass.algoType
7487 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7489 def copy(self, mesh):
7491 Create a copy of self and assign mesh to the copy
7494 other = algoCreator( self.method )
7495 other.defaultAlgoType = self.defaultAlgoType
7496 other.algoTypeToClass = self.algoTypeToClass
7500 def __call__(self,algo="",geom=0,*args):
7502 Create an instance of algorithm
7506 if isinstance( algo, str ):
7508 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7509 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7514 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7516 elif not algoType and isinstance( geom, str ):
7521 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7523 elif isinstance( arg, str ) and not algoType:
7526 import traceback, sys
7527 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7528 sys.stderr.write( msg + '\n' )
7529 tb = traceback.extract_stack(None,2)
7530 traceback.print_list( [tb[0]] )
7532 algoType = self.defaultAlgoType
7533 if not algoType and self.algoTypeToClass:
7534 algoType = sorted( self.algoTypeToClass.keys() )[0]
7535 if algoType in self.algoTypeToClass:
7536 #print("Create algo",algoType)
7537 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7538 raise RuntimeError( "No class found for algo type %s" % algoType)
7541 class hypMethodWrapper:
7543 Private class used to substitute and store variable parameters of hypotheses.
7546 def __init__(self, hyp, method):
7548 self.method = method
7549 #print("REBIND:", method.__name__)
7552 def __call__(self,*args):
7554 call a method of hypothesis with calling SetVarParameter() before
7558 return self.method( self.hyp, *args ) # hypothesis method with no args
7560 #print("MethWrapper.__call__", self.method.__name__, args)
7562 parsed = ParseParameters(*args) # replace variables with their values
7563 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7564 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7565 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7566 # maybe there is a replaced string arg which is not variable
7567 result = self.method( self.hyp, *args )
7568 except ValueError as detail: # raised by ParseParameters()
7570 result = self.method( self.hyp, *args )
7571 except omniORB.CORBA.BAD_PARAM:
7572 raise ValueError(detail) # wrong variable name
7577 class genObjUnRegister:
7579 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7582 def __init__(self, genObj=None):
7583 self.genObjList = []
7587 def set(self, genObj):
7588 "Store one or a list of of SALOME.GenericObj'es"
7589 if isinstance( genObj, list ):
7590 self.genObjList.extend( genObj )
7592 self.genObjList.append( genObj )
7596 for genObj in self.genObjList:
7597 if genObj and hasattr( genObj, "UnRegister" ):
7600 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7602 Bind methods creating mesher plug-ins to the Mesh class
7605 # print("pluginName: ", pluginName)
7606 pluginBuilderName = pluginName + "Builder"
7608 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7609 except Exception as e:
7610 from salome_utils import verbose
7611 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7613 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7614 plugin = eval( pluginBuilderName )
7615 # print(" plugin:" , str(plugin))
7617 # add methods creating algorithms to Mesh
7618 for k in dir( plugin ):
7619 if k[0] == '_': continue
7620 algo = getattr( plugin, k )
7621 #print(" algo:", str(algo))
7622 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7623 #print(" meshMethod:" , str(algo.meshMethod))
7624 if not hasattr( Mesh, algo.meshMethod ):
7625 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7627 _mmethod = getattr( Mesh, algo.meshMethod )
7628 if hasattr( _mmethod, "add" ):